@okta/spa-platform 0.6.0

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.
Files changed (82) hide show
  1. package/LICENSE +189 -0
  2. package/THIRD-PARTY-NOTICES.md +5 -0
  3. package/dist/esm/Credential/Credential.js +26 -0
  4. package/dist/esm/Credential/Credential.js.map +1 -0
  5. package/dist/esm/Credential/CredentialCoordinator.js +128 -0
  6. package/dist/esm/Credential/CredentialCoordinator.js.map +1 -0
  7. package/dist/esm/Credential/CredentialDataSource.js +24 -0
  8. package/dist/esm/Credential/CredentialDataSource.js.map +1 -0
  9. package/dist/esm/Credential/TokenStorage.js +275 -0
  10. package/dist/esm/Credential/TokenStorage.js.map +1 -0
  11. package/dist/esm/FetchClient/index.js +21 -0
  12. package/dist/esm/FetchClient/index.js.map +1 -0
  13. package/dist/esm/flows/AuthorizationCodeFlow.js +137 -0
  14. package/dist/esm/flows/AuthorizationCodeFlow.js.map +1 -0
  15. package/dist/esm/flows/SessionLogoutFlow.js +45 -0
  16. package/dist/esm/flows/SessionLogoutFlow.js.map +1 -0
  17. package/dist/esm/flows/TransactionStorage.js +32 -0
  18. package/dist/esm/flows/TransactionStorage.js.map +1 -0
  19. package/dist/esm/index.js +36 -0
  20. package/dist/esm/index.js.map +1 -0
  21. package/dist/esm/orchestrators/AuthorizationCodeFlowOrchestrator.js +124 -0
  22. package/dist/esm/orchestrators/AuthorizationCodeFlowOrchestrator.js.map +1 -0
  23. package/dist/esm/orchestrators/HostOrchestrator/Host.js +161 -0
  24. package/dist/esm/orchestrators/HostOrchestrator/Host.js.map +1 -0
  25. package/dist/esm/orchestrators/HostOrchestrator/OrchestrationBridge.js +37 -0
  26. package/dist/esm/orchestrators/HostOrchestrator/OrchestrationBridge.js.map +1 -0
  27. package/dist/esm/orchestrators/HostOrchestrator/SubApp.js +139 -0
  28. package/dist/esm/orchestrators/HostOrchestrator/SubApp.js.map +1 -0
  29. package/dist/esm/orchestrators/HostOrchestrator/index.js +45 -0
  30. package/dist/esm/orchestrators/HostOrchestrator/index.js.map +1 -0
  31. package/dist/esm/platform/OAuth2Client.js +30 -0
  32. package/dist/esm/platform/OAuth2Client.js.map +1 -0
  33. package/dist/esm/platform/defaults.js +25 -0
  34. package/dist/esm/platform/defaults.js.map +1 -0
  35. package/dist/esm/platform/dpop/authority.js +19 -0
  36. package/dist/esm/platform/dpop/authority.js.map +1 -0
  37. package/dist/esm/platform/dpop/nonceCache.js +32 -0
  38. package/dist/esm/platform/dpop/nonceCache.js.map +1 -0
  39. package/dist/esm/platform/index.js +21 -0
  40. package/dist/esm/platform/index.js.map +1 -0
  41. package/dist/esm/utils/IndexedDBStore.js +117 -0
  42. package/dist/esm/utils/IndexedDBStore.js.map +1 -0
  43. package/dist/esm/utils/LocalBroadcastChannel.js +114 -0
  44. package/dist/esm/utils/LocalBroadcastChannel.js.map +1 -0
  45. package/dist/esm/utils/LocalStorageCache.js +78 -0
  46. package/dist/esm/utils/LocalStorageCache.js.map +1 -0
  47. package/dist/esm/utils/SynchronizedResult.js +101 -0
  48. package/dist/esm/utils/SynchronizedResult.js.map +1 -0
  49. package/dist/esm/utils/UserAgent.js +18 -0
  50. package/dist/esm/utils/UserAgent.js.map +1 -0
  51. package/dist/esm/utils/isModernBrowser.js +25 -0
  52. package/dist/esm/utils/isModernBrowser.js.map +1 -0
  53. package/dist/types/Credential/Credential.d.ts +20 -0
  54. package/dist/types/Credential/CredentialCoordinator.d.ts +28 -0
  55. package/dist/types/Credential/CredentialDataSource.d.ts +9 -0
  56. package/dist/types/Credential/TokenStorage.d.ts +56 -0
  57. package/dist/types/Credential/index.d.ts +5 -0
  58. package/dist/types/FetchClient/index.d.ts +13 -0
  59. package/dist/types/flows/AuthorizationCodeFlow.d.ts +95 -0
  60. package/dist/types/flows/SessionLogoutFlow.d.ts +9 -0
  61. package/dist/types/flows/TransactionStorage.d.ts +9 -0
  62. package/dist/types/flows/index.d.ts +6 -0
  63. package/dist/types/index.d.ts +18 -0
  64. package/dist/types/orchestrators/AuthorizationCodeFlowOrchestrator.d.ts +55 -0
  65. package/dist/types/orchestrators/HostOrchestrator/Host.d.ts +21 -0
  66. package/dist/types/orchestrators/HostOrchestrator/OrchestrationBridge.d.ts +10 -0
  67. package/dist/types/orchestrators/HostOrchestrator/SubApp.d.ts +29 -0
  68. package/dist/types/orchestrators/HostOrchestrator/index.d.ts +170 -0
  69. package/dist/types/orchestrators/index.d.ts +5 -0
  70. package/dist/types/platform/OAuth2Client.d.ts +13 -0
  71. package/dist/types/platform/defaults.d.ts +2 -0
  72. package/dist/types/platform/dpop/authority.d.ts +6 -0
  73. package/dist/types/platform/dpop/index.d.ts +5 -0
  74. package/dist/types/platform/dpop/nonceCache.d.ts +16 -0
  75. package/dist/types/platform/index.d.ts +12 -0
  76. package/dist/types/utils/IndexedDBStore.d.ts +20 -0
  77. package/dist/types/utils/LocalBroadcastChannel.d.ts +39 -0
  78. package/dist/types/utils/LocalStorageCache.d.ts +35 -0
  79. package/dist/types/utils/SynchronizedResult.d.ts +40 -0
  80. package/dist/types/utils/UserAgent.d.ts +6 -0
  81. package/dist/types/utils/isModernBrowser.d.ts +9 -0
  82. package/package.json +1 -0
