浏览代码

feat(inIframe/isEmbedded) add ability to detect generic embedding

On web we detect if we run on an iframe, and on mobile we detect if the
app is one of ours.
j25
Saúl Ibarra Corretgé 7 个月前
父节点
当前提交
1e8cc9d085

+ 2
- 2
index.html 查看文件

36
                 Component: JitsiMeetJS.app.entryPoints.APP
36
                 Component: JitsiMeetJS.app.entryPoints.APP
37
             })
37
             })
38
 
38
 
39
-            const inIframe = () => {
39
+            const isEmbedded = () => {
40
                 try {
40
                 try {
41
                     return window.self !== window.top;
41
                     return window.self !== window.top;
42
                 } catch (e) {
42
                 } catch (e) {
45
             };
45
             };
46
 
46
 
47
             const isElectron = navigator.userAgent.includes('Electron');
47
             const isElectron = navigator.userAgent.includes('Electron');
48
-            const shouldRegisterWorker = !isElectron && !inIframe() && 'serviceWorker' in navigator;
48
+            const shouldRegisterWorker = !isElectron && !isEmbedded() && 'serviceWorker' in navigator;
49
 
49
 
50
             if (shouldRegisterWorker) {
50
             if (shouldRegisterWorker) {
51
                 navigator.serviceWorker
51
                 navigator.serviceWorker

+ 2
- 2
react/features/analytics/functions.ts 查看文件

12
     browser
12
     browser
13
 } from '../base/lib-jitsi-meet';
13
 } from '../base/lib-jitsi-meet';
14
 import { isAnalyticsEnabled } from '../base/lib-jitsi-meet/functions.any';
14
 import { isAnalyticsEnabled } from '../base/lib-jitsi-meet/functions.any';
15
+import { isEmbedded } from '../base/util/embedUtils';
15
 import { getJitsiMeetGlobalNS } from '../base/util/helpers';
16
 import { getJitsiMeetGlobalNS } from '../base/util/helpers';
16
-import { inIframe } from '../base/util/iframeUtils';
17
 import { loadScript } from '../base/util/loadScript';
17
 import { loadScript } from '../base/util/loadScript';
18
 import { parseURLParams } from '../base/util/parseURLParams';
18
 import { parseURLParams } from '../base/util/parseURLParams';
19
 import { parseURIString } from '../base/util/uri';
19
 import { parseURIString } from '../base/util/uri';
213
     permanentProperties.externalApi = typeof API_ID === 'number';
213
     permanentProperties.externalApi = typeof API_ID === 'number';
214
 
214
 
215
     // Report if we are loaded in iframe
215
     // Report if we are loaded in iframe
216
-    permanentProperties.inIframe = inIframe();
216
+    permanentProperties.inIframe = isEmbedded();
217
 
217
 
218
     // Report the tenant from the URL.
218
     // Report the tenant from the URL.
219
     permanentProperties.tenant = tenant || '/';
219
     permanentProperties.tenant = tenant || '/';

+ 2
- 2
react/features/app/actions.web.ts 查看文件

7
 } from '../base/config/actions';
7
 } from '../base/config/actions';
8
 import { setLocationURL } from '../base/connection/actions.web';
8
 import { setLocationURL } from '../base/connection/actions.web';
9
 import { loadConfig } from '../base/lib-jitsi-meet/functions.web';
9
 import { loadConfig } from '../base/lib-jitsi-meet/functions.web';
10
-import { inIframe } from '../base/util/iframeUtils';
10
+import { isEmbedded } from '../base/util/embedUtils';
11
 import { parseURIString } from '../base/util/uri';
11
 import { parseURIString } from '../base/util/uri';
12
 import { isVpaasMeeting } from '../jaas/functions';
12
 import { isVpaasMeeting } from '../jaas/functions';
13
 import { clearNotifications, showNotification } from '../notifications/actions';
13
 import { clearNotifications, showNotification } from '../notifications/actions';
102
         // if close page is enabled redirect to it, without further action
102
         // if close page is enabled redirect to it, without further action
