fix: Calls with jwt not working on ios and fix media permission on iOS (#5075)

* fix roomId

* fix ios permission

* update lib and patch

* try

* update webview

* update method

* fix ios

* move to a function
This commit is contained in:
Gleidson Daniel Silva 2023-06-06 18:53:48 -03:00 committed by GitHub
parent 7abd52a6e3
commit a6eb514761
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 102 additions and 77 deletions

View File

@ -0,0 +1,18 @@
import { getRoomIdFromJitsiCallUrl } from './getRoomIdFromJitsiCall';
describe('getRoomIdFromJitsiCallUrl function', () => {
const urlWithJwt =
'https://meet.rocketchat.test/rocket6474dd29bbb65c7e344c0da0?jwt=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJ2aWRlb2NvbmZzcXVhZF9hcHAiLCJzdWIiOiJtZWV0LnJvY2tldGNoYXQuc2hvcCIsImlhdCI6MTY4NTM4NTE3OSwibmJmIjoxNjg1Mzg1MTc5LCJleHAiOjE2ODUzODg3ZXQ2NDc0ZGQyOWJiYjY1YzdlMzQ0YzBkYTAiLCJjb250ZXh0Ijp7InVzZXIiOnsibmFtZSI6InhkYW5pIiwiYXZhdGFyIjoiaHR0cHM6Ly9tb2JpbGUucm9ja2V0LmNoYXQvYXZhdGFyL3hkYW5pIiwiZW1haWwiOiJ1c2VyX2FSdEVMTHJGdkpEQ29USktiQHJvY2tldC5jaGF0In19LCJtb2RlcmF0b3IiOnRydWV9.WCo8Do4m1w8LBg5lVyd7Z-M9dG97uk5ogwfCaBzEUv4#config.desktopSharingChromeExtId="nocfbnnmjnndkbipkabodnheejiegccf"&config.callDisplayName="daniel"&config.startWithAudioMuted=false&config.startWithVideoMuted=true&config.prejoinPageEnabled=false&config.prejoinConfig.enabled=false&config.disableDeepLinking=true';
const urlWithoutJwt =
'https://meet.rocketchat.test/rocket6474dd29bbb65c7e344c0da0#config.desktopSharingChromeExtId="nocfbnnmjnndkbipkabodnheejiegccf"&config.callDisplayName="daniel"&config.startWithAudioMuted=false&config.startWithVideoMuted=true&config.prejoinPageEnabled=false&config.prejoinConfig.enabled=false&config.disableDeepLinking=true';
test('return correct url without jwt', () => {
const roomId = getRoomIdFromJitsiCallUrl(urlWithoutJwt);
expect(roomId).toEqual('rocket6474dd29bbb65c7e344c0da0');
});
test('return correct url with jwt', () => {
const roomId = getRoomIdFromJitsiCallUrl(urlWithJwt);
expect(roomId).toEqual('rocket6474dd29bbb65c7e344c0da0');
});
});

View File

@ -0,0 +1,9 @@
export const getRoomIdFromJitsiCallUrl = (jitsiCallUrl: string): string => {
const url = jitsiCallUrl
?.split(/^https?:\/\//)[1]
?.split('#')[0]
?.split('/')[1];
const roomId = url.includes('?jwt') ? url.split('?jwt')[0] : url;
return roomId;
};

View File

@ -29,6 +29,8 @@ const AdminPanelView = () => {
return null;
}
const str = `Meteor.loginWithToken('${token}', function() { })`;
return (
<SafeAreaView>
<StatusBar />
@ -36,7 +38,7 @@ const AdminPanelView = () => {
// https://github.com/react-native-community/react-native-webview/issues/1311
onMessage={() => {}}
source={{ uri: `${baseUrl}/admin/info?layout=embedded` }}
injectedJavaScript={`Meteor.loginWithToken('${token}', function() { })`}
injectedJavaScript={str}
/>
</SafeAreaView>
);

View File

@ -1,4 +1,4 @@
import { activateKeepAwake, deactivateKeepAwake } from 'expo-keep-awake';
import { activateKeepAwakeAsync, deactivateKeepAwake } from 'expo-keep-awake';
import React from 'react';
import { BackHandler, Linking, NativeEventSubscription, SafeAreaView } from 'react-native';
import WebView from 'react-native-webview';
@ -7,6 +7,7 @@ import { WebViewNavigation } from 'react-native-webview/lib/WebViewTypes';
import { IBaseScreen } from '../definitions';
import { userAgent } from '../lib/constants';
import { isIOS } from '../lib/methods/helpers';
import { getRoomIdFromJitsiCallUrl } from '../lib/methods/helpers/getRoomIdFromJitsiCall';
import { events, logEvent } from '../lib/methods/helpers/log';
import { endVideoConfTimer, initVideoConfTimer } from '../lib/methods/videoConfTimer';
import { ChatsStackParamList } from '../stacks/types';
@ -30,7 +31,7 @@ class JitsiMeetView extends React.Component<TJitsiMeetViewProps> {
componentDidMount() {
this.handleJitsiApp();
this.onConferenceJoined();
activateKeepAwake();
activateKeepAwakeAsync();
}
componentWillUnmount() {
@ -67,11 +68,10 @@ class JitsiMeetView extends React.Component<TJitsiMeetViewProps> {
onNavigationStateChange = (webViewState: WebViewNavigation) => {
const { navigation, route } = this.props;
const jitsiRoomId = route.params.url
?.split(/^https?:\/\//)[1]
?.split('#')[0]
?.split('/')[1];
if ((jitsiRoomId && !webViewState.url.includes(jitsiRoomId)) || webViewState.url.includes('close')) {
const roomId = getRoomIdFromJitsiCallUrl(route.params.url);
if ((roomId && !webViewState.url.includes(roomId)) || webViewState.url.includes('close')) {
if (isIOS) {
if (webViewState.navigationType) {
navigation.pop();
@ -83,16 +83,19 @@ class JitsiMeetView extends React.Component<TJitsiMeetViewProps> {
};
render() {
const uri = `${this.url}${this.url.includes('#config') ? '&' : '#'}config.disableDeepLinking=true`;
return (
<SafeAreaView style={{ flex: 1 }}>
<WebView
source={{ uri: `${this.url}${this.url.includes('#config') ? '&' : '#'}config.disableDeepLinking=true` }}
source={{ uri: uri.replace(/"/g, "'") }}
onNavigationStateChange={this.onNavigationStateChange}
style={{ flex: 1 }}
// Jitsi default background color
style={{ flex: 1, backgroundColor: 'rgb(62,62,62)' }}
userAgent={userAgent}
javaScriptEnabled
domStorageEnabled
mediaPlaybackRequiresUserAction={false}
mediaCapturePermissionGrantType={'grant'}
/>
</SafeAreaView>
);

View File

@ -407,8 +407,8 @@ PODS:
- React
- react-native-slider (4.4.2):
- React-Core
- react-native-webview (10.3.2):
- React
- react-native-webview (11.26.1):
- React-Core
- React-perflogger (0.71.7)
- React-RCTActionSheet (0.71.7):
- React-Core/RCTActionSheetHeaders (= 0.71.7)
@ -949,7 +949,7 @@ SPEC CHECKSUMS:
react-native-safe-area-context: f0906bf8bc9835ac9a9d3f97e8bde2a997d8da79
react-native-simple-crypto: a26121696064628b6cb92f52f653353114deb7f4
react-native-slider: 33b8d190b59d4f67a541061bb91775d53d617d9d
react-native-webview: 679b6f400176e2ea8a785acf7ae16cf282e7d1eb
react-native-webview: 9f111dfbcfc826084d6c507f569e5e03342ee1c1
React-perflogger: 2d505bbe298e3b7bacdd9e542b15535be07220f6
React-RCTActionSheet: 0e96e4560bd733c9b37efbf68f5b1a47615892fb
React-RCTAnimation: fd138e26f120371c87e406745a27535e2c8a04ef

View File

@ -131,7 +131,7 @@
"react-native-svg": "^13.8.0",
"react-native-ui-lib": "RocketChat/react-native-ui-lib#7.2.0",
"react-native-vector-icons": "^9.2.0",
"react-native-webview": "10.3.2",
"react-native-webview": "11.26.1",
"react-redux": "^8.0.5",
"reactotron-react-native": "^5.0.3",
"redux": "4.2.0",

View File

@ -1,10 +1,10 @@
diff --git a/node_modules/react-native-webview/android/src/main/java/com/reactnativecommunity/webview/RNCWebViewManager.java b/node_modules/react-native-webview/android/src/main/java/com/reactnativecommunity/webview/RNCWebViewManager.java
index ab869cf..08ce7ce 100644
index 9cfe821..b7fe976 100644
--- a/node_modules/react-native-webview/android/src/main/java/com/reactnativecommunity/webview/RNCWebViewManager.java
+++ b/node_modules/react-native-webview/android/src/main/java/com/reactnativecommunity/webview/RNCWebViewManager.java
@@ -84,6 +84,12 @@ import java.util.Map;
import javax.annotation.Nullable;
@@ -102,6 +102,12 @@ import java.util.Locale;
import java.util.Map;
import java.util.concurrent.atomic.AtomicReference;
+import java.security.cert.X509Certificate;
+import java.security.PrivateKey;
@ -15,16 +15,16 @@ index ab869cf..08ce7ce 100644
/**
* Manages instances of {@link WebView}
* <p>
@@ -140,6 +146,8 @@ public class RNCWebViewManager extends SimpleViewManager<WebView> {
protected @Nullable String mUserAgent = null;
protected @Nullable String mUserAgentWithApplicationName = null;
@@ -166,6 +172,8 @@ public class RNCWebViewManager extends SimpleViewManager<WebView> {
protected @Nullable String mDownloadingMessage = null;
protected @Nullable String mLackPermissionToDownloadMessage = null;
+ private static String certificateAlias = null;
+
public RNCWebViewManager() {
mWebViewConfig = new WebViewConfig() {
public void configWebView(WebView webView) {
@@ -151,6 +159,10 @@ public class RNCWebViewManager extends SimpleViewManager<WebView> {
@@ -177,6 +185,10 @@ public class RNCWebViewManager extends SimpleViewManager<WebView> {
mWebViewConfig = webViewConfig;
}
@ -32,10 +32,10 @@ index ab869cf..08ce7ce 100644
+ certificateAlias = alias;
+ }
+
protected static void dispatchEvent(WebView webView, Event event) {
ReactContext reactContext = (ReactContext) webView.getContext();
EventDispatcher eventDispatcher =
@@ -562,7 +574,7 @@ public class RNCWebViewManager extends SimpleViewManager<WebView> {
@Override
public String getName() {
return REACT_CLASS;
@@ -687,7 +699,7 @@ public class RNCWebViewManager extends SimpleViewManager<WebView> {
@Override
protected void addEventEmitters(ThemedReactContext reactContext, WebView view) {
// Do not register default touch emitter and let WebView implementation handle touches
@ -44,17 +44,12 @@ index ab869cf..08ce7ce 100644
}
@Override
@@ -742,12 +754,56 @@ public class RNCWebViewManager extends SimpleViewManager<WebView> {
protected static class RNCWebViewClient extends WebViewClient {
+ protected ReactContext reactContext;
protected boolean mLastLoadFailed = false;
protected @Nullable
ReadableArray mUrlPrefixesForDefaultIntent;
@@ -913,6 +925,50 @@ public class RNCWebViewManager extends SimpleViewManager<WebView> {
protected RNCWebView.ProgressChangedFilter progressChangedFilter = null;
protected @Nullable String ignoreErrFailedForThisURL = null;
protected @Nullable BasicAuthCredential basicAuthCredential = null;
+ protected ReactContext reactContext;
+
+ public RNCWebViewClient(ReactContext reactContext) {
+ this.reactContext = reactContext;
+ }
@ -97,12 +92,11 @@ index ab869cf..08ce7ce 100644
+ super.onReceivedClientCertRequest(view, request);
+ }
+ }
+
public void setIgnoreErrFailedForThisURL(@Nullable String url) {
ignoreErrFailedForThisURL = url;
}
diff --git a/node_modules/react-native-webview/apple/RNCWebView.m b/node_modules/react-native-webview/apple/RNCWebView.m
index 02b4238..e0635ed 100644
index 7570d8d..eaa0e5d 100644
--- a/node_modules/react-native-webview/apple/RNCWebView.m
+++ b/node_modules/react-native-webview/apple/RNCWebView.m
@@ -17,6 +17,9 @@
@ -115,8 +109,8 @@ index 02b4238..e0635ed 100644
static NSTimer *keyboardTimer;
static NSString *const HistoryShimName = @"ReactNativeHistoryShim";
static NSString *const MessageHandlerName = @"ReactNativeWebView";
@@ -737,6 +740,68 @@ static NSDictionary* customCertificatesForHost;
customCertificatesForHost = certificates;
@@ -963,6 +966,68 @@ + (void)setCustomCertificatesForHost:(nullable NSDictionary*)certificates {
customCertificatesForHost = certificates;
}
+-(NSURLCredential *)getUrlCredential:(NSURLAuthenticationChallenge *)challenge path:(NSString *)path password:(NSString *)password
@ -184,37 +178,36 @@ index 02b4238..e0635ed 100644
- (void) webView:(WKWebView *)webView
didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential * _Nullable))completionHandler
@@ -746,7 +811,32 @@ static NSDictionary* customCertificatesForHost;
host = webView.URL.host;
}
if ([[challenge protectionSpace] authenticationMethod] == NSURLAuthenticationMethodClientCertificate) {
- completionHandler(NSURLSessionAuthChallengeUseCredential, clientAuthenticationCredential);
+ NSString *host = challenge.protectionSpace.host;
@@ -972,7 +1037,31 @@ - (void) webView:(WKWebView *)webView
host = webView.URL.host;
}
if ([[challenge protectionSpace] authenticationMethod] == NSURLAuthenticationMethodClientCertificate) {
- completionHandler(NSURLSessionAuthChallengeUseCredential, clientAuthenticationCredential);
+ NSString *host = challenge.protectionSpace.host;
+
+ // Read the clientSSL info from MMKV
+ __block NSDictionary *clientSSL;
+ SecureStorage *secureStorage = [[SecureStorage alloc] init];
+
+ // https://github.com/ammarahm-ed/react-native-mmkv-storage/blob/master/src/loader.js#L31
+ NSString *key = [secureStorage getSecureKey:[self stringToHex:@"com.MMKV.default"]];
+ NSURLCredential *credential = [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust];
+
+ if (key == NULL) {
+ return completionHandler(NSURLSessionAuthChallengePerformDefaultHandling, credential);
+ }
+
+ NSData *cryptKey = [key dataUsingEncoding:NSUTF8StringEncoding];
+ MMKV *mmkv = [MMKV mmkvWithID:@"default" cryptKey:cryptKey mode:MMKVMultiProcess];
+ clientSSL = [mmkv getObjectOfClass:[NSDictionary class] forKey:host];
+
+
+ if (clientSSL != (id)[NSNull null]) {
+ NSString *path = [clientSSL objectForKey:@"path"];
+ NSString *password = [clientSSL objectForKey:@"password"];
+ credential = [self getUrlCredential:challenge path:path password:password];
+ }
+
+ completionHandler(NSURLSessionAuthChallengeUseCredential, credential);
return;
}
if ([[challenge protectionSpace] serverTrust] != nil && customCertificatesForHost != nil && host != nil) {
+ // Read the clientSSL info from MMKV
+ __block NSDictionary *clientSSL;
+ SecureStorage *secureStorage = [[SecureStorage alloc] init];
+
+ // https://github.com/ammarahm-ed/react-native-mmkv-storage/blob/master/src/loader.js#L31
+ NSString *key = [secureStorage getSecureKey:[self stringToHex:@"com.MMKV.default"]];
+ NSURLCredential *credential = [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust];
+
+ if (key == NULL) {
+ return completionHandler(NSURLSessionAuthChallengePerformDefaultHandling, credential);
+ }
+
+ NSData *cryptKey = [key dataUsingEncoding:NSUTF8StringEncoding];
+ MMKV *mmkv = [MMKV mmkvWithID:@"default" cryptKey:cryptKey mode:MMKVMultiProcess];
+ clientSSL = [mmkv getObjectOfClass:[NSDictionary class] forKey:host];
+
+ if (clientSSL != (id)[NSNull null]) {
+ NSString *path = [clientSSL objectForKey:@"path"];
+ NSString *password = [clientSSL objectForKey:@"password"];
+ credential = [self getUrlCredential:challenge path:path password:password];
+ }
+
+ completionHandler(NSURLSessionAuthChallengeUseCredential, credential);
return;
}
if ([[challenge protectionSpace] serverTrust] != nil && customCertificatesForHost != nil && host != nil) {

View File

@ -17242,10 +17242,10 @@ react-native-vector-icons@^9.2.0:
prop-types "^15.7.2"
yargs "^16.1.1"
react-native-webview@10.3.2:
version "10.3.2"
resolved "https://registry.yarnpkg.com/react-native-webview/-/react-native-webview-10.3.2.tgz#c634946152099c95d521a3abc71065d1d642e192"
integrity sha512-4A8FKL/puonkqQ1FOKd+iPulqRXCG4inmIK4pQ60zv9Ua+YkBKLxxofQiCvRwIXSSgAXYT+AE3rOHr3bx4A/cw==
react-native-webview@11.26.1:
version "11.26.1"
resolved "https://registry.yarnpkg.com/react-native-webview/-/react-native-webview-11.26.1.tgz#658c09ed5162dc170b361e48c2dd26c9712879da"
integrity sha512-hC7BkxOpf+z0UKhxFSFTPAM4shQzYmZHoELa6/8a/MspcjEP7ukYKpuSUTLDywQditT8yI9idfcKvfZDKQExGw==
dependencies:
escape-string-regexp "2.0.0"
invariant "2.2.4"