@@ -0,0 +1,170 @@
1
+ /**
2
+ * @module
3
+ * @mergeModuleWith TokenOrchestrators
4
+ */
5
+ import { type TokenOrchestrator, type AcrValues, type JsonRecord, type TokenPrimitiveInit, Token } from '@okta/auth-foundation/core';
6
+ import { HostOrchestrator as HostApp } from './Host.ts';
7
+ import { SubAppOrchestrator } from './SubApp.ts';
8
+ export declare namespace HostOrchestrator {
9
+ /**
10
+ * Receives and fulfills delegated {@link Platform.Token | Token} requests from {@link HostOrchestrator.SubApp} instances
11
+ *
12
+ * @group Host
13
+ */
14
+ abstract class Host<E extends HostEvents = HostEvents> extends HostApp<E> {
15
+ }
16
+ /**
17
+ * A {@link AuthFoundation!TokenOrchestrator | TokenOrchestrator} instance which delegates all {@link Platform.Token | Token}
18
+ * requests to a {@link HostOrchestrator.Host}
19
+ *
20
+ * @group SubApp
21
+ */
22
+ class SubApp<E extends SubAppEvents = SubAppEvents> extends SubAppOrchestrator<E> {
23
+ }
24
+ /**
25
+ * A utility class to adapt any {@link AuthFoundation!TokenOrchestrator | TokenOrchestrator} instance into a {@link HostOrchestrator.Host}
26
+ * @group ProxyHost
27
+ */
28
+ class ProxyHost<E extends HostEvents = HostEvents> extends HostOrchestrator.Host<E> {
29
+ protected readonly orchestrator: Exclude<TokenOrchestrator, HostOrchestrator.SubApp>;
30
+ constructor(name: string, orchestrator: Exclude<TokenOrchestrator, HostOrchestrator.SubApp>);
31
+ findToken(params?: TokenOrchestrator.AuthorizeParams): Promise<Token | ErrorResponse>;
32
+ }
33
+ /**
34
+ * @group Host
35
+ */
36
+ type HostOptions = {
37
+ allowedOrigins?: string[];
38
+ };
39
+ /**
40
+ * @group Host
41
+ */
42
+ type HostEvents = {
43
+ 'duplicate_host': {
44
+ id: string;
45
+ duplicateId: string;
46
+ };
47
+ 'login_prompt_required': Record<string, any>;
48
+ 'request_received': {
49
+ request: RequestEvent[keyof RequestEvent];
50
+ };
51
+ 'request_fulfilled': {
52
+ request: RequestEvent[keyof RequestEvent];
53
+ response: ResponseEvent[keyof ResponseEvent];
54
+ };
55
+ };
56
+ /**
57
+ * @group SubApp
58
+ */
59
+ type SubAppOptions = TokenOrchestrator.AuthorizeParams & {
60
+ targetOrigin?: string;
61
+ };
62
+ /**
63
+ * @group SubApp
64
+ */
65
+ type SubAppEvents = {
66
+ 'no_host_found': void;
67
+ } & TokenOrchestrator.Events;
68
+ /**
69
+ * @group Types
70
+ */
71
+ type TokenRequestEventPayloads = {
72
+ 'TOKEN': TokenRequest;
73
+ 'AUTHORIZE': AuthorizeRequest;
74
+ 'PROFILE': TokenRequest;
75
+ };
76
+ /**
77
+ * @group Types
78
+ * Payload for "host_activated" events.
79
+ * Sent once a {@link HostOrchestrator.Host} instantiates. Used to detect multiple hosts
80
+ */
81
+ type ActivatedEvent = {
82
+ eventName: 'ACTIVATED';
83
+ hostId: string;
84
+ data: undefined;
85
+ };
86
+ /**
87
+ * @group Types
88
+ */
89
+ type PingEvent = {
90
+ eventName: 'PING';
91
+ data: undefined;
92
+ };
93
+ /**
94
+ * @group Types
95
+ * Lose typing of the request event object structure. Provides slightly more type-safety than
96
+ * using `any` or `unknown` like most generic messaging APIs
97
+ */
98
+ type RequestEvent = ({
99
+ [K in keyof TokenRequestEventPayloads]: {
100
+ eventName: K;
101
+ data: TokenRequestEventPayloads[K];
102
+ requestId: string;
103
+ subAppId: string;
104
+ };
105
+ } & {
106
+ ACTIVATED: ActivatedEvent;
107
+ PING: PingEvent;
108
+ });
109
+ /**
110
+ * @group Types
111
+ */
112
+ type TokenRequest = {
113
+ issuer?: string;
114
+ clientId?: string;
115
+ scopes?: string[];
116
+ acrValues?: AcrValues;
117
+ maxAge?: number;
118
+ };
119
+ /**
120
+ * @group Types
121
+ */
122
+ type AuthorizeRequest = TokenRequest & {
123
+ url?: string;
124
+ method?: string;
125
+ nonce?: string;
126
+ };
127
+ /**
128
+ * @group Types
129
+ * Map of responses from a HostOrchestrator request event
130
+ */
131
+ type ResponseEvent = {
132
+ 'TOKEN': TokenResponse;
133
+ 'AUTHORIZE': AuthorizeResponse;
134
+ 'PROFILE': ProfileResponse;
135
+ 'PING': PingResponse;
136
+ 'ACTIVATED': object;
137
+ };
138
+ /**
139
+ * @group Types
140
+ */
141
+ type ErrorResponse = {
142
+ error: string;
143
+ };
144
+ /**
145
+ * @group Types
146
+ */
147
+ type PingResponse = {
148
+ message: 'PONG';
149
+ };
150
+ /**
151
+ * @group Types
152
+ */
153
+ type TokenResponse = {
154
+ token: TokenPrimitiveInit;
155
+ } | ErrorResponse;
156
+ /**
157
+ * @group Types
158
+ */
159
+ type AuthorizeResponse = {
160
+ tokenType: string;
161
+ dpop?: string;
162
+ authorization: string;
163
+ } | ErrorResponse;
164
+ /**
165
+ * @group Types
166
+ */
167
+ type ProfileResponse = {
168
+ profile: JsonRecord;
169
+ } | ErrorResponse;
170
+ }
@@ -0,0 +1,5 @@
1
+ /**
2
+ * @module TokenOrchestrators
3
+ */
4
+ export * from './AuthorizationCodeFlowOrchestrator.ts';
5
+ export * from './HostOrchestrator/index.ts';
@@ -0,0 +1,13 @@
1
+ /**
2
+ * @module
3
+ * @mergeModuleWith Platform
4
+ */
5
+ import { Token, OAuth2Client as OAuth2ClientBase, OAuth2ErrorResponse } from '@okta/auth-foundation/core';
6
+ /**
7
+ * Browser-specific implementation of {@link OAuth2Client}
8
+ *
9
+ * @group OAuth2Client
10
+ */
11
+ export declare class OAuth2Client extends OAuth2ClientBase {
12
+ protected prepareRefreshRequest(token: Token, scopes?: string[]): Promise<Token | OAuth2ErrorResponse>;
13
+ }
@@ -0,0 +1,2 @@
1
+ import { type PlatformDependencies } from '@okta/auth-foundation/core';
2
+ export declare const PlatformDefaults: PlatformDependencies;
@@ -0,0 +1,6 @@
1
+ /**
2
+ * @packageDocumentation
3
+ * @internal
4
+ */
5
+ import { DPoPSigningAuthority } from '@okta/auth-foundation/core';
6
+ export declare const DefaultSigningAuthority: DPoPSigningAuthority;
@@ -0,0 +1,5 @@
1
+ /**
2
+ * @packageDocumentation
3
+ * @internal
4
+ */
5
+ export * from './nonceCache.ts';
@@ -0,0 +1,16 @@
1
+ /**
2
+ * @packageDocumentation
3
+ * @internal
4
+ */
5
+ import type { DPoPNonceCache } from '@okta/auth-foundation/core';
6
+ /**
7
+ * @internal
8
+ * Implementation of persistent cache; backed via `LocalStorage`
9
+ */
10
+ export declare class PersistentCache implements DPoPNonceCache {
11
+ #private;
12
+ constructor(storageKey: string, clearOnParseError?: boolean);
13
+ getNonce(key: string): Promise<string | undefined>;
14
+ cacheNonce(key: string, nonce: string): Promise<void>;
15
+ clear(): Promise<void>;
16
+ }
@@ -0,0 +1,12 @@
1
+ /**
2
+ * @module Platform
3
+ */
4
+ export * from './OAuth2Client.ts';
5
+ /**
6
+ * Clears all DPoP public / private key pairs from storage
7
+ *
8
+ * @remarks
9
+ * Recommended to be called when performing sign out
10
+ *
11
+ */
12
+ export declare function clearDPoPKeyPairs(): Promise<void>;
@@ -0,0 +1,20 @@
1
+ /**
2
+ * @packageDocumentation
3
+ * @internal
4
+ */
5
+ /**
6
+ * Lightweight wrapper around IndexedDB ObjectStore instances
7
+ *
8
+ * @internal
9
+ */
10
+ export declare class IndexedDBStore<T> {
11
+ private readonly storeName;
12
+ private readonly dbName;
13
+ constructor(storeName: string);
14
+ private keyStore;
15
+ private invokeStoreMethod;
16
+ get(id: string): Promise<T | null>;
17
+ add(id: string, item: T): Promise<void>;
18
+ remove(id: string): Promise<void>;
19
+ clear(): Promise<void>;
20
+ }
@@ -0,0 +1,39 @@
1
+ /**
2
+ * @packageDocumentation
3
+ * @internal
4
+ */
5
+ import type { JsonRecord, BroadcastChannelLike } from '@okta/auth-foundation/core';
6
+ export type LocalBroadcastChannelMessage<M = any> = {
7
+ name: string;
8
+ source: string;
9
+ message: M;
10
+ };
11
+ export type LocalBroadcastChannelMessageHandler<M extends JsonRecord = JsonRecord, R extends JsonRecord = M> = (event: {
12
+ data: M;
13
+ }, reply?: (message: R) => any) => any;
14
+ export type LocalBroadcastChannelOptions = {
15
+ targetOrigin?: string;
16
+ allowedOrigins?: string[];
17
+ };
18
+ /**
19
+ * @internal
20
+ *
21
+ * Based off of `BroadcastChannel`, but backed by `window.postMessage`
22
+ * Designed for situations when broadcasts should be limited to current window
23
+ *
24
+ * Supports cross-origin, but not cross-domain communication
25
+ */
26
+ export declare class LocalBroadcastChannel<M extends JsonRecord = JsonRecord> implements BroadcastChannelLike<M> {
27
+ #private;
28
+ readonly name: string;
29
+ constructor(name: string, targetOrigin?: string);
30
+ constructor(name: string, options: LocalBroadcastChannelOptions);
31
+ close(): void;
32
+ private isTrustedMessage;
33
+ private isValidMessage;
34
+ get boundHandler(): ((event: MessageEvent<LocalBroadcastChannelMessage<M>>) => any) | null;
35
+ set boundHandler(handler: ((event: MessageEvent<LocalBroadcastChannelMessage<M>>) => any) | null);
36
+ get onmessage(): LocalBroadcastChannelMessageHandler<M> | null;
37
+ set onmessage(handler: LocalBroadcastChannelMessageHandler<M> | null);
38
+ postMessage(message: M): void;
39
+ }
@@ -0,0 +1,35 @@
1
+ /**
2
+ * @packageDocumentation
3
+ * @internal
4
+ */
5
+ import { type Json, type JsonPrimitive, type Seconds } from '@okta/auth-foundation/core';
6
+ /**
7
+ * @internal
8
+ * A `LocalStorage`-based cache, which holds items for a duration of time
9
+ * in attempt to avoid orphaned records in `LocalStorage`
10
+ */
11
+ export declare class LocalStorageCache<T extends Json | JsonPrimitive = string> {
12
+ protected storageKey: string;
13
+ ttl: Seconds;
14
+ clearOnParseError: boolean;
15
+ constructor(storageKey: string, options?: Partial<LocalStorageCache.Options>);
16
+ static DefaultOptions: LocalStorageCache.Options;
17
+ protected getStore(): Record<string, {
18
+ item: T;
19
+ ts: number;
20
+ }>;
21
+ protected updateStore(store: any): void;
22
+ add(key: string, item: T): void;
23
+ get(key: string): T | null;
24
+ remove(key: string): void;
25
+ clear(): void;
26
+ }
27
+ /**
28
+ * @internal
29
+ */
30
+ export declare namespace LocalStorageCache {
31
+ type Options = {
32
+ ttl: Seconds;
33
+ clearOnParseError: boolean;
34
+ };
35
+ }
@@ -0,0 +1,40 @@
1
+ /**
2
+ * @packageDocumentation
3
+ * @internal
4
+ */
5
+ export type SynchronizedResultOptions<T = any, R = any> = {
6
+ timeout: number;
7
+ lockFreedDelay: number;
8
+ retries: number;
9
+ seralizer?: (obj: T) => R;
10
+ deseralizer?: (input: R) => T;
11
+ };
12
+ /**
13
+ * Synchronizes the result of an `async` action between multiple subscribers
14
+ *
15
+ * `T` is return type of `task()`
16
+ * `R` is raw type used to transfer `task()` result between tabs
17
+ *
18
+ * @remarks
19
+ * Current implementation only works in browser environments
20
+ */
21
+ export declare class SynchronizedResult<T, R = T> {
22
+ readonly name: string;
23
+ private task;
24
+ private channel;
25
+ private options;
26
+ constructor(name: string, task: () => Promise<T>, options?: Partial<SynchronizedResultOptions<T, R>>);
27
+ private onResultFromOtherTab;
28
+ private onLockFreedPlusDelay;
29
+ private onTimeout;
30
+ private whenLockIsTaken;
31
+ private whenLockIsGranted;
32
+ exec(overrides?: Partial<SynchronizedResultOptions<T, R>>): Promise<T>;
33
+ /**
34
+ * Closes the underlying BroadcastChannel, useful for testing environments to avoid open handles
35
+ *
36
+ * @see
37
+ * {@link https://jestjs.io/docs/cli#--detectopenhandles | jest --detectOpenHandles}
38
+ */
39
+ close(): void;
40
+ }
@@ -0,0 +1,6 @@
1
+ /**
2
+ * @packageDocumentation
3
+ * @internal
4
+ */
5
+ /** @internal */
6
+ export declare function isFirefox(): boolean;
@@ -0,0 +1,9 @@
1
+ /**
2
+ * @module Utils
3
+ */
4
+ /**
5
+ * Verifies the browser supports all features this library depends on
6
+ *
7
+ * @returns boolean
8
+ */
9
+ export declare function isModernBrowser(): boolean;
package/package.json ADDED
@@ -0,0 +1 @@
1
+ {"name":"@okta/spa-platform","version":"0.6.0","type":"module","main":"dist/esm/index.js","module":"dist/esm/index.js","types":"dist/types/index.d.ts","license":"Apache-2.0","files":["./LICENSE","./dist","*.md","package.json"],"exports":{".":{"types":"./dist/types/index.d.ts","import":"./dist/esm/index.js"},"./package.json":"./package.json"},"scripts":{"lint":"eslint --ext .js,.ts,.jsx .","build":"yarn build:esm && yarn build:types","build:watch":"yarn build:esm --watch & yarn build:types --watch","build:esm":"rollup -c","build:types":"tsc","test":"yarn test:unit","test:watch":"jest --watchAll","test:unit":"jest"},"dependencies":{},"peerDependencies":{"@okta/auth-foundation":"*","@okta/oauth2-flows":"*"},"peerDependenciesMeta":{"@okta/oauth2-flows":{"optional":true}},"devDependencies":{"@repo/eslint-config":"*","@repo/jest-helpers":"*","@repo/typescript-config":"*","@repo/rollup-config":"*","@okta/auth-foundation":"*","@okta/oauth2-flows":"*","eslint":"^8.56.0","jest":"^29.7.0","rollup":"^4.52.4","typescript":"^5.9.2"},"devEngines":{"runtime":{"name":"node","version":">=22.13.1","onFail":"warn"},"packageManager":{"name":"yarn","version":">=1.19.0","onFail":"warn"}},"okta":{"commitSha":"533d076fb5f59d4214751d8414be8f0f3adac2f5","fullVersion":"0.6.0-g533d076-g533d076"}}