103
         if (enableClosePage) {
103
         if (enableClosePage) {
104
             if (isVpaasMeeting(getState())) {
104
             if (isVpaasMeeting(getState())) {
105
-                const isOpenedInIframe = inIframe();
105
+                const isOpenedInIframe = isEmbedded();
106
 
106
 
107
                 if (isOpenedInIframe) {
107
                 if (isOpenedInIframe) {
108
                     // @ts-ignore
108
                     // @ts-ignore

+ 2
- 1
react/features/app/components/App.native.tsx 查看文件

12
 import DimensionsDetector from '../../base/responsive-ui/components/DimensionsDetector.native';
12
 import DimensionsDetector from '../../base/responsive-ui/components/DimensionsDetector.native';
13
 import { updateSettings } from '../../base/settings/actions';
13
 import { updateSettings } from '../../base/settings/actions';
14
 import JitsiThemePaperProvider from '../../base/ui/components/JitsiThemeProvider.native';
14
 import JitsiThemePaperProvider from '../../base/ui/components/JitsiThemeProvider.native';
15
+import { isEmbedded } from '../../base/util/embedUtils.native';
15
 import { _getRouteToRender } from '../getRouteToRender.native';
16
 import { _getRouteToRender } from '../getRouteToRender.native';
16
 import logger from '../logger';
17
 import logger from '../logger';
17
 
18
 
87
 
88
 
88
         const liteTxt = AppInfo.isLiteSDK ? ' (lite)' : '';
89
         const liteTxt = AppInfo.isLiteSDK ? ' (lite)' : '';
89
 
90
 
90
-        logger.info(`Loaded SDK ${AppInfo.sdkVersion}${liteTxt}`);
91
+        logger.info(`Loaded SDK ${AppInfo.sdkVersion}${liteTxt} isEmbedded=${isEmbedded()}`);
91
     }
92
     }
92
 
93
 
93
     /**
94
     /**

+ 2
- 2
react/features/app/middleware.ts 查看文件

7
 import { CONNECTION_ESTABLISHED, CONNECTION_FAILED } from '../base/connection/actionTypes';
7
 import { CONNECTION_ESTABLISHED, CONNECTION_FAILED } from '../base/connection/actionTypes';
8
 import { getURLWithoutParams } from '../base/connection/utils';
8
 import { getURLWithoutParams } from '../base/connection/utils';
9
 import MiddlewareRegistry from '../base/redux/MiddlewareRegistry';
9
 import MiddlewareRegistry from '../base/redux/MiddlewareRegistry';
10
-import { inIframe } from '../base/util/iframeUtils';
10
+import { isEmbedded } from '../base/util/embedUtils';
11
 
11
 
12
 import { reloadNow } from './actions';
12
 import { reloadNow } from './actions';
13
 import { _getRouteToRender } from './getRouteToRender';
13
 import { _getRouteToRender } from './getRouteToRender';
52
     // @ts-ignore
52
     // @ts-ignore
53
     const { history, location } = window;
53
     const { history, location } = window;
54
 
54
 
55
-    if (inIframe()) {
55
+    if (isEmbedded()) {
56
         return;
56
         return;
57
     }
57
     }
58
 
58
 

+ 2
- 2
react/features/base/app/middleware.web.ts 查看文件

1
 import { AnyAction } from 'redux';
1
 import { AnyAction } from 'redux';
2
 
2
 
3
 import MiddlewareRegistry from '../redux/MiddlewareRegistry';
3
 import MiddlewareRegistry from '../redux/MiddlewareRegistry';
4
-import { inIframe } from '../util/iframeUtils';
4
+import { isEmbedded } from '../util/embedUtils';
5
 
5
 
6
 import { APP_WILL_MOUNT, APP_WILL_UNMOUNT } from './actionTypes';
6
 import { APP_WILL_MOUNT, APP_WILL_UNMOUNT } from './actionTypes';
7
 import logger from './logger';
7
 import logger from './logger';
24
     case APP_WILL_MOUNT: {
24
     case APP_WILL_MOUNT: {
25
         // Disable it inside an iframe until Google fixes the origin trial for 3rd party sources:
25
         // Disable it inside an iframe until Google fixes the origin trial for 3rd party sources:
26
         // https://bugs.chromium.org/p/chromium/issues/detail?id=1504167
26
         // https://bugs.chromium.org/p/chromium/issues/detail?id=1504167
27
-        if (!inIframe() && 'PressureObserver' in globalThis) {
27
+        if (!isEmbedded() && 'PressureObserver' in globalThis) {
28
             pressureObserver = new window.PressureObserver(
28
             pressureObserver = new window.PressureObserver(
29
                     (records: typeof window.PressureRecord) => {
29
                     (records: typeof window.PressureRecord) => {
30
                         logger.info('Compute pressure state changed:', JSON.stringify(records));
30
                         logger.info('Compute pressure state changed:', JSON.stringify(records));

+ 3
- 3
react/features/base/config/configWhitelist.ts 查看文件

1
-import { inIframe } from '../util/iframeUtils';
1
+import { isEmbedded } from '../util/embedUtils';
2
 
2
 
3
 import extraConfigWhitelist from './extraConfigWhitelist';
3
 import extraConfigWhitelist from './extraConfigWhitelist';
4
-import inIframeConfigWhitelist from './inIframeConfigWhitelist';
4
+import isEmbeddedConfigWhitelist from './isEmbeddedConfigWhitelist';
5
 
5
 
6
 /**
6
 /**
7
  * The config keys to whitelist, the keys that can be overridden.
7
  * The config keys to whitelist, the keys that can be overridden.
249
     'webrtcIceTcpDisable',
249
     'webrtcIceTcpDisable',
250
     'webrtcIceUdpDisable',
250
     'webrtcIceUdpDisable',
251
     'whiteboard.enabled'
251
     'whiteboard.enabled'
252
-].concat(extraConfigWhitelist).concat(inIframe() ? inIframeConfigWhitelist : []);
252
+].concat(extraConfigWhitelist).concat(isEmbedded() ? isEmbeddedConfigWhitelist : []);

+ 0
- 4
react/features/base/config/inIframeConfigWhitelist.ts 查看文件

1
-/**
2
- * Additional config whitelist extending the original whitelist in the case where jitsi-meet is loaded in an iframe.
3
- */
4
-export default [];

+ 0
- 5
react/features/base/config/inIframeInterfaceConfigWhitelist.ts 查看文件

1
-/**
2
- * Additional interface config whitelist extending the original whitelist in the case where jitsi-meet is loaded in an
3
- * iframe.
4
- */
5
-export default [];

+ 3
- 3
react/features/base/config/interfaceConfigWhitelist.ts 查看文件

1
-import { inIframe } from '../util/iframeUtils';
1
+import { isEmbedded } from '../util/embedUtils';
2
 
2
 
3
 import extraInterfaceConfigWhitelistCopy from './extraInterfaceConfigWhitelist';
3
 import extraInterfaceConfigWhitelistCopy from './extraInterfaceConfigWhitelist';
4
-import inIframeInterfaceConfigWhitelist from './inIframeInterfaceConfigWhitelist';
4
+import isEmbeddedInterfaceConfigWhitelist from './isEmbeddedInterfaceConfigWhitelist';
5
 
5
 
6
 /**
6
 /**
7
  * The interface config keys to whitelist, the keys that can be overridden.
7
  * The interface config keys to whitelist, the keys that can be overridden.
54
     'VERTICAL_FILMSTRIP',
54
     'VERTICAL_FILMSTRIP',
55
     'VIDEO_LAYOUT_FIT',
55
     'VIDEO_LAYOUT_FIT',
56
     'VIDEO_QUALITY_LABEL_DISABLED'
56
     'VIDEO_QUALITY_LABEL_DISABLED'
57
-].concat(extraInterfaceConfigWhitelistCopy).concat(inIframe() ? inIframeInterfaceConfigWhitelist : []);
57
+].concat(extraInterfaceConfigWhitelistCopy).concat(isEmbedded() ? isEmbeddedInterfaceConfigWhitelist : []);

+ 11
- 0
react/features/base/config/isEmbeddedConfigWhitelist.ts 查看文件

1
+/**
2
+ * Additional config whitelist extending the original whitelist applied when Jitsi Meet is embedded
3
+ * in another app be that with an iframe or a mobile SDK.
4
+ */
5
+export default [
6
+    'customToolbarButtons',
7
+    'defaultLogoUrl',
8
+    'deploymentUrls',
9
+    'liveStreaming',
10
+    'salesforceUrl'
11
+];

+ 6
- 0
react/features/base/config/isEmbeddedInterfaceConfigWhitelist.ts 查看文件

1
+/**
2
+ * Additional interface config whitelist extending the original whitelist applied when Jitsi Meet is embedded
3
+ * in another app be that with an iframe or a mobile SDK.
4
+ */
5
+export default [
6
+];

+ 2
- 2
react/features/base/connection/actions.any.ts 查看文件

5
 import { getCurrentConference } from '../conference/functions';
5
 import { getCurrentConference } from '../conference/functions';
6
 import { IConfigState } from '../config/reducer';
6
 import { IConfigState } from '../config/reducer';
7
 import JitsiMeetJS, { JitsiConnectionEvents } from '../lib-jitsi-meet';
7
 import JitsiMeetJS, { JitsiConnectionEvents } from '../lib-jitsi-meet';
8
-import { inIframe } from '../util/iframeUtils';
8
+import { isEmbedded } from '../util/embedUtils';
9
 import { parseURLParams } from '../util/parseURLParams';
9
 import { parseURLParams } from '../util/parseURLParams';
10
 import {
10
 import {
11
     appendURLParam,
11
     appendURLParam,
121
     const iceServersOverride = params['iceServers.replace'];
121
     const iceServersOverride = params['iceServers.replace'];
122
 
122
 
123
     // Allow iceServersOverride only when jitsi-meet is in an iframe.
123
     // Allow iceServersOverride only when jitsi-meet is in an iframe.
124
-    if (inIframe() && iceServersOverride) {
124
+    if (isEmbedded() && iceServersOverride) {
125
         options.iceServersOverride = iceServersOverride;
125
         options.iceServersOverride = iceServersOverride;
126
     }
126
     }
127
 
127
 

+ 2
- 2
react/features/base/jitsi-local-storage/setup.web.ts 查看文件

5
 import { safeJsonParse } from '@jitsi/js-utils/json';
5
 import { safeJsonParse } from '@jitsi/js-utils/json';
6
 
6
 
7
 import { browser } from '../lib-jitsi-meet';
7
 import { browser } from '../lib-jitsi-meet';
8
-import { inIframe } from '../util/iframeUtils';
8
+import { isEmbedded } from '../util/embedUtils';
9
 import { parseURLParams } from '../util/parseURLParams';
9
 import { parseURLParams } from '../util/parseURLParams';
10
 
10
 
11
 import logger from './logger';
11
 import logger from './logger';
41
         return true;
41
         return true;
42
     }
42
     }
43
 
43
 
44
-    if (browser.isWebKitBased() && inIframe()) {
44
+    if (browser.isWebKitBased() && isEmbedded()) {
45
         // WebKit browsers don't persist local storage for third-party iframes.
45
         // WebKit browsers don't persist local storage for third-party iframes.
46
 
46
 
47
         return true;
47
         return true;

+ 32
- 0
react/features/base/util/embedUtils.native.ts 查看文件

1
+import { getBundleId } from 'react-native-device-info';
2
+
3
+/**
4
+ * BUndle ids for the Jitsi Meet apps.
5
+ */
6
+const JITSI_MEET_APPS = [
7
+
8
+    // iOS app.
9
+    'com.atlassian.JitsiMeet.ios',
10
+
11
+    // Android + iOS (testing) app.
12
+    'org.jitsi.meet',
13
+
14
+    // Android debug app.
15
+    'org.jitsi.meet.debug',
16
+
17
+    // 8x8 Work (Android).
18
+    'org.vom8x8.sipua',
19
+
20
+    // 8x8 Work (iOS).
21
+    'com.yourcompany.Virtual-Office'
22
+];
23
+
24
+/**
25
+ * Checks whether we are loaded in iframe. In the mobile case we treat SDK
26
+ * consumers as the web treats iframes.
27
+ *
28
+ * @returns {boolean} Whether the current app is a Jitsi Meet app.
29
+ */
30
+export function isEmbedded(): boolean {
31
+    return !JITSI_MEET_APPS.includes(getBundleId());
32
+}

react/features/base/util/iframeUtils.ts → react/features/base/util/embedUtils.web.ts 查看文件

3
  *
3
  *
4
  * @returns {boolean} Whether the current page is loaded in an iframe.
4
  * @returns {boolean} Whether the current page is loaded in an iframe.
5
  */
5
  */
6
-export function inIframe(): boolean {
7
-    if (navigator.product === 'ReactNative') {
8
-        return false;
9
-    }
10
-
6
+export function isEmbedded(): boolean {
11
     try {
7
     try {
12
         return window.self !== window.top;
8
         return window.self !== window.top;
13
     } catch (e) {
9
     } catch (e) {

+ 4
- 3
react/features/conference/middleware.any.ts 查看文件

27
 import { SET_REDUCED_UI } from '../base/responsive-ui/actionTypes';
27
 import { SET_REDUCED_UI } from '../base/responsive-ui/actionTypes';
28
 import { LOWER_HAND_MESSAGE } from '../base/tracks/constants';
28
 import { LOWER_HAND_MESSAGE } from '../base/tracks/constants';
29
 import { BUTTON_TYPES } from '../base/ui/constants.any';
29
 import { BUTTON_TYPES } from '../base/ui/constants.any';
30
-import { inIframe } from '../base/util/iframeUtils';
30
+import { isEmbedded } from '../base/util/embedUtils';
31
 import { isCalendarEnabled } from '../calendar-sync/functions';
31
 import { isCalendarEnabled } from '../calendar-sync/functions';
32
 import FeedbackDialog from '../feedback/components/FeedbackDialog';
32
 import FeedbackDialog from '../feedback/components/FeedbackDialog';
33
 import { setFilmstripEnabled } from '../filmstrip/actions.any';
33
 import { setFilmstripEnabled } from '../filmstrip/actions.any';
191
         }
191
         }
192
     }
192
     }
193
 
193
 
194
-    if (inIframe() && state['features/base/config'].disableIframeAPI && !browser.isElectron()
195
-        && !isVpaasMeeting(state) && !allowIframe) {
194
+    // TODO: enable for mobile too?
195
+    if (isEmbedded() && state['features/base/config'].disableIframeAPI && !browser.isElectron()
196
+            && !browser.isReactNative() && !isVpaasMeeting(state) && !allowIframe) {
196
         // show sticky notification and redirect in 5 minutes
197
         // show sticky notification and redirect in 5 minutes
197
         const { locationURL } = state['features/base/connection'];
198
         const { locationURL } = state['features/base/connection'];
198
         let translationKey = 'notify.disabledIframe';
199
         let translationKey = 'notify.disabledIframe';

+ 3
- 3
react/features/recent-list/middleware.ts 查看文件

6
 import { JITSI_CONFERENCE_URL_KEY } from '../base/conference/constants';
6
 import { JITSI_CONFERENCE_URL_KEY } from '../base/conference/constants';
7
 import { addKnownDomains } from '../base/known-domains/actions';
7
 import { addKnownDomains } from '../base/known-domains/actions';
8
 import MiddlewareRegistry from '../base/redux/MiddlewareRegistry';
8
 import MiddlewareRegistry from '../base/redux/MiddlewareRegistry';
9
-import { inIframe } from '../base/util/iframeUtils';
9
+import { isEmbedded } from '../base/util/embedUtils';
10
 import { parseURIString } from '../base/util/uri';
10
 import { parseURIString } from '../base/util/uri';
11
 
11
 
12
 import { _storeCurrentConference, _updateConferenceDuration } from './actions';
12
 import { _storeCurrentConference, _updateConferenceDuration } from './actions';
86
     const state = getState();
86
     const state = getState();
87
     const { doNotStoreRoom } = state['features/base/config'];
87
     const { doNotStoreRoom } = state['features/base/config'];
88
 
88
 
89
-    if (!doNotStoreRoom && !inIframe()) {
89
+    if (!doNotStoreRoom && !isEmbedded()) {
90
         let locationURL;
90
         let locationURL;
91
 
91
 
92
         /**
92
         /**
130
 function _setRoom({ dispatch, getState }: IStore, next: Function, action: AnyAction) {
130
 function _setRoom({ dispatch, getState }: IStore, next: Function, action: AnyAction) {
131
     const { doNotStoreRoom } = getState()['features/base/config'];
131
     const { doNotStoreRoom } = getState()['features/base/config'];
132
 
132
 
133
-    if (!doNotStoreRoom && !inIframe() && action.room) {
133
+    if (!doNotStoreRoom && !isEmbedded() && action.room) {
134
         const { locationURL } = getState()['features/base/connection'];
134
         const { locationURL } = getState()['features/base/connection'];
135
 
135
 
136
         if (locationURL) {
136
         if (locationURL) {

+ 2
- 2
react/features/recording/components/Recording/LocalRecordingManager.web.ts 查看文件

6
 import { getRoomName } from '../../../base/conference/functions';
6
 import { getRoomName } from '../../../base/conference/functions';
7
 import { MEDIA_TYPE } from '../../../base/media/constants';
7
 import { MEDIA_TYPE } from '../../../base/media/constants';
8
 import { getLocalTrack, getTrackState } from '../../../base/tracks/functions';
8
 import { getLocalTrack, getTrackState } from '../../../base/tracks/functions';
9
-import { inIframe } from '../../../base/util/iframeUtils';
9
+import { isEmbedded } from '../../../base/util/embedUtils';
10
 import { stopLocalVideoRecording } from '../../actions.any';
10
 import { stopLocalVideoRecording } from '../../actions.any';
11
 
11
 
12
 interface ISelfRecording {
12
 interface ISelfRecording {
180
         const { dispatch, getState } = store;
180
         const { dispatch, getState } = store;
181
 
181
 
182
         // @ts-ignore
182
         // @ts-ignore
183
-        const supportsCaptureHandle = Boolean(navigator.mediaDevices.setCaptureHandleConfig) && !inIframe();
183
+        const supportsCaptureHandle = Boolean(navigator.mediaDevices.setCaptureHandleConfig) && !isEmbedded();
184
         const tabId = uuidV4();
184
         const tabId = uuidV4();
185
 
185
 
186
         this.selfRecording.on = onlySelf;
186
         this.selfRecording.on = onlySelf;

正在加载...
取消
保存