@okta/okta-signin-widget 7.13.0 → 7.13.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -5
- package/dist/esm/src/config/config.json.js +1 -1
- package/dist/js/okta-sign-in.classic.js +1 -1
- package/dist/js/okta-sign-in.classic.min.js +1 -1
- package/dist/js/okta-sign-in.js +1 -1
- package/dist/js/okta-sign-in.min.js +1 -1
- package/dist/js/okta-sign-in.next.js +2 -2
- package/dist/js/okta-sign-in.next.js.map +1 -1
- package/dist/js/okta-sign-in.next.no-polyfill.js +10 -10
- package/dist/js/okta-sign-in.next.no-polyfill.js.map +1 -1
- package/dist/js/okta-sign-in.no-polyfill.min.js +1 -1
- package/dist/js/okta-sign-in.oie.js +1 -1
- package/dist/js/okta-sign-in.oie.min.js +1 -1
- package/package.json +3 -3
- package/src/config/config.json +1 -1
- package/src/v3/hooks/useOnSubmit.ts +0 -12
- package/src/v3/src/hooks/useOnSubmit.ts +0 -12
- package/src/v3/src/util/browserUtils.ts +0 -4
- package/src/v3/util/browserUtils.ts +0 -4
- package/src/v3/src/util/deviceFingerprintingUtils.test.ts +0 -144
- package/src/v3/src/util/deviceFingerprintingUtils.ts +0 -99
- package/src/v3/util/deviceFingerprintingUtils.ts +0 -99
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"private": false,
|
|
3
3
|
"name": "@okta/okta-signin-widget",
|
|
4
4
|
"description": "The Okta Sign-In Widget",
|
|
5
|
-
"version": "7.13.
|
|
5
|
+
"version": "7.13.1",
|
|
6
6
|
"homepage": "https://github.com/okta/okta-signin-widget",
|
|
7
7
|
"license": "Apache-2.0",
|
|
8
8
|
"repository": {
|
|
@@ -291,7 +291,7 @@
|
|
|
291
291
|
"workerDirectory": "playground"
|
|
292
292
|
},
|
|
293
293
|
"okta": {
|
|
294
|
-
"commitSha": "
|
|
295
|
-
"fullVersion": "7.13.
|
|
294
|
+
"commitSha": "a1ffb10459f45fb281da734bbea061e5bbed5d30",
|
|
295
|
+
"fullVersion": "7.13.1-ga1ffb10"
|
|
296
296
|
}
|
|
297
297
|
}
|
package/src/config/config.json
CHANGED
|
@@ -20,7 +20,6 @@ import {
|
|
|
20
20
|
} from '@okta/okta-auth-js';
|
|
21
21
|
import { cloneDeep, merge, omit } from 'lodash';
|
|
22
22
|
import { useCallback } from 'preact/hooks';
|
|
23
|
-
import { generateDeviceFingerprint } from 'src/util/deviceFingerprintingUtils';
|
|
24
23
|
|
|
25
24
|
import { IDX_STEP, ON_PREM_TOKEN_CHANGE_ERROR_KEY } from '../constants';
|
|
26
25
|
import { useWidgetContext } from '../contexts';
|
|
@@ -28,7 +27,6 @@ import { MessageType } from '../types';
|
|
|
28
27
|
import {
|
|
29
28
|
areTransactionsEqual,
|
|
30
29
|
containsMessageKey,
|
|
31
|
-
getBaseUrl,
|
|
32
30
|
getErrorEventContext,
|
|
33
31
|
getImmutableData,
|
|
34
32
|
isConfigRecoverFlow,
|
|
@@ -211,16 +209,6 @@ export const useOnSubmit = (): (options: OnSubmitHandlerOptions) => Promise<void
|
|
|
211
209
|
if (step === IDX_STEP.CANCEL_TRANSACTION) {
|
|
212
210
|
SessionStorage.removeStateHandle();
|
|
213
211
|
}
|
|
214
|
-
if (step === IDX_STEP.IDENTIFY && features?.deviceFingerprinting) {
|
|
215
|
-
const baseUrl = getBaseUrl(widgetProps);
|
|
216
|
-
if (baseUrl) {
|
|
217
|
-
// Proceeds with form submission even if device fingerprinting fails
|
|
218
|
-
const fingerprint = await generateDeviceFingerprint(baseUrl).catch(() => undefined);
|
|
219
|
-
if (fingerprint) {
|
|
220
|
-
authClient.http.setRequestHeader('X-Device-Fingerprint', fingerprint);
|
|
221
|
-
}
|
|
222
|
-
}
|
|
223
|
-
}
|
|
224
212
|
setMessage(undefined);
|
|
225
213
|
try {
|
|
226
214
|
let newTransaction = await fn(payload);
|
|
@@ -20,7 +20,6 @@ import {
|
|
|
20
20
|
} from '@okta/okta-auth-js';
|
|
21
21
|
import { cloneDeep, merge, omit } from 'lodash';
|
|
22
22
|
import { useCallback } from 'preact/hooks';
|
|
23
|
-
import { generateDeviceFingerprint } from 'src/util/deviceFingerprintingUtils';
|
|
24
23
|
|
|
25
24
|
import { IDX_STEP, ON_PREM_TOKEN_CHANGE_ERROR_KEY } from '../constants';
|
|
26
25
|
import { useWidgetContext } from '../contexts';
|
|
@@ -28,7 +27,6 @@ import { MessageType } from '../types';
|
|
|
28
27
|
import {
|
|
29
28
|
areTransactionsEqual,
|
|
30
29
|
containsMessageKey,
|
|
31
|
-
getBaseUrl,
|
|
32
30
|
getErrorEventContext,
|
|
33
31
|
getImmutableData,
|
|
34
32
|
isConfigRecoverFlow,
|
|
@@ -211,16 +209,6 @@ export const useOnSubmit = (): (options: OnSubmitHandlerOptions) => Promise<void
|
|
|
211
209
|
if (step === IDX_STEP.CANCEL_TRANSACTION) {
|
|
212
210
|
SessionStorage.removeStateHandle();
|
|
213
211
|
}
|
|
214
|
-
if (step === IDX_STEP.IDENTIFY && features?.deviceFingerprinting) {
|
|
215
|
-
const baseUrl = getBaseUrl(widgetProps);
|
|
216
|
-
if (baseUrl) {
|
|
217
|
-
// Proceeds with form submission even if device fingerprinting fails
|
|
218
|
-
const fingerprint = await generateDeviceFingerprint(baseUrl).catch(() => undefined);
|
|
219
|
-
if (fingerprint) {
|
|
220
|
-
authClient.http.setRequestHeader('X-Device-Fingerprint', fingerprint);
|
|
221
|
-
}
|
|
222
|
-
}
|
|
223
|
-
}
|
|
224
212
|
setMessage(undefined);
|
|
225
213
|
try {
|
|
226
214
|
let newTransaction = await fn(payload);
|
|
@@ -24,7 +24,3 @@ export const isIOS = (): boolean => (
|
|
|
24
24
|
);
|
|
25
25
|
|
|
26
26
|
export const isAndroidOrIOS = (): boolean => isAndroid() || isIOS();
|
|
27
|
-
|
|
28
|
-
export const getUserAgent = (): string => navigator.userAgent;
|
|
29
|
-
|
|
30
|
-
export const isWindowsPhone = (userAgent: string): RegExpMatchArray | null => userAgent.match(/windows phone|iemobile|wpdesktop/i);
|
|
@@ -24,7 +24,3 @@ export const isIOS = (): boolean => (
|
|
|
24
24
|
);
|
|
25
25
|
|
|
26
26
|
export const isAndroidOrIOS = (): boolean => isAndroid() || isIOS();
|
|
27
|
-
|
|
28
|
-
export const getUserAgent = (): string => navigator.userAgent;
|
|
29
|
-
|
|
30
|
-
export const isWindowsPhone = (userAgent: string): RegExpMatchArray | null => userAgent.match(/windows phone|iemobile|wpdesktop/i);
|
|
@@ -1,144 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* Copyright (c) 2023-present, Okta, Inc. and/or its affiliates. All rights reserved.
|
|
3
|
-
* The Okta software accompanied by this notice is provided pursuant to the Apache License, Version 2.0 (the "License.")
|
|
4
|
-
*
|
|
5
|
-
* You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0.
|
|
6
|
-
* Unless required by applicable law or agreed to in writing, software
|
|
7
|
-
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
8
|
-
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
9
|
-
*
|
|
10
|
-
* See the License for the specific language governing permissions and limitations under the License.
|
|
11
|
-
*/
|
|
12
|
-
|
|
13
|
-
import * as DeviceFingerprintingUtils from './deviceFingerprintingUtils';
|
|
14
|
-
|
|
15
|
-
describe('DeviceFingerprintingUtils', () => {
|
|
16
|
-
const oktaDomainUrl = '';
|
|
17
|
-
|
|
18
|
-
beforeAll(() => {
|
|
19
|
-
const mockForm = document.createElement('form');
|
|
20
|
-
mockForm.setAttribute('data-se', 'o-form');
|
|
21
|
-
document.body.append(mockForm);
|
|
22
|
-
});
|
|
23
|
-
|
|
24
|
-
const mockIFrameMessages = (success: boolean, errorMessage?: { type: string }) => {
|
|
25
|
-
const message = success
|
|
26
|
-
? { type: 'FingerprintAvailable', fingerprint: 'thisIsTheFingerprint' }
|
|
27
|
-
: errorMessage;
|
|
28
|
-
|
|
29
|
-
// TODO (jest): event is missing `origin` property
|
|
30
|
-
window.postMessage(JSON.stringify(message), '*');
|
|
31
|
-
};
|
|
32
|
-
|
|
33
|
-
const mockUserAgent = (userAgent: string) => {
|
|
34
|
-
jest.spyOn(navigator, 'userAgent', 'get').mockReturnValue(userAgent);
|
|
35
|
-
};
|
|
36
|
-
|
|
37
|
-
const bypassMessageSourceCheck = () => {
|
|
38
|
-
jest.spyOn(DeviceFingerprintingUtils, 'isMessageFromCorrectSource').mockReturnValue(true);
|
|
39
|
-
};
|
|
40
|
-
|
|
41
|
-
it('creates hidden iframe during fingerprint generation', async () => {
|
|
42
|
-
mockIFrameMessages(true);
|
|
43
|
-
bypassMessageSourceCheck();
|
|
44
|
-
const fingerprintPromise = DeviceFingerprintingUtils.generateDeviceFingerprint(oktaDomainUrl);
|
|
45
|
-
let iframe = document.getElementById('device-fingerprint-container');
|
|
46
|
-
expect(iframe).not.toBeNull();
|
|
47
|
-
expect(iframe).not.toBeVisible();
|
|
48
|
-
expect(iframe?.getAttribute('src')).toBe('/auth/services/devicefingerprint');
|
|
49
|
-
await fingerprintPromise;
|
|
50
|
-
iframe = document.getElementById('device-fingerprint-container');
|
|
51
|
-
expect(iframe).toBeNull();
|
|
52
|
-
});
|
|
53
|
-
|
|
54
|
-
it('returns a fingerprint if the communication with the iframe is successful', async () => {
|
|
55
|
-
mockIFrameMessages(true);
|
|
56
|
-
bypassMessageSourceCheck();
|
|
57
|
-
const fingerprint = await DeviceFingerprintingUtils.generateDeviceFingerprint(oktaDomainUrl);
|
|
58
|
-
expect(fingerprint).toBe('thisIsTheFingerprint');
|
|
59
|
-
});
|
|
60
|
-
|
|
61
|
-
it('fails if the iframe does not load', async () => {
|
|
62
|
-
await expect(DeviceFingerprintingUtils.generateDeviceFingerprint(oktaDomainUrl))
|
|
63
|
-
.rejects
|
|
64
|
-
.toThrow('Service not available');
|
|
65
|
-
const iframe = document.getElementById('device-fingerprint-container');
|
|
66
|
-
expect(iframe).toBeNull();
|
|
67
|
-
});
|
|
68
|
-
|
|
69
|
-
it('clears iframe timeout once the iframe loads', async () => {
|
|
70
|
-
mockIFrameMessages(true);
|
|
71
|
-
bypassMessageSourceCheck();
|
|
72
|
-
|
|
73
|
-
const clearTimeoutSpy = jest.spyOn(window, 'clearTimeout');
|
|
74
|
-
|
|
75
|
-
await expect(DeviceFingerprintingUtils.generateDeviceFingerprint(oktaDomainUrl))
|
|
76
|
-
.resolves
|
|
77
|
-
.toBe('thisIsTheFingerprint');
|
|
78
|
-
expect(clearTimeoutSpy).toHaveBeenCalled();
|
|
79
|
-
});
|
|
80
|
-
|
|
81
|
-
it('fails if there is a problem with communicating with the iframe', async () => {
|
|
82
|
-
mockIFrameMessages(false);
|
|
83
|
-
bypassMessageSourceCheck();
|
|
84
|
-
|
|
85
|
-
await expect(DeviceFingerprintingUtils.generateDeviceFingerprint(oktaDomainUrl))
|
|
86
|
-
.rejects
|
|
87
|
-
.toThrow('No data');
|
|
88
|
-
const iframe = document.getElementById('device-fingerprint-container');
|
|
89
|
-
expect(iframe).toBeNull();
|
|
90
|
-
});
|
|
91
|
-
|
|
92
|
-
it('fails if there iframe sends and invalid message content', async () => {
|
|
93
|
-
mockIFrameMessages(false, { type: 'InvalidMessageType' });
|
|
94
|
-
bypassMessageSourceCheck();
|
|
95
|
-
|
|
96
|
-
await expect(DeviceFingerprintingUtils.generateDeviceFingerprint(oktaDomainUrl))
|
|
97
|
-
.rejects
|
|
98
|
-
.toThrow('No data');
|
|
99
|
-
const iframe = document.getElementById('device-fingerprint-container');
|
|
100
|
-
expect(iframe).toBeNull();
|
|
101
|
-
});
|
|
102
|
-
|
|
103
|
-
it('fails if user agent is not defined', async () => {
|
|
104
|
-
mockUserAgent('');
|
|
105
|
-
mockIFrameMessages(true);
|
|
106
|
-
|
|
107
|
-
await expect(DeviceFingerprintingUtils.generateDeviceFingerprint(oktaDomainUrl))
|
|
108
|
-
.rejects
|
|
109
|
-
.toThrow('User agent is not defined');
|
|
110
|
-
const iframe = document.getElementById('device-fingerprint-container');
|
|
111
|
-
expect(iframe).toBeNull();
|
|
112
|
-
});
|
|
113
|
-
|
|
114
|
-
it('fails if it is called from a Windows phone', async () => {
|
|
115
|
-
mockUserAgent('Windows Phone');
|
|
116
|
-
mockIFrameMessages(true);
|
|
117
|
-
|
|
118
|
-
await expect(DeviceFingerprintingUtils.generateDeviceFingerprint(oktaDomainUrl))
|
|
119
|
-
.rejects
|
|
120
|
-
.toThrow('Device fingerprint is not supported on Windows phones');
|
|
121
|
-
const iframe = document.getElementById('device-fingerprint-container');
|
|
122
|
-
expect(iframe).toBeNull();
|
|
123
|
-
});
|
|
124
|
-
|
|
125
|
-
it('fails if it the iframe does not load or there is a slow connection', async () => {
|
|
126
|
-
// Not sending any mock messages should trigger a timeout
|
|
127
|
-
await expect(DeviceFingerprintingUtils.generateDeviceFingerprint(oktaDomainUrl))
|
|
128
|
-
.rejects
|
|
129
|
-
.toThrow('Service not available');
|
|
130
|
-
const iframe = document.getElementById('device-fingerprint-container');
|
|
131
|
-
expect(iframe).toBeNull();
|
|
132
|
-
});
|
|
133
|
-
|
|
134
|
-
it('fails if it there is no form to attach the iframe to', async () => {
|
|
135
|
-
const form = document.querySelector('form[data-se="o-form"]');
|
|
136
|
-
expect(form).not.toBeNull();
|
|
137
|
-
document.body.removeChild(form!);
|
|
138
|
-
await expect(DeviceFingerprintingUtils.generateDeviceFingerprint(oktaDomainUrl))
|
|
139
|
-
.rejects
|
|
140
|
-
.toThrow('Form does not exist');
|
|
141
|
-
const iframe = document.getElementById('device-fingerprint-container');
|
|
142
|
-
expect(iframe).toBeNull();
|
|
143
|
-
});
|
|
144
|
-
});
|
|
@@ -1,99 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* Copyright (c) 2023-present, Okta, Inc. and/or its affiliates. All rights reserved.
|
|
3
|
-
* The Okta software accompanied by this notice is provided pursuant to the Apache License, Version 2.0 (the "License.")
|
|
4
|
-
*
|
|
5
|
-
* You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0.
|
|
6
|
-
* Unless required by applicable law or agreed to in writing, software
|
|
7
|
-
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
8
|
-
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
9
|
-
*
|
|
10
|
-
* See the License for the specific language governing permissions and limitations under the License.
|
|
11
|
-
*/
|
|
12
|
-
|
|
13
|
-
import { getUserAgent, isWindowsPhone } from './browserUtils';
|
|
14
|
-
|
|
15
|
-
export const isMessageFromCorrectSource = (iframe: HTMLIFrameElement, event: MessageEvent)
|
|
16
|
-
: boolean => (
|
|
17
|
-
event.source === iframe.contentWindow
|
|
18
|
-
);
|
|
19
|
-
|
|
20
|
-
// NOTE: This utility is similar to the DeviceFingerprinting.js file used for V2 authentication flows.
|
|
21
|
-
export const generateDeviceFingerprint = (oktaDomainUrl: string): Promise<string> => {
|
|
22
|
-
const userAgent = getUserAgent();
|
|
23
|
-
if (!userAgent) {
|
|
24
|
-
return Promise.reject(new Error('User agent is not defined'));
|
|
25
|
-
}
|
|
26
|
-
if (isWindowsPhone(userAgent)) {
|
|
27
|
-
return Promise.reject(new Error('Device fingerprint is not supported on Windows phones'));
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
return new Promise((resolve, reject) => {
|
|
31
|
-
let iframe: HTMLIFrameElement;
|
|
32
|
-
let iframeTimeout: NodeJS.Timeout;
|
|
33
|
-
let onMessageReceivedFromOkta: (event: MessageEvent) => void;
|
|
34
|
-
|
|
35
|
-
const removeIframe = () => {
|
|
36
|
-
iframe.remove();
|
|
37
|
-
window.removeEventListener('message', onMessageReceivedFromOkta);
|
|
38
|
-
};
|
|
39
|
-
|
|
40
|
-
const handleError = (reason: string) => {
|
|
41
|
-
removeIframe();
|
|
42
|
-
reject(new Error(reason));
|
|
43
|
-
};
|
|
44
|
-
|
|
45
|
-
const sendMessageToOkta = (message: { type: string }) => {
|
|
46
|
-
const win = iframe.contentWindow;
|
|
47
|
-
|
|
48
|
-
if (win) {
|
|
49
|
-
win.postMessage(JSON.stringify(message), oktaDomainUrl);
|
|
50
|
-
}
|
|
51
|
-
};
|
|
52
|
-
|
|
53
|
-
onMessageReceivedFromOkta = (event: MessageEvent) => {
|
|
54
|
-
if (!isMessageFromCorrectSource(iframe, event)) {
|
|
55
|
-
return;
|
|
56
|
-
}
|
|
57
|
-
// deviceFingerprint service is available, clear timeout
|
|
58
|
-
clearTimeout(iframeTimeout);
|
|
59
|
-
if (!event || !event.data || event.origin !== oktaDomainUrl) {
|
|
60
|
-
handleError('No data');
|
|
61
|
-
}
|
|
62
|
-
try {
|
|
63
|
-
const message = JSON.parse(event.data);
|
|
64
|
-
|
|
65
|
-
if (message && message.type === 'FingerprintServiceReady') {
|
|
66
|
-
sendMessageToOkta({
|
|
67
|
-
type: 'GetFingerprint',
|
|
68
|
-
});
|
|
69
|
-
} else if (message && message.type === 'FingerprintAvailable') {
|
|
70
|
-
removeIframe();
|
|
71
|
-
resolve(message.fingerprint);
|
|
72
|
-
} else {
|
|
73
|
-
handleError('No data');
|
|
74
|
-
}
|
|
75
|
-
} catch (error) {
|
|
76
|
-
// Ignore any errors since we could get other messages too
|
|
77
|
-
}
|
|
78
|
-
};
|
|
79
|
-
|
|
80
|
-
// Attach listener
|
|
81
|
-
window.addEventListener('message', onMessageReceivedFromOkta, false);
|
|
82
|
-
iframe = document.createElement('iframe');
|
|
83
|
-
iframe.id = 'device-fingerprint-container';
|
|
84
|
-
iframe.style.display = 'none';
|
|
85
|
-
// Create and load devicefingerprint page inside the iframe
|
|
86
|
-
iframe.src = `${oktaDomainUrl}/auth/services/devicefingerprint`;
|
|
87
|
-
|
|
88
|
-
const formElement = document.querySelector('form[data-se="o-form"]');
|
|
89
|
-
if (formElement === null) {
|
|
90
|
-
handleError('Form does not exist');
|
|
91
|
-
}
|
|
92
|
-
formElement!.appendChild(iframe);
|
|
93
|
-
|
|
94
|
-
iframeTimeout = setTimeout(() => {
|
|
95
|
-
// If the iframe does not load or there is a slow connection, throw an error
|
|
96
|
-
handleError('Service not available');
|
|
97
|
-
}, 2000);
|
|
98
|
-
});
|
|
99
|
-
};
|
|
@@ -1,99 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* Copyright (c) 2023-present, Okta, Inc. and/or its affiliates. All rights reserved.
|
|
3
|
-
* The Okta software accompanied by this notice is provided pursuant to the Apache License, Version 2.0 (the "License.")
|
|
4
|
-
*
|
|
5
|
-
* You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0.
|
|
6
|
-
* Unless required by applicable law or agreed to in writing, software
|
|
7
|
-
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
8
|
-
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
9
|
-
*
|
|
10
|
-
* See the License for the specific language governing permissions and limitations under the License.
|
|
11
|
-
*/
|
|
12
|
-
|
|
13
|
-
import { getUserAgent, isWindowsPhone } from './browserUtils';
|
|
14
|
-
|
|
15
|
-
export const isMessageFromCorrectSource = (iframe: HTMLIFrameElement, event: MessageEvent)
|
|
16
|
-
: boolean => (
|
|
17
|
-
event.source === iframe.contentWindow
|
|
18
|
-
);
|
|
19
|
-
|
|
20
|
-
// NOTE: This utility is similar to the DeviceFingerprinting.js file used for V2 authentication flows.
|
|
21
|
-
export const generateDeviceFingerprint = (oktaDomainUrl: string): Promise<string> => {
|
|
22
|
-
const userAgent = getUserAgent();
|
|
23
|
-
if (!userAgent) {
|
|
24
|
-
return Promise.reject(new Error('User agent is not defined'));
|
|
25
|
-
}
|
|
26
|
-
if (isWindowsPhone(userAgent)) {
|
|
27
|
-
return Promise.reject(new Error('Device fingerprint is not supported on Windows phones'));
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
return new Promise((resolve, reject) => {
|
|
31
|
-
let iframe: HTMLIFrameElement;
|
|
32
|
-
let iframeTimeout: NodeJS.Timeout;
|
|
33
|
-
let onMessageReceivedFromOkta: (event: MessageEvent) => void;
|
|
34
|
-
|
|
35
|
-
const removeIframe = () => {
|
|
36
|
-
iframe.remove();
|
|
37
|
-
window.removeEventListener('message', onMessageReceivedFromOkta);
|
|
38
|
-
};
|
|
39
|
-
|
|
40
|
-
const handleError = (reason: string) => {
|
|
41
|
-
removeIframe();
|
|
42
|
-
reject(new Error(reason));
|
|
43
|
-
};
|
|
44
|
-
|
|
45
|
-
const sendMessageToOkta = (message: { type: string }) => {
|
|
46
|
-
const win = iframe.contentWindow;
|
|
47
|
-
|
|
48
|
-
if (win) {
|
|
49
|
-
win.postMessage(JSON.stringify(message), oktaDomainUrl);
|
|
50
|
-
}
|
|
51
|
-
};
|
|
52
|
-
|
|
53
|
-
onMessageReceivedFromOkta = (event: MessageEvent) => {
|
|
54
|
-
if (!isMessageFromCorrectSource(iframe, event)) {
|
|
55
|
-
return;
|
|
56
|
-
}
|
|
57
|
-
// deviceFingerprint service is available, clear timeout
|
|
58
|
-
clearTimeout(iframeTimeout);
|
|
59
|
-
if (!event || !event.data || event.origin !== oktaDomainUrl) {
|
|
60
|
-
handleError('No data');
|
|
61
|
-
}
|
|
62
|
-
try {
|
|
63
|
-
const message = JSON.parse(event.data);
|
|
64
|
-
|
|
65
|
-
if (message && message.type === 'FingerprintServiceReady') {
|
|
66
|
-
sendMessageToOkta({
|
|
67
|
-
type: 'GetFingerprint',
|
|
68
|
-
});
|
|
69
|
-
} else if (message && message.type === 'FingerprintAvailable') {
|
|
70
|
-
removeIframe();
|
|
71
|
-
resolve(message.fingerprint);
|
|
72
|
-
} else {
|
|
73
|
-
handleError('No data');
|
|
74
|
-
}
|
|
75
|
-
} catch (error) {
|
|
76
|
-
// Ignore any errors since we could get other messages too
|
|
77
|
-
}
|
|
78
|
-
};
|
|
79
|
-
|
|
80
|
-
// Attach listener
|
|
81
|
-
window.addEventListener('message', onMessageReceivedFromOkta, false);
|
|
82
|
-
iframe = document.createElement('iframe');
|
|
83
|
-
iframe.id = 'device-fingerprint-container';
|
|
84
|
-
iframe.style.display = 'none';
|
|
85
|
-
// Create and load devicefingerprint page inside the iframe
|
|
86
|
-
iframe.src = `${oktaDomainUrl}/auth/services/devicefingerprint`;
|
|
87
|
-
|
|
88
|
-
const formElement = document.querySelector('form[data-se="o-form"]');
|
|
89
|
-
if (formElement === null) {
|
|
90
|
-
handleError('Form does not exist');
|
|
91
|
-
}
|
|
92
|
-
formElement!.appendChild(iframe);
|
|
93
|
-
|
|
94
|
-
iframeTimeout = setTimeout(() => {
|
|
95
|
-
// If the iframe does not load or there is a slow connection, throw an error
|
|
96
|
-
handleError('Service not available');
|
|
97
|
-
}, 2000);
|
|
98
|
-
});
|
|
99
|
-
};
|