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:
parent
7abd52a6e3
commit
a6eb514761
|
@ -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');
|
||||
});
|
||||
});
|
|
@ -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;
|
||||
};
|
|
@ -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>
|
||||
);
|
||||
|
|
|
@ -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>
|
||||
);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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) {
|
|
@ -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"
|
||||
|
|
Loading…
Reference in New Issue