@oxyhq/core 5.5.0 → 7.0.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.
- package/dist/cjs/.tsbuildinfo +1 -1
- package/dist/cjs/HttpService.js +7 -4
- package/dist/cjs/OxyServices.base.js +7 -102
- package/dist/cjs/boot/coldBootV2.js +350 -0
- package/dist/cjs/boot/deviceBootReturn.js +152 -0
- package/dist/cjs/crypto/keyManager.js +95 -0
- package/dist/cjs/i18n/locales/en-US.json +13 -1
- package/dist/cjs/i18n/locales/es-ES.json +13 -1
- package/dist/cjs/i18n/locales/locales/en-US.json +13 -1
- package/dist/cjs/i18n/locales/locales/es-ES.json +13 -1
- package/dist/cjs/index.js +54 -45
- package/dist/cjs/mixins/OxyServices.accounts.js +13 -26
- package/dist/cjs/mixins/OxyServices.auth.js +66 -201
- package/dist/cjs/mixins/OxyServices.deviceBoot.js +119 -0
- package/dist/cjs/mixins/index.js +8 -17
- package/dist/cjs/server/index.js +2 -2
- package/dist/cjs/session/SessionClient.js +40 -1
- package/dist/cjs/session/authStateStore.js +284 -0
- package/dist/cjs/session/refresh.js +264 -0
- package/dist/cjs/shared/utils/debugUtils.js +3 -3
- package/dist/cjs/utils/accountUtils.js +1 -55
- package/dist/cjs/utils/authWebUrl.js +10 -39
- package/dist/cjs/utils/coldBoot.js +10 -8
- package/dist/cjs/utils/platform.js +19 -0
- package/dist/cjs/utils/registrableApex.js +49 -0
- package/dist/cjs/utils/ssoBounce.js +15 -362
- package/dist/cjs/utils/validationUtils.js +57 -0
- package/dist/esm/.tsbuildinfo +1 -1
- package/dist/esm/HttpService.js +7 -4
- package/dist/esm/OxyServices.base.js +7 -102
- package/dist/esm/boot/coldBootV2.js +344 -0
- package/dist/esm/boot/deviceBootReturn.js +146 -0
- package/dist/esm/crypto/keyManager.js +95 -0
- package/dist/esm/i18n/locales/en-US.json +13 -1
- package/dist/esm/i18n/locales/es-ES.json +13 -1
- package/dist/esm/i18n/locales/locales/en-US.json +13 -1
- package/dist/esm/i18n/locales/locales/es-ES.json +13 -1
- package/dist/esm/index.js +34 -17
- package/dist/esm/mixins/OxyServices.accounts.js +13 -26
- package/dist/esm/mixins/OxyServices.auth.js +66 -201
- package/dist/esm/mixins/OxyServices.deviceBoot.js +116 -0
- package/dist/esm/mixins/index.js +8 -17
- package/dist/esm/server/index.js +1 -1
- package/dist/esm/session/SessionClient.js +40 -1
- package/dist/esm/session/authStateStore.js +278 -0
- package/dist/esm/session/refresh.js +257 -0
- package/dist/esm/shared/utils/debugUtils.js +3 -3
- package/dist/esm/utils/accountUtils.js +0 -53
- package/dist/esm/utils/authWebUrl.js +9 -37
- package/dist/esm/utils/coldBoot.js +10 -8
- package/dist/esm/utils/platform.js +18 -0
- package/dist/esm/utils/registrableApex.js +46 -0
- package/dist/esm/utils/ssoBounce.js +14 -345
- package/dist/esm/utils/validationUtils.js +56 -0
- package/dist/types/.tsbuildinfo +1 -1
- package/dist/types/HttpService.d.ts +14 -1
- package/dist/types/OxyServices.base.d.ts +0 -52
- package/dist/types/OxyServices.d.ts +0 -25
- package/dist/types/boot/coldBootV2.d.ts +76 -0
- package/dist/types/boot/deviceBootReturn.d.ts +83 -0
- package/dist/types/crypto/keyManager.d.ts +21 -0
- package/dist/types/index.d.ts +14 -21
- package/dist/types/mixins/OxyServices.accounts.d.ts +24 -29
- package/dist/types/mixins/OxyServices.analytics.d.ts +0 -2
- package/dist/types/mixins/OxyServices.appData.d.ts +0 -2
- package/dist/types/mixins/OxyServices.assets.d.ts +0 -2
- package/dist/types/mixins/OxyServices.auth.d.ts +35 -77
- package/dist/types/mixins/OxyServices.civic.d.ts +0 -2
- package/dist/types/mixins/OxyServices.connectedApps.d.ts +0 -2
- package/dist/types/mixins/OxyServices.contacts.d.ts +0 -2
- package/dist/types/mixins/OxyServices.deviceBoot.d.ts +110 -0
- package/dist/types/mixins/OxyServices.devices.d.ts +0 -2
- package/dist/types/mixins/OxyServices.features.d.ts +0 -2
- package/dist/types/mixins/OxyServices.identity.d.ts +0 -2
- package/dist/types/mixins/OxyServices.language.d.ts +0 -2
- package/dist/types/mixins/OxyServices.links.d.ts +0 -2
- package/dist/types/mixins/OxyServices.location.d.ts +0 -2
- package/dist/types/mixins/OxyServices.nodes.d.ts +0 -2
- package/dist/types/mixins/OxyServices.payment.d.ts +0 -2
- package/dist/types/mixins/OxyServices.privacy.d.ts +0 -2
- package/dist/types/mixins/OxyServices.reputation.d.ts +0 -2
- package/dist/types/mixins/OxyServices.security.d.ts +0 -2
- package/dist/types/mixins/OxyServices.topics.d.ts +0 -2
- package/dist/types/mixins/OxyServices.user.d.ts +0 -2
- package/dist/types/mixins/OxyServices.utility.d.ts +0 -2
- package/dist/types/mixins/index.d.ts +5 -9
- package/dist/types/models/interfaces.d.ts +0 -67
- package/dist/types/models/session.d.ts +4 -5
- package/dist/types/server/index.d.ts +1 -1
- package/dist/types/session/SessionClient.d.ts +26 -1
- package/dist/types/session/authStateStore.d.ts +119 -0
- package/dist/types/session/refresh.d.ts +93 -0
- package/dist/types/shared/utils/debugUtils.d.ts +3 -3
- package/dist/types/utils/accountUtils.d.ts +2 -17
- package/dist/types/utils/authWebUrl.d.ts +9 -35
- package/dist/types/utils/coldBoot.d.ts +17 -14
- package/dist/types/utils/platform.d.ts +14 -0
- package/dist/types/utils/registrableApex.d.ts +31 -0
- package/dist/types/utils/ssoBounce.d.ts +14 -280
- package/dist/types/utils/validationUtils.d.ts +15 -0
- package/package.json +2 -2
- package/src/HttpService.ts +20 -4
- package/src/OxyServices.base.ts +7 -112
- package/src/OxyServices.ts +0 -38
- package/src/boot/__tests__/coldBootV2.test.ts +317 -0
- package/src/boot/__tests__/deviceBootReturn.test.ts +158 -0
- package/src/boot/coldBootV2.ts +426 -0
- package/src/boot/deviceBootReturn.ts +195 -0
- package/src/crypto/__tests__/sharedDeviceToken.test.ts +24 -0
- package/src/crypto/keyManager.ts +101 -0
- package/src/i18n/locales/en-US.json +13 -1
- package/src/i18n/locales/es-ES.json +13 -1
- package/src/index.ts +75 -65
- package/src/mixins/OxyServices.accounts.ts +27 -39
- package/src/mixins/OxyServices.auth.ts +78 -253
- package/src/mixins/OxyServices.deviceBoot.ts +146 -0
- package/src/mixins/__tests__/OxyServices.deviceBoot.test.ts +107 -0
- package/src/mixins/__tests__/accounts.test.ts +17 -44
- package/src/mixins/__tests__/passwordSignIn.test.ts +91 -0
- package/src/mixins/index.ts +10 -23
- package/src/models/interfaces.ts +0 -79
- package/src/models/session.ts +4 -5
- package/src/server/index.ts +1 -1
- package/src/session/SessionClient.ts +53 -2
- package/src/session/__tests__/SessionClient.additive.test.ts +92 -0
- package/src/session/__tests__/SessionClient.rest.test.ts +25 -0
- package/src/session/__tests__/SessionClient.state.test.ts +18 -5
- package/src/session/__tests__/authStateStore.test.ts +209 -0
- package/src/session/__tests__/refresh.test.ts +256 -0
- package/src/session/authStateStore.ts +335 -0
- package/src/session/refresh.ts +334 -0
- package/src/shared/utils/debugUtils.ts +3 -3
- package/src/utils/__tests__/authWebUrl.test.ts +5 -40
- package/src/utils/__tests__/registrableApex.test.ts +62 -0
- package/src/utils/__tests__/validationUtils.test.ts +30 -0
- package/src/utils/accountUtils.ts +2 -65
- package/src/utils/authWebUrl.ts +9 -39
- package/src/utils/coldBoot.ts +17 -14
- package/src/utils/platform.ts +21 -0
- package/src/utils/registrableApex.ts +45 -0
- package/src/utils/ssoBounce.ts +14 -393
- package/src/utils/validationUtils.ts +62 -0
- package/dist/cjs/AuthManager.js +0 -1110
- package/dist/cjs/AuthManagerTypes.js +0 -13
- package/dist/cjs/CrossDomainAuth.js +0 -206
- package/dist/cjs/mixins/OxyServices.fedcm.js +0 -823
- package/dist/cjs/mixins/OxyServices.redirect.js +0 -95
- package/dist/cjs/mixins/OxyServices.silent.js +0 -204
- package/dist/cjs/mixins/OxyServices.sso.js +0 -208
- package/dist/cjs/utils/fapiAutoDetect.js +0 -99
- package/dist/cjs/utils/ssoEstablish.js +0 -110
- package/dist/cjs/utils/ssoReturn.js +0 -275
- package/dist/esm/AuthManager.js +0 -1105
- package/dist/esm/AuthManagerTypes.js +0 -12
- package/dist/esm/CrossDomainAuth.js +0 -201
- package/dist/esm/mixins/OxyServices.fedcm.js +0 -821
- package/dist/esm/mixins/OxyServices.redirect.js +0 -92
- package/dist/esm/mixins/OxyServices.silent.js +0 -202
- package/dist/esm/mixins/OxyServices.sso.js +0 -204
- package/dist/esm/utils/fapiAutoDetect.js +0 -95
- package/dist/esm/utils/ssoEstablish.js +0 -107
- package/dist/esm/utils/ssoReturn.js +0 -271
- package/dist/types/AuthManager.d.ts +0 -380
- package/dist/types/AuthManagerTypes.d.ts +0 -81
- package/dist/types/CrossDomainAuth.d.ts +0 -164
- package/dist/types/mixins/OxyServices.fedcm.d.ts +0 -331
- package/dist/types/mixins/OxyServices.redirect.d.ts +0 -92
- package/dist/types/mixins/OxyServices.silent.d.ts +0 -132
- package/dist/types/mixins/OxyServices.sso.d.ts +0 -138
- package/dist/types/utils/fapiAutoDetect.d.ts +0 -56
- package/dist/types/utils/ssoEstablish.d.ts +0 -85
- package/dist/types/utils/ssoReturn.d.ts +0 -156
- package/src/AuthManager.ts +0 -1269
- package/src/AuthManagerTypes.ts +0 -86
- package/src/CrossDomainAuth.ts +0 -243
- package/src/__tests__/authManager.cookiePath.test.ts +0 -390
- package/src/__tests__/authManager.security.test.ts +0 -377
- package/src/__tests__/crossDomainAuth.test.ts +0 -116
- package/src/__tests__/establishDeviceRefreshSlot.test.ts +0 -221
- package/src/mixins/OxyServices.fedcm.ts +0 -1026
- package/src/mixins/OxyServices.redirect.ts +0 -122
- package/src/mixins/OxyServices.silent.ts +0 -272
- package/src/mixins/OxyServices.sso.ts +0 -261
- package/src/mixins/__tests__/constructorAuthWebUrl.test.ts +0 -85
- package/src/mixins/__tests__/fedcm.test.ts +0 -667
- package/src/mixins/__tests__/sessionBaseUrl.test.ts +0 -61
- package/src/mixins/__tests__/silent.test.ts +0 -102
- package/src/mixins/__tests__/sso.test.ts +0 -228
- package/src/utils/__tests__/consumeSsoReturn.test.ts +0 -816
- package/src/utils/__tests__/fapiAutoDetect.test.ts +0 -183
- package/src/utils/__tests__/ssoBounce.test.ts +0 -219
- package/src/utils/__tests__/ssoEstablish.test.ts +0 -204
- package/src/utils/__tests__/ssoReturn.test.ts +0 -276
- package/src/utils/fapiAutoDetect.ts +0 -91
- package/src/utils/ssoEstablish.ts +0 -174
- package/src/utils/ssoReturn.ts +0 -389
|
@@ -1,331 +0,0 @@
|
|
|
1
|
-
import type { OxyServicesBase } from '../OxyServices.base';
|
|
2
|
-
import type { SessionLoginResponse } from '../models/session';
|
|
3
|
-
export interface FedCMAuthOptions {
|
|
4
|
-
nonce?: string;
|
|
5
|
-
context?: 'signin' | 'signup' | 'continue' | 'use';
|
|
6
|
-
loginHint?: string;
|
|
7
|
-
}
|
|
8
|
-
export interface FedCMConfig {
|
|
9
|
-
enabled: boolean;
|
|
10
|
-
configURL: string;
|
|
11
|
-
clientId?: string;
|
|
12
|
-
}
|
|
13
|
-
/**
|
|
14
|
-
* FedCM request mode values.
|
|
15
|
-
*
|
|
16
|
-
* The W3C FedCM spec renamed the `IdentityCredentialRequestOptions.mode` enum:
|
|
17
|
-
* `'widget'` → `'passive'` and `'button'` → `'active'`. Modern Chrome only
|
|
18
|
-
* accepts `'active'`/`'passive'` and throws a synchronous `TypeError` for the
|
|
19
|
-
* legacy values, while Chrome 125–131 only understands `'button'`/`'widget'`.
|
|
20
|
-
* Callers should use the modern values; the legacy values are accepted for
|
|
21
|
-
* convenience and normalised internally.
|
|
22
|
-
*/
|
|
23
|
-
export type FedCMRequestMode = 'active' | 'passive' | 'button' | 'widget';
|
|
24
|
-
/**
|
|
25
|
-
* Normalised result of a FedCM credential request: the IdP-issued ID token plus
|
|
26
|
-
* whether the browser auto-selected the account (no explicit user choice).
|
|
27
|
-
*/
|
|
28
|
-
interface FedCMTokenResult {
|
|
29
|
-
token: string;
|
|
30
|
-
isAutoSelected: boolean;
|
|
31
|
-
}
|
|
32
|
-
/**
|
|
33
|
-
* Federated Credential Management (FedCM) Authentication Mixin
|
|
34
|
-
*
|
|
35
|
-
* Implements the modern browser-native identity federation API that enables
|
|
36
|
-
* Google-style cross-domain authentication without third-party cookies.
|
|
37
|
-
*
|
|
38
|
-
* Browser Support:
|
|
39
|
-
* - Chrome 108+
|
|
40
|
-
* - Safari 16.4+
|
|
41
|
-
* - Edge 108+
|
|
42
|
-
* - Firefox: Not yet supported (fallback required)
|
|
43
|
-
*
|
|
44
|
-
* Key Features:
|
|
45
|
-
* - No redirects or secondary windows required
|
|
46
|
-
* - Browser-native UI prompts
|
|
47
|
-
* - Privacy-preserving (IdP can't track users)
|
|
48
|
-
* - Automatic SSO across domains
|
|
49
|
-
* - Silent re-authentication support
|
|
50
|
-
*
|
|
51
|
-
* @see https://developer.mozilla.org/en-US/docs/Web/API/FedCM_API
|
|
52
|
-
*/
|
|
53
|
-
export declare function OxyServicesFedCMMixin<T extends typeof OxyServicesBase>(Base: T): {
|
|
54
|
-
new (...args: any[]): {
|
|
55
|
-
resolveFedcmConfigUrl(): string;
|
|
56
|
-
/**
|
|
57
|
-
* Instance method to check FedCM support
|
|
58
|
-
*/
|
|
59
|
-
isFedCMSupported(): boolean;
|
|
60
|
-
/**
|
|
61
|
-
* Sign in using FedCM (Federated Credential Management API)
|
|
62
|
-
*
|
|
63
|
-
* This provides a Google-style authentication experience:
|
|
64
|
-
* - Browser shows native "Sign in with Oxy" prompt
|
|
65
|
-
* - No redirect or secondary window required
|
|
66
|
-
* - User approves → credential exchange happens in browser
|
|
67
|
-
* - All apps automatically get SSO after first sign-in
|
|
68
|
-
*
|
|
69
|
-
* @param options - Authentication options
|
|
70
|
-
* @returns Session with access token and user data
|
|
71
|
-
* @throws {OxyAuthenticationError} If FedCM not supported or user cancels
|
|
72
|
-
*
|
|
73
|
-
* @example
|
|
74
|
-
* ```typescript
|
|
75
|
-
* try {
|
|
76
|
-
* const session = await oxyServices.signInWithFedCM();
|
|
77
|
-
* const user = session.user;
|
|
78
|
-
* } catch (error) {
|
|
79
|
-
* // Fallback to redirect auth
|
|
80
|
-
* oxyServices.signInWithRedirect();
|
|
81
|
-
* }
|
|
82
|
-
* ```
|
|
83
|
-
*/
|
|
84
|
-
signInWithFedCM(options?: FedCMAuthOptions): Promise<SessionLoginResponse>;
|
|
85
|
-
/**
|
|
86
|
-
* Run a single interactive FedCM credential request + token exchange for the
|
|
87
|
-
* given (possibly undefined) loginHint. A successful exchange plants the
|
|
88
|
-
* access token and persists the user id as the future loginHint — the hint is
|
|
89
|
-
* therefore only ever stored after a GENUINELY successful sign-in, never
|
|
90
|
-
* speculatively.
|
|
91
|
-
*
|
|
92
|
-
* @private
|
|
93
|
-
*/
|
|
94
|
-
attemptInteractiveSignIn(options: FedCMAuthOptions, loginHint: string | undefined): Promise<SessionLoginResponse>;
|
|
95
|
-
/**
|
|
96
|
-
* Map a raw FedCM/exchange failure to a user-facing {@link OxyAuthenticationError}
|
|
97
|
-
* (or pass it through). Extracted so the clear-and-retry path can reuse the
|
|
98
|
-
* exact same error normalisation as the first attempt.
|
|
99
|
-
*
|
|
100
|
-
* @private
|
|
101
|
-
*/
|
|
102
|
-
normalizeInteractiveSignInError(error: unknown): unknown;
|
|
103
|
-
/**
|
|
104
|
-
* Silent sign-in using FedCM
|
|
105
|
-
*
|
|
106
|
-
* Attempts to automatically re-authenticate the user without any UI.
|
|
107
|
-
* This is what enables "instant sign-in" across all Oxy domains after
|
|
108
|
-
* the user has signed in once.
|
|
109
|
-
*
|
|
110
|
-
* The browser will:
|
|
111
|
-
* 1. Check if user has previously signed in to Oxy
|
|
112
|
-
* 2. Check if user is still signed in at auth.oxy.so
|
|
113
|
-
* 3. If yes, automatically provide credential without prompting
|
|
114
|
-
*
|
|
115
|
-
* @returns Session if user is already signed in, null otherwise
|
|
116
|
-
*
|
|
117
|
-
* @example
|
|
118
|
-
* ```typescript
|
|
119
|
-
* // On app startup
|
|
120
|
-
* useEffect(() => {
|
|
121
|
-
* const checkAuth = async () => {
|
|
122
|
-
* const session = await oxyServices.silentSignInWithFedCM();
|
|
123
|
-
* if (session) {
|
|
124
|
-
* setUser(session.user);
|
|
125
|
-
* } else {
|
|
126
|
-
* // Show sign-in button
|
|
127
|
-
* }
|
|
128
|
-
* };
|
|
129
|
-
* checkAuth();
|
|
130
|
-
* }, []);
|
|
131
|
-
* ```
|
|
132
|
-
*/
|
|
133
|
-
silentSignInWithFedCM(): Promise<SessionLoginResponse | null>;
|
|
134
|
-
/**
|
|
135
|
-
* Request identity credential from browser using FedCM API
|
|
136
|
-
*
|
|
137
|
-
* Uses a global lock to prevent concurrent requests, as FedCM only
|
|
138
|
-
* allows one navigator.credentials.get request at a time.
|
|
139
|
-
*
|
|
140
|
-
* Interactive requests (optional/required) wait for any silent request to finish first.
|
|
141
|
-
*
|
|
142
|
-
* @private
|
|
143
|
-
*/
|
|
144
|
-
requestIdentityCredential(options: {
|
|
145
|
-
configURL: string;
|
|
146
|
-
clientId: string;
|
|
147
|
-
nonce: string;
|
|
148
|
-
context?: string;
|
|
149
|
-
loginHint?: string;
|
|
150
|
-
mediation?: "silent" | "optional" | "required";
|
|
151
|
-
/**
|
|
152
|
-
* FedCM request mode. The W3C spec values are `'active'` (user-gesture
|
|
153
|
-
* button flow) and `'passive'` (browser-initiated widget flow). Chrome
|
|
154
|
-
* 125–131 used the legacy names `'button'`/`'widget'`; those are accepted
|
|
155
|
-
* here and mapped to the modern values, with an automatic legacy retry if
|
|
156
|
-
* the running browser only understands the old enum.
|
|
157
|
-
*/
|
|
158
|
-
mode?: FedCMRequestMode;
|
|
159
|
-
}): Promise<FedCMTokenResult | null>;
|
|
160
|
-
/**
|
|
161
|
-
* Exchange FedCM ID token for Oxy session
|
|
162
|
-
*
|
|
163
|
-
* The ID token is a JWT issued by auth.oxy.so that proves the user's
|
|
164
|
-
* identity. We exchange it for a full Oxy session with access token.
|
|
165
|
-
*
|
|
166
|
-
* @private
|
|
167
|
-
*/
|
|
168
|
-
exchangeIdTokenForSession(idToken: string): Promise<SessionLoginResponse>;
|
|
169
|
-
/**
|
|
170
|
-
* Revoke FedCM credential (sign out)
|
|
171
|
-
*
|
|
172
|
-
* Uses IdentityCredential.disconnect() to tell the browser to forget
|
|
173
|
-
* the RP-IdP-account association. This resets the "returning account"
|
|
174
|
-
* state, which is required for silent mediation to work again.
|
|
175
|
-
*/
|
|
176
|
-
revokeFedCMCredential(): Promise<void>;
|
|
177
|
-
/**
|
|
178
|
-
* Get configuration for FedCM
|
|
179
|
-
*
|
|
180
|
-
* @returns FedCM configuration with browser support info
|
|
181
|
-
*/
|
|
182
|
-
getFedCMConfig(): FedCMConfig;
|
|
183
|
-
/**
|
|
184
|
-
* Generate a cryptographically secure local nonce for FedCM.
|
|
185
|
-
*
|
|
186
|
-
* NOTE: this is a *local* fallback only. The server-side `/fedcm/exchange`
|
|
187
|
-
* endpoint requires the nonce embedded in the ID token to have been minted
|
|
188
|
-
* by `POST /fedcm/nonce` (see {@link mintServerNonce}) and bound to this
|
|
189
|
-
* origin. A purely local nonce will be rejected with `invalid_nonce`. Use
|
|
190
|
-
* {@link getFedcmNonce}, which prefers a server-minted nonce and only falls
|
|
191
|
-
* back to this generator when the mint endpoint is unreachable.
|
|
192
|
-
*
|
|
193
|
-
* @private
|
|
194
|
-
*/
|
|
195
|
-
generateNonce(): string;
|
|
196
|
-
/**
|
|
197
|
-
* Mint a single-use, origin-bound nonce from the Oxy API.
|
|
198
|
-
*
|
|
199
|
-
* The FedCM ID token issued by the IdP embeds this nonce as the `nonce`
|
|
200
|
-
* claim. When the consuming app calls `POST /fedcm/exchange`, the API burns
|
|
201
|
-
* the nonce (atomic `usedAt` transition) and verifies it was minted for the
|
|
202
|
-
* same origin as the token `aud`. This is the anti-replay binding required
|
|
203
|
-
* by the API's H9 hardening — without a server-minted nonce the exchange
|
|
204
|
-
* always fails.
|
|
205
|
-
*
|
|
206
|
-
* The browser attaches the `Origin` header automatically on this
|
|
207
|
-
* cross-origin request, so the API binds the nonce to the calling app's
|
|
208
|
-
* origin (which also becomes the FedCM `clientId`/token `aud`).
|
|
209
|
-
*
|
|
210
|
-
* @private
|
|
211
|
-
*/
|
|
212
|
-
mintServerNonce(): Promise<string>;
|
|
213
|
-
/**
|
|
214
|
-
* Resolve the nonce to use for a FedCM credential request.
|
|
215
|
-
*
|
|
216
|
-
* Prefers a server-minted, origin-bound nonce (required for the token
|
|
217
|
-
* exchange to succeed). If the mint endpoint is unreachable we fall back to
|
|
218
|
-
* a locally generated nonce so the browser flow can still proceed; the
|
|
219
|
-
* exchange may then fail server-side, but that is strictly better than
|
|
220
|
-
* throwing before the browser ever shows its UI.
|
|
221
|
-
*
|
|
222
|
-
* @private
|
|
223
|
-
*/
|
|
224
|
-
getFedcmNonce(): Promise<string>;
|
|
225
|
-
/**
|
|
226
|
-
* Get the client ID for this origin
|
|
227
|
-
*
|
|
228
|
-
* @private
|
|
229
|
-
*/
|
|
230
|
-
getClientId(): string;
|
|
231
|
-
/** @internal */
|
|
232
|
-
getStoredLoginHint(): string | undefined;
|
|
233
|
-
/** @internal */
|
|
234
|
-
storeLoginHint(userId: string): void;
|
|
235
|
-
/** @internal */
|
|
236
|
-
clearLoginHint(): void;
|
|
237
|
-
/**
|
|
238
|
-
* List the authenticated user's authorized RP apps.
|
|
239
|
-
*
|
|
240
|
-
* Returns the intersection of the user's FedCM grants and the currently-
|
|
241
|
-
* approved RP catalog — what powers the "Connected apps" management UI in
|
|
242
|
-
* @oxyhq/services. Requires a real user session; service tokens are
|
|
243
|
-
* rejected by the underlying endpoint.
|
|
244
|
-
*/
|
|
245
|
-
listAuthorizedApps(): Promise<AuthorizedApp[]>;
|
|
246
|
-
/**
|
|
247
|
-
* Revoke the authenticated user's authorization for a specific RP origin.
|
|
248
|
-
*
|
|
249
|
-
* The next FedCM sign-in from that origin will require explicit re-consent.
|
|
250
|
-
* The corresponding cache entry is invalidated so a subsequent
|
|
251
|
-
* `listAuthorizedApps()` call sees fresh data.
|
|
252
|
-
*/
|
|
253
|
-
revokeAuthorizedApp(origin: string): Promise<void>;
|
|
254
|
-
httpService: import("../HttpService").HttpService;
|
|
255
|
-
cloudURL: string;
|
|
256
|
-
config: import("../OxyServices.base").OxyConfig;
|
|
257
|
-
__resetTokensForTests(): void;
|
|
258
|
-
makeRequest<T_1>(method: "GET" | "POST" | "PUT" | "PATCH" | "DELETE", url: string, data?: any, options?: import("../HttpService").RequestOptions): Promise<T_1>;
|
|
259
|
-
getBaseURL(): string;
|
|
260
|
-
getSessionBaseUrl(): string;
|
|
261
|
-
getClient(): import("../HttpService").HttpService;
|
|
262
|
-
createLinkedClient(config: import("../OxyServices.base").OxyConfig): import("..").LinkedHttpClient;
|
|
263
|
-
getMetrics(): {
|
|
264
|
-
totalRequests: number;
|
|
265
|
-
successfulRequests: number;
|
|
266
|
-
failedRequests: number;
|
|
267
|
-
cacheHits: number;
|
|
268
|
-
cacheMisses: number;
|
|
269
|
-
averageResponseTime: number;
|
|
270
|
-
};
|
|
271
|
-
clearCache(): void;
|
|
272
|
-
clearCacheEntry(key: string): void;
|
|
273
|
-
clearCacheByPrefix(prefix: string): number;
|
|
274
|
-
getCacheStats(): {
|
|
275
|
-
size: number;
|
|
276
|
-
hits: number;
|
|
277
|
-
misses: number;
|
|
278
|
-
hitRate: number;
|
|
279
|
-
};
|
|
280
|
-
getCloudURL(): string;
|
|
281
|
-
setTokens(accessToken: string): void;
|
|
282
|
-
clearTokens(): void;
|
|
283
|
-
onTokensChanged(listener: (accessToken: string | null) => void): () => void;
|
|
284
|
-
_cachedUserId: string | null | undefined;
|
|
285
|
-
_cachedAccessToken: string | null;
|
|
286
|
-
getCurrentUserId(): string | null;
|
|
287
|
-
hasValidToken(): boolean;
|
|
288
|
-
getAccessToken(): string | null;
|
|
289
|
-
establishDeviceRefreshSlot(): Promise<number | null>;
|
|
290
|
-
getAccessTokenExpiry(): number | null;
|
|
291
|
-
waitForAuth(timeoutMs?: number): Promise<boolean>;
|
|
292
|
-
withAuthRetry<T_1>(operation: () => Promise<T_1>, operationName: string, options?: {
|
|
293
|
-
maxRetries?: number;
|
|
294
|
-
retryDelay?: number;
|
|
295
|
-
authTimeoutMs?: number;
|
|
296
|
-
}): Promise<T_1>;
|
|
297
|
-
validate(): Promise<boolean>;
|
|
298
|
-
handleError(error: unknown): Error;
|
|
299
|
-
healthCheck(): Promise<{
|
|
300
|
-
status: string;
|
|
301
|
-
users?: number;
|
|
302
|
-
timestamp?: string;
|
|
303
|
-
[key: string]: any;
|
|
304
|
-
}>;
|
|
305
|
-
};
|
|
306
|
-
readonly DEFAULT_CONFIG_URL: "https://auth.oxy.so/fedcm.json";
|
|
307
|
-
readonly FEDCM_TIMEOUT: 15000;
|
|
308
|
-
readonly FEDCM_SILENT_TIMEOUT: 4000;
|
|
309
|
-
readonly FEDCM_ABORT_SETTLE_GRACE_MS: 500;
|
|
310
|
-
/**
|
|
311
|
-
* Check if FedCM is supported in the current browser
|
|
312
|
-
*/
|
|
313
|
-
isFedCMSupported(): boolean;
|
|
314
|
-
} & T;
|
|
315
|
-
/**
|
|
316
|
-
* Public summary of an RP application the user has authorized — mirrors the
|
|
317
|
-
* `AuthorizedAppSummary` shape returned by `GET /fedcm/me/authorized-apps`.
|
|
318
|
-
*/
|
|
319
|
-
export interface AuthorizedApp {
|
|
320
|
-
/** Normalised RP origin. */
|
|
321
|
-
origin: string;
|
|
322
|
-
/** Friendly display name. */
|
|
323
|
-
name: string;
|
|
324
|
-
/** Optional human-readable description. */
|
|
325
|
-
description?: string;
|
|
326
|
-
/** ISO-8601 timestamp of when the user first authorized this RP. */
|
|
327
|
-
firstGrantedAt: string;
|
|
328
|
-
/** ISO-8601 timestamp of the most recent FedCM exchange for this user+RP. */
|
|
329
|
-
lastUsedAt: string;
|
|
330
|
-
}
|
|
331
|
-
export { OxyServicesFedCMMixin as FedCMMixin };
|
|
@@ -1,92 +0,0 @@
|
|
|
1
|
-
import type { OxyServicesBase } from '../OxyServices.base';
|
|
2
|
-
import type { SessionLoginResponse } from '../models/session';
|
|
3
|
-
export interface RedirectAuthOptions {
|
|
4
|
-
redirectUri?: string;
|
|
5
|
-
mode?: 'login' | 'signup';
|
|
6
|
-
preserveUrl?: boolean;
|
|
7
|
-
}
|
|
8
|
-
/**
|
|
9
|
-
* Redirect-based authentication without bearer tokens in URLs.
|
|
10
|
-
*
|
|
11
|
-
* The redirect fallback now uses the same central SSO code-return contract as
|
|
12
|
-
* cold boot: the RP stores CSRF/destination state in sessionStorage, navigates
|
|
13
|
-
* to the central IdP, receives only an opaque one-time code in the URL fragment,
|
|
14
|
-
* and the provider's `sso-return` step exchanges that code for the real session.
|
|
15
|
-
*/
|
|
16
|
-
export declare function OxyServicesRedirectAuthMixin<T extends typeof OxyServicesBase>(Base: T): {
|
|
17
|
-
new (...args: any[]): {
|
|
18
|
-
/**
|
|
19
|
-
* Start a full-page redirect through the central SSO flow.
|
|
20
|
-
*
|
|
21
|
-
* No access token, refresh token, or session id is ever put in the URL or
|
|
22
|
-
* localStorage. The caller's provider must run `consumeSsoReturn` on startup
|
|
23
|
-
* to complete the code exchange and commit the session.
|
|
24
|
-
*/
|
|
25
|
-
signInWithRedirect(options?: RedirectAuthOptions): void;
|
|
26
|
-
signUpWithRedirect(options?: RedirectAuthOptions): void;
|
|
27
|
-
/**
|
|
28
|
-
* Legacy token-query callbacks are intentionally rejected. Modern providers
|
|
29
|
-
* complete redirect auth through `consumeSsoReturn`, which accepts only
|
|
30
|
-
* `#oxy_sso=ok&code=...`.
|
|
31
|
-
*/
|
|
32
|
-
handleAuthCallback(): SessionLoginResponse | null;
|
|
33
|
-
restoreSession(): boolean;
|
|
34
|
-
clearStoredSession(): void;
|
|
35
|
-
getStoredSessionId(): string | null;
|
|
36
|
-
generateState(): string;
|
|
37
|
-
generateNonce(): string;
|
|
38
|
-
cleanAuthCallbackUrl(url: URL): void;
|
|
39
|
-
httpService: import("../HttpService").HttpService;
|
|
40
|
-
cloudURL: string;
|
|
41
|
-
config: import("../OxyServices.base").OxyConfig;
|
|
42
|
-
__resetTokensForTests(): void;
|
|
43
|
-
makeRequest<T_1>(method: "GET" | "POST" | "PUT" | "PATCH" | "DELETE", url: string, data?: any, options?: import("../HttpService").RequestOptions): Promise<T_1>;
|
|
44
|
-
getBaseURL(): string;
|
|
45
|
-
getSessionBaseUrl(): string;
|
|
46
|
-
getClient(): import("../HttpService").HttpService;
|
|
47
|
-
createLinkedClient(config: import("../OxyServices.base").OxyConfig): import("..").LinkedHttpClient;
|
|
48
|
-
getMetrics(): {
|
|
49
|
-
totalRequests: number;
|
|
50
|
-
successfulRequests: number;
|
|
51
|
-
failedRequests: number;
|
|
52
|
-
cacheHits: number;
|
|
53
|
-
cacheMisses: number;
|
|
54
|
-
averageResponseTime: number;
|
|
55
|
-
};
|
|
56
|
-
clearCache(): void;
|
|
57
|
-
clearCacheEntry(key: string): void;
|
|
58
|
-
clearCacheByPrefix(prefix: string): number;
|
|
59
|
-
getCacheStats(): {
|
|
60
|
-
size: number;
|
|
61
|
-
hits: number;
|
|
62
|
-
misses: number;
|
|
63
|
-
hitRate: number;
|
|
64
|
-
};
|
|
65
|
-
getCloudURL(): string;
|
|
66
|
-
setTokens(accessToken: string): void;
|
|
67
|
-
clearTokens(): void;
|
|
68
|
-
onTokensChanged(listener: (accessToken: string | null) => void): () => void;
|
|
69
|
-
_cachedUserId: string | null | undefined;
|
|
70
|
-
_cachedAccessToken: string | null;
|
|
71
|
-
getCurrentUserId(): string | null;
|
|
72
|
-
hasValidToken(): boolean;
|
|
73
|
-
getAccessToken(): string | null;
|
|
74
|
-
establishDeviceRefreshSlot(): Promise<number | null>;
|
|
75
|
-
getAccessTokenExpiry(): number | null;
|
|
76
|
-
waitForAuth(timeoutMs?: number): Promise<boolean>;
|
|
77
|
-
withAuthRetry<T_1>(operation: () => Promise<T_1>, operationName: string, options?: {
|
|
78
|
-
maxRetries?: number;
|
|
79
|
-
retryDelay?: number;
|
|
80
|
-
authTimeoutMs?: number;
|
|
81
|
-
}): Promise<T_1>;
|
|
82
|
-
validate(): Promise<boolean>;
|
|
83
|
-
handleError(error: unknown): Error;
|
|
84
|
-
healthCheck(): Promise<{
|
|
85
|
-
status: string;
|
|
86
|
-
users?: number;
|
|
87
|
-
timestamp?: string;
|
|
88
|
-
[key: string]: any;
|
|
89
|
-
}>;
|
|
90
|
-
};
|
|
91
|
-
} & T;
|
|
92
|
-
export { OxyServicesRedirectAuthMixin as RedirectAuthMixin };
|
|
@@ -1,132 +0,0 @@
|
|
|
1
|
-
import type { OxyServicesBase } from "../OxyServices.base";
|
|
2
|
-
import type { SessionLoginResponse } from "../models/session";
|
|
3
|
-
export interface SilentAuthOptions {
|
|
4
|
-
timeout?: number;
|
|
5
|
-
/**
|
|
6
|
-
* Override the auth-web (IdP) origin used for the silent iframe, instead of
|
|
7
|
-
* the instance's configured `resolveAuthUrl()`.
|
|
8
|
-
*
|
|
9
|
-
* Why this exists: an instance configured with the CENTRAL IdP
|
|
10
|
-
* (`authWebUrl=https://auth.oxy.so`, for the opaque-code `/sso` bounce and
|
|
11
|
-
* FedCM) cannot read the DURABLE per-apex `fedcm_session` cookie via the
|
|
12
|
-
* central host — that cookie is first-party only on `auth.<rp-apex>` (e.g.
|
|
13
|
-
* `auth.mention.earth`). The cross-domain reload-restore path must point the
|
|
14
|
-
* `/auth/silent` iframe at the PER-APEX host so the cookie is same-site to
|
|
15
|
-
* the RP page (first-party under Safari ITP / Firefox TCP) and the restore
|
|
16
|
-
* is NOT a top-level navigation (no flash, works in a backgrounded tab).
|
|
17
|
-
*
|
|
18
|
-
* When provided this value is used BOTH for the iframe `src` AND for the
|
|
19
|
-
* `postMessage` origin validation in {@link waitForIframeAuth}, so the
|
|
20
|
-
* security check still matches the exact origin the iframe was loaded from.
|
|
21
|
-
* Must be an absolute origin (`https://auth.<apex>`); ignored if empty.
|
|
22
|
-
*/
|
|
23
|
-
authWebUrlOverride?: string;
|
|
24
|
-
}
|
|
25
|
-
/**
|
|
26
|
-
* Cross-domain silent browser auth helpers.
|
|
27
|
-
*
|
|
28
|
-
* The clean session model supports FedCM, tokenless redirect SSO, and silent
|
|
29
|
-
* iframe SSO. Bearer-token callback URLs are not part of this surface.
|
|
30
|
-
*/
|
|
31
|
-
export declare function OxyServicesSilentAuthMixin<T extends typeof OxyServicesBase>(Base: T): {
|
|
32
|
-
new (...args: any[]): {
|
|
33
|
-
/** Resolve auth URL from config or static default (method, not getter — getters break in TS mixins) */
|
|
34
|
-
resolveAuthUrl(): string;
|
|
35
|
-
/**
|
|
36
|
-
* Silent sign-in using hidden iframe
|
|
37
|
-
*
|
|
38
|
-
* Attempts to automatically re-authenticate the user without any UI.
|
|
39
|
-
* This is what enables seamless SSO across all Oxy domains.
|
|
40
|
-
*
|
|
41
|
-
* How it works:
|
|
42
|
-
* 1. Creates hidden iframe pointing to auth.oxy.so/silent-auth
|
|
43
|
-
* 2. If user has valid session at auth.oxy.so, it exchanges an opaque SSO code
|
|
44
|
-
* 3. If not, iframe responds with null (no error thrown)
|
|
45
|
-
*
|
|
46
|
-
* This should be called on app startup to check for existing sessions.
|
|
47
|
-
*
|
|
48
|
-
* @param options - Silent auth options
|
|
49
|
-
* @returns Session if user is signed in, null otherwise
|
|
50
|
-
*
|
|
51
|
-
* @example
|
|
52
|
-
* ```typescript
|
|
53
|
-
* useEffect(() => {
|
|
54
|
-
* const checkAuth = async () => {
|
|
55
|
-
* const session = await oxyServices.silentSignIn();
|
|
56
|
-
* if (session) {
|
|
57
|
-
* setUser(session.user);
|
|
58
|
-
* }
|
|
59
|
-
* };
|
|
60
|
-
* checkAuth();
|
|
61
|
-
* }, []);
|
|
62
|
-
* ```
|
|
63
|
-
*/
|
|
64
|
-
silentSignIn(options?: SilentAuthOptions): Promise<SessionLoginResponse | null>;
|
|
65
|
-
/**
|
|
66
|
-
* Wait for authentication response from iframe
|
|
67
|
-
*
|
|
68
|
-
* @private
|
|
69
|
-
*/
|
|
70
|
-
waitForIframeAuth(iframe: HTMLIFrameElement, timeout: number, expectedOrigin: string): Promise<SessionLoginResponse | null>;
|
|
71
|
-
/**
|
|
72
|
-
* Generate nonce for replay attack prevention
|
|
73
|
-
*
|
|
74
|
-
* @private
|
|
75
|
-
*/
|
|
76
|
-
generateNonce(): string;
|
|
77
|
-
httpService: import("../HttpService").HttpService;
|
|
78
|
-
cloudURL: string;
|
|
79
|
-
config: import("../OxyServices.base").OxyConfig;
|
|
80
|
-
__resetTokensForTests(): void;
|
|
81
|
-
makeRequest<T_1>(method: "GET" | "POST" | "PUT" | "PATCH" | "DELETE", url: string, data?: any, options?: import("../HttpService").RequestOptions): Promise<T_1>;
|
|
82
|
-
getBaseURL(): string;
|
|
83
|
-
getSessionBaseUrl(): string;
|
|
84
|
-
getClient(): import("../HttpService").HttpService;
|
|
85
|
-
createLinkedClient(config: import("../OxyServices.base").OxyConfig): import("..").LinkedHttpClient;
|
|
86
|
-
getMetrics(): {
|
|
87
|
-
totalRequests: number;
|
|
88
|
-
successfulRequests: number;
|
|
89
|
-
failedRequests: number;
|
|
90
|
-
cacheHits: number;
|
|
91
|
-
cacheMisses: number;
|
|
92
|
-
averageResponseTime: number;
|
|
93
|
-
};
|
|
94
|
-
clearCache(): void;
|
|
95
|
-
clearCacheEntry(key: string): void;
|
|
96
|
-
clearCacheByPrefix(prefix: string): number;
|
|
97
|
-
getCacheStats(): {
|
|
98
|
-
size: number;
|
|
99
|
-
hits: number;
|
|
100
|
-
misses: number;
|
|
101
|
-
hitRate: number;
|
|
102
|
-
};
|
|
103
|
-
getCloudURL(): string;
|
|
104
|
-
setTokens(accessToken: string): void;
|
|
105
|
-
clearTokens(): void;
|
|
106
|
-
onTokensChanged(listener: (accessToken: string | null) => void): () => void;
|
|
107
|
-
_cachedUserId: string | null | undefined;
|
|
108
|
-
_cachedAccessToken: string | null;
|
|
109
|
-
getCurrentUserId(): string | null;
|
|
110
|
-
hasValidToken(): boolean;
|
|
111
|
-
getAccessToken(): string | null;
|
|
112
|
-
establishDeviceRefreshSlot(): Promise<number | null>;
|
|
113
|
-
getAccessTokenExpiry(): number | null;
|
|
114
|
-
waitForAuth(timeoutMs?: number): Promise<boolean>;
|
|
115
|
-
withAuthRetry<T_1>(operation: () => Promise<T_1>, operationName: string, options?: {
|
|
116
|
-
maxRetries?: number;
|
|
117
|
-
retryDelay?: number;
|
|
118
|
-
authTimeoutMs?: number;
|
|
119
|
-
}): Promise<T_1>;
|
|
120
|
-
validate(): Promise<boolean>;
|
|
121
|
-
handleError(error: unknown): Error;
|
|
122
|
-
healthCheck(): Promise<{
|
|
123
|
-
status: string;
|
|
124
|
-
users?: number;
|
|
125
|
-
timestamp?: string;
|
|
126
|
-
[key: string]: any;
|
|
127
|
-
}>;
|
|
128
|
-
};
|
|
129
|
-
readonly DEFAULT_AUTH_URL: "https://auth.oxy.so";
|
|
130
|
-
readonly SILENT_TIMEOUT: 5000;
|
|
131
|
-
} & T;
|
|
132
|
-
export { OxyServicesSilentAuthMixin as SilentAuthMixin };
|