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

View File

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

View File

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