@axa-fr/oidc-client 7.27.11 → 7.27.13
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 +30 -0
- package/dist/events.d.ts +1 -0
- package/dist/events.d.ts.map +1 -1
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1164 -1123
- package/dist/index.umd.cjs +2 -2
- package/dist/initWorker.d.ts +22 -0
- package/dist/initWorker.d.ts.map +1 -1
- package/dist/oidc.d.ts +1 -0
- package/dist/oidc.d.ts.map +1 -1
- package/dist/oidcClient.d.ts +15 -0
- package/dist/oidcClient.d.ts.map +1 -1
- package/dist/protocol.d.ts +75 -0
- package/dist/protocol.d.ts.map +1 -0
- package/dist/protocol.spec.d.ts +2 -0
- package/dist/protocol.spec.d.ts.map +1 -0
- package/dist/signalServiceWorker.spec.d.ts +2 -0
- package/dist/signalServiceWorker.spec.d.ts.map +1 -0
- package/dist/types.d.ts +1 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/version.d.ts +1 -1
- package/package.json +2 -2
- package/src/events.ts +1 -0
- package/src/index.ts +20 -0
- package/src/initWorker.ts +51 -2
- package/src/oidcClient.ts +29 -0
- package/src/protocol.spec.ts +96 -0
- package/src/protocol.ts +106 -0
- package/src/signalServiceWorker.spec.ts +77 -0
- package/src/types.ts +1 -0
- package/src/version.ts +1 -1
package/src/initWorker.ts
CHANGED
|
@@ -4,6 +4,20 @@ import timer from './timer.js';
|
|
|
4
4
|
import { OidcConfiguration } from './types.js';
|
|
5
5
|
import codeVersion from './version.js';
|
|
6
6
|
|
|
7
|
+
export const DEFAULT_SW_MESSAGE_TIMEOUT_MS = 5000;
|
|
8
|
+
|
|
9
|
+
export interface ServiceWorkerSignalMessage {
|
|
10
|
+
type: string;
|
|
11
|
+
configurationName?: string;
|
|
12
|
+
data?: unknown;
|
|
13
|
+
tabId?: string;
|
|
14
|
+
[key: string]: unknown;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export interface ServiceWorkerSignalOptions {
|
|
18
|
+
timeoutMs?: number;
|
|
19
|
+
}
|
|
20
|
+
|
|
7
21
|
let keepAliveServiceWorkerTimeoutId = null;
|
|
8
22
|
let keepAliveController: AbortController | undefined;
|
|
9
23
|
|
|
@@ -57,8 +71,6 @@ export const getTabId = (configurationName: string) => {
|
|
|
57
71
|
return newTabId;
|
|
58
72
|
};
|
|
59
73
|
|
|
60
|
-
const DEFAULT_SW_MESSAGE_TIMEOUT_MS = 5000;
|
|
61
|
-
|
|
62
74
|
const getServiceWorkerTarget = (registration: ServiceWorkerRegistration): ServiceWorker | null => {
|
|
63
75
|
return (
|
|
64
76
|
navigator.serviceWorker.controller ??
|
|
@@ -673,6 +685,18 @@ export const initWorkerAsync = async (
|
|
|
673
685
|
});
|
|
674
686
|
};
|
|
675
687
|
|
|
688
|
+
const signalAsync = (
|
|
689
|
+
message: ServiceWorkerSignalMessage,
|
|
690
|
+
options?: ServiceWorkerSignalOptions,
|
|
691
|
+
): Promise<any> =>
|
|
692
|
+
sendMessageAsync(
|
|
693
|
+
registration,
|
|
694
|
+
options,
|
|
695
|
+
)({
|
|
696
|
+
...message,
|
|
697
|
+
configurationName: message.configurationName ?? configurationName,
|
|
698
|
+
});
|
|
699
|
+
|
|
676
700
|
return {
|
|
677
701
|
clearAsync,
|
|
678
702
|
initAsync,
|
|
@@ -692,5 +716,30 @@ export const initWorkerAsync = async (
|
|
|
692
716
|
getDemonstratingProofOfPossessionNonce,
|
|
693
717
|
setDemonstratingProofOfPossessionJwkAsync,
|
|
694
718
|
getDemonstratingProofOfPossessionJwkAsync,
|
|
719
|
+
signalAsync,
|
|
695
720
|
};
|
|
696
721
|
};
|
|
722
|
+
|
|
723
|
+
/**
|
|
724
|
+
* Sends a typed message to the OIDC service worker for the given
|
|
725
|
+
* configuration. Wraps `MessageChannel` setup, request/response correlation
|
|
726
|
+
* and timeouts.
|
|
727
|
+
*
|
|
728
|
+
* Resolves with the SW response, rejects on timeout or when no SW is
|
|
729
|
+
* registered for the configuration. The provided `configurationName` is
|
|
730
|
+
* used when the message itself does not carry one.
|
|
731
|
+
*/
|
|
732
|
+
export const signalServiceWorkerAsync = async (
|
|
733
|
+
configuration: OidcConfiguration,
|
|
734
|
+
configurationName: string,
|
|
735
|
+
message: ServiceWorkerSignalMessage,
|
|
736
|
+
options?: ServiceWorkerSignalOptions,
|
|
737
|
+
): Promise<any> => {
|
|
738
|
+
const worker = await initWorkerAsync(configuration, configurationName);
|
|
739
|
+
if (!worker) {
|
|
740
|
+
throw new Error(
|
|
741
|
+
`signalServiceWorkerAsync: no service worker registered for configuration "${configurationName}"`,
|
|
742
|
+
);
|
|
743
|
+
}
|
|
744
|
+
return worker.signalAsync(message, options);
|
|
745
|
+
};
|
package/src/oidcClient.ts
CHANGED
|
@@ -1,4 +1,9 @@
|
|
|
1
1
|
import { fetchWithTokens } from './fetch';
|
|
2
|
+
import {
|
|
3
|
+
ServiceWorkerSignalMessage,
|
|
4
|
+
ServiceWorkerSignalOptions,
|
|
5
|
+
signalServiceWorkerAsync,
|
|
6
|
+
} from './initWorker.js';
|
|
2
7
|
import { ILOidcLocation, OidcLocation } from './location';
|
|
3
8
|
import { LoginCallback, Oidc } from './oidc.js';
|
|
4
9
|
import { getValidTokenAsync, OidcToken, Tokens, ValidToken } from './parseTokens.js';
|
|
@@ -130,6 +135,30 @@ export class OidcClient {
|
|
|
130
135
|
userInfo<T extends OidcUserInfo = OidcUserInfo>(): T {
|
|
131
136
|
return this._oidc.userInfo;
|
|
132
137
|
}
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* High-level helper to send a message to the OIDC service worker.
|
|
141
|
+
*
|
|
142
|
+
* Wraps the low-level `postMessage` + `MessageChannel` plumbing and
|
|
143
|
+
* returns the response posted back by the worker. Use the typed message
|
|
144
|
+
* symbols exported from `@axa-fr/oidc-client-service-worker/protocol`
|
|
145
|
+
* (`ServiceWorkerMessageType`) to build messages.
|
|
146
|
+
*
|
|
147
|
+
* @throws if no service worker is registered for the current
|
|
148
|
+
* configuration, or if the worker does not respond before the timeout
|
|
149
|
+
* elapses.
|
|
150
|
+
*/
|
|
151
|
+
async signalServiceWorker<TResponse = unknown>(
|
|
152
|
+
message: ServiceWorkerSignalMessage,
|
|
153
|
+
options?: ServiceWorkerSignalOptions,
|
|
154
|
+
): Promise<TResponse> {
|
|
155
|
+
return signalServiceWorkerAsync(
|
|
156
|
+
this._oidc.configuration,
|
|
157
|
+
this._oidc.configurationName,
|
|
158
|
+
message,
|
|
159
|
+
options,
|
|
160
|
+
) as Promise<TResponse>;
|
|
161
|
+
}
|
|
133
162
|
}
|
|
134
163
|
|
|
135
164
|
export interface OidcUserInfo {
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import { describe, expect, it } from 'vitest';
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
buildDpopSecuredPlaceholder,
|
|
5
|
+
buildSecuredTokenPlaceholder,
|
|
6
|
+
buildStorageKey,
|
|
7
|
+
DPOP_TOKEN_PLACEHOLDER_PREFIX,
|
|
8
|
+
isServiceWorkerMessageType,
|
|
9
|
+
PROTOCOL_VERSION,
|
|
10
|
+
ServiceWorkerMessageType,
|
|
11
|
+
STORAGE_KEY_PREFIX,
|
|
12
|
+
SW_CONTROLLER_CHANGE_RELOAD_COUNT_KEY,
|
|
13
|
+
TOKEN_PLACEHOLDERS,
|
|
14
|
+
} from './protocol';
|
|
15
|
+
|
|
16
|
+
describe('public oidc-client protocol surface', () => {
|
|
17
|
+
it('exposes a stable PROTOCOL_VERSION', () => {
|
|
18
|
+
expect(PROTOCOL_VERSION).toMatch(/^\d+\.\d+\.\d+$/);
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
it('matches the wire-level message types documented in PROTOCOL.md', () => {
|
|
22
|
+
expect(ServiceWorkerMessageType).toEqual({
|
|
23
|
+
SKIP_WAITING: 'SKIP_WAITING',
|
|
24
|
+
CLAIM: 'claim',
|
|
25
|
+
CLEAR: 'clear',
|
|
26
|
+
INIT: 'init',
|
|
27
|
+
SET_STATE: 'setState',
|
|
28
|
+
GET_STATE: 'getState',
|
|
29
|
+
SET_CODE_VERIFIER: 'setCodeVerifier',
|
|
30
|
+
GET_CODE_VERIFIER: 'getCodeVerifier',
|
|
31
|
+
SET_SESSION_STATE: 'setSessionState',
|
|
32
|
+
GET_SESSION_STATE: 'getSessionState',
|
|
33
|
+
SET_NONCE: 'setNonce',
|
|
34
|
+
GET_NONCE: 'getNonce',
|
|
35
|
+
SET_DPOP_NONCE: 'setDemonstratingProofOfPossessionNonce',
|
|
36
|
+
GET_DPOP_NONCE: 'getDemonstratingProofOfPossessionNonce',
|
|
37
|
+
SET_DPOP_JWK: 'setDemonstratingProofOfPossessionJwk',
|
|
38
|
+
GET_DPOP_JWK: 'getDemonstratingProofOfPossessionJwk',
|
|
39
|
+
});
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
it('exposes the token placeholders the service worker emits', () => {
|
|
43
|
+
expect(TOKEN_PLACEHOLDERS).toEqual({
|
|
44
|
+
ACCESS_TOKEN: 'ACCESS_TOKEN_SECURED_BY_OIDC_SERVICE_WORKER',
|
|
45
|
+
REFRESH_TOKEN: 'REFRESH_TOKEN_SECURED_BY_OIDC_SERVICE_WORKER',
|
|
46
|
+
NONCE_TOKEN: 'NONCE_SECURED_BY_OIDC_SERVICE_WORKER',
|
|
47
|
+
CODE_VERIFIER: 'CODE_VERIFIER_SECURED_BY_OIDC_SERVICE_WORKER',
|
|
48
|
+
});
|
|
49
|
+
expect(DPOP_TOKEN_PLACEHOLDER_PREFIX).toBe('DPOP_SECURED_BY_OIDC_SERVICE_WORKER');
|
|
50
|
+
});
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
describe('protocol helpers', () => {
|
|
54
|
+
it('builds secured token placeholders that match the SW output', () => {
|
|
55
|
+
expect(buildSecuredTokenPlaceholder(TOKEN_PLACEHOLDERS.ACCESS_TOKEN, 'demo', 'tab-1')).toBe(
|
|
56
|
+
'ACCESS_TOKEN_SECURED_BY_OIDC_SERVICE_WORKER_demo#tabId=tab-1',
|
|
57
|
+
);
|
|
58
|
+
expect(buildSecuredTokenPlaceholder(TOKEN_PLACEHOLDERS.NONCE_TOKEN, 'demo')).toBe(
|
|
59
|
+
'NONCE_SECURED_BY_OIDC_SERVICE_WORKER_demo#tabId=default',
|
|
60
|
+
);
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
it('builds DPoP placeholders that match the SW output', () => {
|
|
64
|
+
expect(buildDpopSecuredPlaceholder('demo', 'tab-2')).toBe(
|
|
65
|
+
`${DPOP_TOKEN_PLACEHOLDER_PREFIX}_demo#tabId=tab-2`,
|
|
66
|
+
);
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
it.each([
|
|
70
|
+
[STORAGE_KEY_PREFIX.STATE, 'demo', 'oidc.state.demo'],
|
|
71
|
+
[STORAGE_KEY_PREFIX.NONCE, 'demo', 'oidc.nonce.demo'],
|
|
72
|
+
[STORAGE_KEY_PREFIX.CODE_VERIFIER, 'demo', 'oidc.code_verifier.demo'],
|
|
73
|
+
[STORAGE_KEY_PREFIX.LOGIN_PARAMS, 'demo', 'oidc.login.demo'],
|
|
74
|
+
[STORAGE_KEY_PREFIX.TAB_ID, 'demo', 'oidc.tabId.demo'],
|
|
75
|
+
])('combines storage prefix %s + %s into %s', (prefix, configurationName, expected) => {
|
|
76
|
+
expect(buildStorageKey(prefix, configurationName)).toBe(expected);
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
it('exposes the SW controllerchange reload counter key', () => {
|
|
80
|
+
expect(SW_CONTROLLER_CHANGE_RELOAD_COUNT_KEY).toBe('oidc.sw.controllerchange_reload_count');
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
it.each(Object.values(ServiceWorkerMessageType))(
|
|
84
|
+
'recognises "%s" as a known message type',
|
|
85
|
+
type => {
|
|
86
|
+
expect(isServiceWorkerMessageType(type)).toBe(true);
|
|
87
|
+
},
|
|
88
|
+
);
|
|
89
|
+
|
|
90
|
+
it.each(['unknown', '', 42, null, undefined, {}])(
|
|
91
|
+
'rejects %p as not a known message type',
|
|
92
|
+
value => {
|
|
93
|
+
expect(isServiceWorkerMessageType(value)).toBe(false);
|
|
94
|
+
},
|
|
95
|
+
);
|
|
96
|
+
});
|
package/src/protocol.ts
ADDED
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Public, supported entry point for the OIDC service worker `postMessage`
|
|
3
|
+
* protocol, available directly from `@axa-fr/oidc-client`.
|
|
4
|
+
*
|
|
5
|
+
* The same exports are also published from
|
|
6
|
+
* `@axa-fr/oidc-client-service-worker/protocol`. The two modules are kept
|
|
7
|
+
* deliberately in sync (and verified by a unit test) so applications that
|
|
8
|
+
* depend only on `@axa-fr/oidc-client` can interact with the service worker
|
|
9
|
+
* without adding a transitive dependency.
|
|
10
|
+
*
|
|
11
|
+
* See `packages/oidc-client-service-worker/PROTOCOL.md` for the full
|
|
12
|
+
* specification.
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Semver-protected version of the service worker `postMessage` protocol.
|
|
17
|
+
*/
|
|
18
|
+
export const PROTOCOL_VERSION = '1.0.0' as const;
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Every supported service worker message type. The values are also the
|
|
22
|
+
* literal strings used on the wire as `MessageEventData.type` and must
|
|
23
|
+
* remain stable across patch and minor versions of the protocol.
|
|
24
|
+
*/
|
|
25
|
+
export const ServiceWorkerMessageType = {
|
|
26
|
+
SKIP_WAITING: 'SKIP_WAITING',
|
|
27
|
+
CLAIM: 'claim',
|
|
28
|
+
CLEAR: 'clear',
|
|
29
|
+
INIT: 'init',
|
|
30
|
+
SET_STATE: 'setState',
|
|
31
|
+
GET_STATE: 'getState',
|
|
32
|
+
SET_CODE_VERIFIER: 'setCodeVerifier',
|
|
33
|
+
GET_CODE_VERIFIER: 'getCodeVerifier',
|
|
34
|
+
SET_SESSION_STATE: 'setSessionState',
|
|
35
|
+
GET_SESSION_STATE: 'getSessionState',
|
|
36
|
+
SET_NONCE: 'setNonce',
|
|
37
|
+
GET_NONCE: 'getNonce',
|
|
38
|
+
SET_DPOP_NONCE: 'setDemonstratingProofOfPossessionNonce',
|
|
39
|
+
GET_DPOP_NONCE: 'getDemonstratingProofOfPossessionNonce',
|
|
40
|
+
SET_DPOP_JWK: 'setDemonstratingProofOfPossessionJwk',
|
|
41
|
+
GET_DPOP_JWK: 'getDemonstratingProofOfPossessionJwk',
|
|
42
|
+
} as const;
|
|
43
|
+
|
|
44
|
+
export type ServiceWorkerMessageTypeKey = keyof typeof ServiceWorkerMessageType;
|
|
45
|
+
export type ServiceWorkerMessageTypeValue =
|
|
46
|
+
(typeof ServiceWorkerMessageType)[ServiceWorkerMessageTypeKey];
|
|
47
|
+
|
|
48
|
+
export interface ServiceWorkerMessage<TData = unknown> {
|
|
49
|
+
type: ServiceWorkerMessageTypeValue | 'SKIP_WAITING' | 'claim';
|
|
50
|
+
configurationName: string;
|
|
51
|
+
data: TData;
|
|
52
|
+
tabId?: string;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export interface ServiceWorkerResponse {
|
|
56
|
+
configurationName?: string;
|
|
57
|
+
error?: unknown;
|
|
58
|
+
[key: string]: unknown;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/** Stable internal token placeholders – matched by the SW request handler. */
|
|
62
|
+
export const TOKEN_PLACEHOLDERS = {
|
|
63
|
+
ACCESS_TOKEN: 'ACCESS_TOKEN_SECURED_BY_OIDC_SERVICE_WORKER',
|
|
64
|
+
REFRESH_TOKEN: 'REFRESH_TOKEN_SECURED_BY_OIDC_SERVICE_WORKER',
|
|
65
|
+
NONCE_TOKEN: 'NONCE_SECURED_BY_OIDC_SERVICE_WORKER',
|
|
66
|
+
CODE_VERIFIER: 'CODE_VERIFIER_SECURED_BY_OIDC_SERVICE_WORKER',
|
|
67
|
+
} as const;
|
|
68
|
+
|
|
69
|
+
export const DPOP_TOKEN_PLACEHOLDER_PREFIX = 'DPOP_SECURED_BY_OIDC_SERVICE_WORKER' as const;
|
|
70
|
+
|
|
71
|
+
export const STORAGE_KEY_PREFIX = {
|
|
72
|
+
TAB_ID: 'oidc.tabId.',
|
|
73
|
+
STATE: 'oidc.state.',
|
|
74
|
+
NONCE: 'oidc.nonce.',
|
|
75
|
+
CODE_VERIFIER: 'oidc.code_verifier.',
|
|
76
|
+
LOGIN_PARAMS: 'oidc.login.',
|
|
77
|
+
SW_VERSION_MISMATCH_RELOAD: 'oidc.sw.version_mismatch_reload.',
|
|
78
|
+
} as const;
|
|
79
|
+
|
|
80
|
+
export const SW_CONTROLLER_CHANGE_RELOAD_COUNT_KEY =
|
|
81
|
+
'oidc.sw.controllerchange_reload_count' as const;
|
|
82
|
+
|
|
83
|
+
export const buildStorageKey = (
|
|
84
|
+
prefix: (typeof STORAGE_KEY_PREFIX)[keyof typeof STORAGE_KEY_PREFIX],
|
|
85
|
+
configurationName: string,
|
|
86
|
+
): string => `${prefix}${configurationName}`;
|
|
87
|
+
|
|
88
|
+
export const buildSecuredTokenPlaceholder = (
|
|
89
|
+
placeholder: (typeof TOKEN_PLACEHOLDERS)[keyof typeof TOKEN_PLACEHOLDERS],
|
|
90
|
+
configurationName: string,
|
|
91
|
+
tabId: string = 'default',
|
|
92
|
+
): string => `${placeholder}_${configurationName}#tabId=${tabId}`;
|
|
93
|
+
|
|
94
|
+
export const buildDpopSecuredPlaceholder = (
|
|
95
|
+
configurationName: string,
|
|
96
|
+
tabId: string = 'default',
|
|
97
|
+
): string => `${DPOP_TOKEN_PLACEHOLDER_PREFIX}_${configurationName}#tabId=${tabId}`;
|
|
98
|
+
|
|
99
|
+
export const isServiceWorkerMessageType = (
|
|
100
|
+
value: unknown,
|
|
101
|
+
): value is ServiceWorkerMessageTypeValue => {
|
|
102
|
+
if (typeof value !== 'string') {
|
|
103
|
+
return false;
|
|
104
|
+
}
|
|
105
|
+
return Object.values(ServiceWorkerMessageType).includes(value as ServiceWorkerMessageTypeValue);
|
|
106
|
+
};
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { afterEach, describe, expect, it, vi } from 'vitest';
|
|
2
|
+
|
|
3
|
+
import * as initWorker from './initWorker';
|
|
4
|
+
import { OidcClient } from './oidcClient';
|
|
5
|
+
import { ServiceWorkerMessageType } from './protocol';
|
|
6
|
+
|
|
7
|
+
const buildClient = (overrides: Partial<{ configurationName: string }> = {}) => {
|
|
8
|
+
const oidc = {
|
|
9
|
+
configuration: { client_id: 'demo-client' },
|
|
10
|
+
configurationName: overrides.configurationName ?? 'demo',
|
|
11
|
+
};
|
|
12
|
+
return new OidcClient(oidc as never);
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
describe('OidcClient.signalServiceWorker', () => {
|
|
16
|
+
afterEach(() => {
|
|
17
|
+
vi.restoreAllMocks();
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
it('forwards the typed message to signalServiceWorkerAsync with the OIDC config', async () => {
|
|
21
|
+
const expected = { configurationName: 'demo', state: 'restored-state' };
|
|
22
|
+
const spy = vi
|
|
23
|
+
.spyOn(initWorker, 'signalServiceWorkerAsync')
|
|
24
|
+
.mockResolvedValue(expected as never);
|
|
25
|
+
|
|
26
|
+
const client = buildClient();
|
|
27
|
+
const response = await client.signalServiceWorker<{ state: string }>({
|
|
28
|
+
type: ServiceWorkerMessageType.GET_STATE,
|
|
29
|
+
configurationName: 'demo',
|
|
30
|
+
data: null,
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
expect(response).toEqual(expected);
|
|
34
|
+
expect(spy).toHaveBeenCalledOnce();
|
|
35
|
+
expect(spy).toHaveBeenCalledWith(
|
|
36
|
+
{ client_id: 'demo-client' },
|
|
37
|
+
'demo',
|
|
38
|
+
expect.objectContaining({
|
|
39
|
+
type: 'getState',
|
|
40
|
+
data: null,
|
|
41
|
+
}),
|
|
42
|
+
undefined,
|
|
43
|
+
);
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
it('propagates a custom timeout option', async () => {
|
|
47
|
+
const spy = vi.spyOn(initWorker, 'signalServiceWorkerAsync').mockResolvedValue({} as never);
|
|
48
|
+
|
|
49
|
+
const client = buildClient();
|
|
50
|
+
await client.signalServiceWorker(
|
|
51
|
+
{ type: ServiceWorkerMessageType.CLEAR, configurationName: 'demo', data: { status: null } },
|
|
52
|
+
{ timeoutMs: 9000 },
|
|
53
|
+
);
|
|
54
|
+
|
|
55
|
+
expect(spy).toHaveBeenCalledWith(
|
|
56
|
+
expect.anything(),
|
|
57
|
+
'demo',
|
|
58
|
+
expect.objectContaining({ type: 'clear' }),
|
|
59
|
+
{ timeoutMs: 9000 },
|
|
60
|
+
);
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
it('rejects when the underlying helper rejects', async () => {
|
|
64
|
+
const error = new Error('no SW');
|
|
65
|
+
vi.spyOn(initWorker, 'signalServiceWorkerAsync').mockRejectedValue(error);
|
|
66
|
+
|
|
67
|
+
const client = buildClient();
|
|
68
|
+
|
|
69
|
+
await expect(
|
|
70
|
+
client.signalServiceWorker({
|
|
71
|
+
type: ServiceWorkerMessageType.GET_STATE,
|
|
72
|
+
configurationName: 'demo',
|
|
73
|
+
data: null,
|
|
74
|
+
}),
|
|
75
|
+
).rejects.toBe(error);
|
|
76
|
+
});
|
|
77
|
+
});
|
package/src/types.ts
CHANGED
|
@@ -46,6 +46,7 @@ export type OidcConfiguration = {
|
|
|
46
46
|
demonstrating_proof_of_possession?: boolean;
|
|
47
47
|
demonstrating_proof_of_possession_configuration?: DemonstratingProofOfPossessionConfiguration;
|
|
48
48
|
preload_user_info?: boolean;
|
|
49
|
+
loading_timeout_ms?: number;
|
|
49
50
|
};
|
|
50
51
|
|
|
51
52
|
export interface DemonstratingProofOfPossessionConfiguration {
|
package/src/version.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export default '7.27.
|
|
1
|
+
export default '7.27.13';
|