@oxyhq/core 12.10.6 → 12.11.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/dist/cjs/.tsbuildinfo +1 -1
- package/dist/cjs/HttpService.js +66 -6
- package/dist/cjs/boot/sessionColdBoot.js +142 -37
- package/dist/cjs/i18n/locales/ar-SA.json +13 -1
- package/dist/cjs/i18n/locales/ca-ES.json +13 -1
- package/dist/cjs/i18n/locales/de-DE.json +13 -1
- package/dist/cjs/i18n/locales/en-US.json +13 -4
- package/dist/cjs/i18n/locales/es-ES.json +13 -4
- package/dist/cjs/i18n/locales/fr-FR.json +13 -1
- package/dist/cjs/i18n/locales/it-IT.json +13 -1
- package/dist/cjs/i18n/locales/ja-JP.json +13 -1
- package/dist/cjs/i18n/locales/ko-KR.json +13 -1
- package/dist/cjs/i18n/locales/locales/ar-SA.json +13 -1
- package/dist/cjs/i18n/locales/locales/ca-ES.json +13 -1
- package/dist/cjs/i18n/locales/locales/de-DE.json +13 -1
- package/dist/cjs/i18n/locales/locales/en-US.json +13 -4
- package/dist/cjs/i18n/locales/locales/es-ES.json +13 -4
- package/dist/cjs/i18n/locales/locales/fr-FR.json +13 -1
- package/dist/cjs/i18n/locales/locales/it-IT.json +13 -1
- package/dist/cjs/i18n/locales/locales/ja-JP.json +13 -1
- package/dist/cjs/i18n/locales/locales/ko-KR.json +13 -1
- package/dist/cjs/i18n/locales/locales/pt-PT.json +13 -1
- package/dist/cjs/i18n/locales/locales/zh-CN.json +13 -1
- package/dist/cjs/i18n/locales/pt-PT.json +13 -1
- package/dist/cjs/i18n/locales/zh-CN.json +13 -1
- package/dist/cjs/index.js +31 -5
- package/dist/cjs/mixins/OxyServices.auth.js +257 -17
- package/dist/cjs/mixins/OxyServices.deviceBoot.js +54 -3
- package/dist/cjs/mixins/OxyServices.notifications.js +63 -0
- package/dist/cjs/mixins/OxyServices.privacy.js +6 -0
- package/dist/cjs/mixins/OxyServices.user.js +1 -0
- package/dist/cjs/mixins/index.js +5 -0
- package/dist/cjs/session/SessionClient.js +40 -4
- package/dist/cjs/session/accountDialogController.js +288 -41
- package/dist/cjs/session/identityPin.js +256 -0
- package/dist/cjs/session/identitySession.js +135 -0
- package/dist/cjs/session/projectSessionState.js +54 -15
- package/dist/cjs/session/refresh.js +73 -8
- package/dist/cjs/utils/commonsDelivery.js +59 -0
- package/dist/cjs/utils/oauthPkce.js +33 -3
- package/dist/esm/.tsbuildinfo +1 -1
- package/dist/esm/HttpService.js +66 -6
- package/dist/esm/boot/sessionColdBoot.js +142 -37
- package/dist/esm/i18n/locales/ar-SA.json +13 -1
- package/dist/esm/i18n/locales/ca-ES.json +13 -1
- package/dist/esm/i18n/locales/de-DE.json +13 -1
- package/dist/esm/i18n/locales/en-US.json +13 -4
- package/dist/esm/i18n/locales/es-ES.json +13 -4
- package/dist/esm/i18n/locales/fr-FR.json +13 -1
- package/dist/esm/i18n/locales/it-IT.json +13 -1
- package/dist/esm/i18n/locales/ja-JP.json +13 -1
- package/dist/esm/i18n/locales/ko-KR.json +13 -1
- package/dist/esm/i18n/locales/locales/ar-SA.json +13 -1
- package/dist/esm/i18n/locales/locales/ca-ES.json +13 -1
- package/dist/esm/i18n/locales/locales/de-DE.json +13 -1
- package/dist/esm/i18n/locales/locales/en-US.json +13 -4
- package/dist/esm/i18n/locales/locales/es-ES.json +13 -4
- package/dist/esm/i18n/locales/locales/fr-FR.json +13 -1
- package/dist/esm/i18n/locales/locales/it-IT.json +13 -1
- package/dist/esm/i18n/locales/locales/ja-JP.json +13 -1
- package/dist/esm/i18n/locales/locales/ko-KR.json +13 -1
- package/dist/esm/i18n/locales/locales/pt-PT.json +13 -1
- package/dist/esm/i18n/locales/locales/zh-CN.json +13 -1
- package/dist/esm/i18n/locales/pt-PT.json +13 -1
- package/dist/esm/i18n/locales/zh-CN.json +13 -1
- package/dist/esm/index.js +14 -1
- package/dist/esm/mixins/OxyServices.auth.js +257 -17
- package/dist/esm/mixins/OxyServices.deviceBoot.js +52 -3
- package/dist/esm/mixins/OxyServices.notifications.js +60 -0
- package/dist/esm/mixins/OxyServices.privacy.js +6 -0
- package/dist/esm/mixins/OxyServices.user.js +1 -0
- package/dist/esm/mixins/index.js +5 -0
- package/dist/esm/session/SessionClient.js +40 -4
- package/dist/esm/session/accountDialogController.js +288 -41
- package/dist/esm/session/identityPin.js +249 -0
- package/dist/esm/session/identitySession.js +131 -0
- package/dist/esm/session/projectSessionState.js +54 -15
- package/dist/esm/session/refresh.js +73 -8
- package/dist/esm/utils/commonsDelivery.js +54 -0
- package/dist/esm/utils/oauthPkce.js +31 -2
- package/dist/types/.tsbuildinfo +1 -1
- package/dist/types/HttpService.d.ts +18 -1
- package/dist/types/boot/sessionColdBoot.d.ts +38 -1
- package/dist/types/index.d.ts +12 -4
- package/dist/types/mixins/OxyServices.auth.d.ts +262 -11
- package/dist/types/mixins/OxyServices.deviceBoot.d.ts +31 -1
- package/dist/types/mixins/OxyServices.notifications.d.ts +143 -0
- package/dist/types/mixins/OxyServices.user.d.ts +2 -0
- package/dist/types/mixins/index.d.ts +2 -1
- package/dist/types/session/SessionClient.d.ts +28 -0
- package/dist/types/session/accountDialogController.d.ts +187 -9
- package/dist/types/session/identityPin.d.ts +87 -0
- package/dist/types/session/identitySession.d.ts +105 -0
- package/dist/types/session/projectSessionState.d.ts +21 -19
- package/dist/types/session/refresh.d.ts +32 -1
- package/dist/types/utils/commonsDelivery.d.ts +105 -0
- package/dist/types/utils/oauthPkce.d.ts +21 -1
- package/package.json +3 -3
- package/src/HttpService.ts +67 -6
- package/src/__tests__/inSessionRefresh.test.ts +67 -0
- package/src/boot/__tests__/sessionColdBoot.identity.test.ts +393 -0
- package/src/boot/sessionColdBoot.ts +183 -37
- package/src/i18n/locales/ar-SA.json +13 -1
- package/src/i18n/locales/ca-ES.json +13 -1
- package/src/i18n/locales/de-DE.json +13 -1
- package/src/i18n/locales/en-US.json +13 -4
- package/src/i18n/locales/es-ES.json +13 -4
- package/src/i18n/locales/fr-FR.json +13 -1
- package/src/i18n/locales/it-IT.json +13 -1
- package/src/i18n/locales/ja-JP.json +13 -1
- package/src/i18n/locales/ko-KR.json +13 -1
- package/src/i18n/locales/pt-PT.json +13 -1
- package/src/i18n/locales/zh-CN.json +13 -1
- package/src/index.ts +49 -0
- package/src/mixins/OxyServices.auth.ts +464 -24
- package/src/mixins/OxyServices.deviceBoot.ts +54 -2
- package/src/mixins/OxyServices.notifications.ts +142 -0
- package/src/mixins/OxyServices.privacy.ts +6 -0
- package/src/mixins/OxyServices.user.ts +3 -0
- package/src/mixins/__tests__/commonsSignIn.test.ts +754 -2
- package/src/mixins/__tests__/deviceTokenMintPinned.test.ts +113 -0
- package/src/mixins/__tests__/preSessionSkipAuth.test.ts +18 -0
- package/src/mixins/__tests__/privacyCacheInvalidation.test.ts +2 -0
- package/src/mixins/index.ts +6 -0
- package/src/session/SessionClient.ts +57 -4
- package/src/session/__tests__/SessionClient.identityPin.test.ts +175 -0
- package/src/session/__tests__/accountDialogController.test.ts +812 -1
- package/src/session/__tests__/identityPin.test.ts +131 -0
- package/src/session/__tests__/identitySession.test.ts +194 -0
- package/src/session/__tests__/projectSessionState.test.ts +88 -0
- package/src/session/__tests__/refresh.identityPin.test.ts +306 -0
- package/src/session/accountDialogController.ts +435 -44
- package/src/session/identityPin.ts +310 -0
- package/src/session/identitySession.ts +206 -0
- package/src/session/projectSessionState.ts +61 -13
- package/src/session/refresh.ts +103 -9
- package/src/utils/__tests__/oauthPkce.test.ts +51 -0
- package/src/utils/commonsDelivery.ts +132 -0
- package/src/utils/oauthPkce.ts +56 -3
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.selectCommonsDelivery = selectCommonsDelivery;
|
|
4
|
+
exports.pushTargetsFromDelivery = pushTargetsFromDelivery;
|
|
5
|
+
exports.commonsDeliveryPlatform = commonsDeliveryPlatform;
|
|
6
|
+
const platform_1 = require("./platform");
|
|
7
|
+
/**
|
|
8
|
+
* Choose the ONE primary delivery route for a "Sign in with Oxy" request.
|
|
9
|
+
*
|
|
10
|
+
* Decision order (issue #691, "Automatic delivery selection"):
|
|
11
|
+
*
|
|
12
|
+
* 1. Mobile with a verified Commons link available → open Commons directly.
|
|
13
|
+
* No push is needed when the identity is already reachable on this device.
|
|
14
|
+
* 2. At least one eligible Commons installation was pushed to → await the push.
|
|
15
|
+
* 3. Otherwise → QR.
|
|
16
|
+
*
|
|
17
|
+
* A caller that already knows it is on step 1 does not need to call
|
|
18
|
+
* `deliverCommonsSignIn` at all; every other caller runs the delivery
|
|
19
|
+
* round-trip first and passes its `targets` in here.
|
|
20
|
+
*
|
|
21
|
+
* `pushTargets` is server-derived, so it is validated rather than trusted: a
|
|
22
|
+
* negative, fractional, non-finite, or otherwise malformed count is treated as
|
|
23
|
+
* "no targets" and degrades to QR instead of parking the user on a "check your
|
|
24
|
+
* phone" screen that nothing will ever wake.
|
|
25
|
+
*/
|
|
26
|
+
function selectCommonsDelivery(facts) {
|
|
27
|
+
if (facts.platform === 'mobile' && facts.commonsAvailable) {
|
|
28
|
+
return 'open-commons';
|
|
29
|
+
}
|
|
30
|
+
if (Number.isInteger(facts.pushTargets) && facts.pushTargets >= 1) {
|
|
31
|
+
return 'await-push';
|
|
32
|
+
}
|
|
33
|
+
return 'qr';
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Map a `deliverCommonsSignIn` result onto the `pushTargets` fact for
|
|
37
|
+
* {@link selectCommonsDelivery}. The server reports eligible install *count*
|
|
38
|
+
* separately from whether any push was accepted — a transport failure can leave
|
|
39
|
+
* `delivered: false` with `targets > 0`, which must NOT park the user on
|
|
40
|
+
* "check your phone".
|
|
41
|
+
*/
|
|
42
|
+
function pushTargetsFromDelivery(result) {
|
|
43
|
+
return result.delivered ? result.targets : 0;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Classify the current runtime surface for delivery selection. Callers that
|
|
47
|
+
* cannot confidently detect the platform should not use this — pass
|
|
48
|
+
* `'unknown'` explicitly instead.
|
|
49
|
+
*/
|
|
50
|
+
function commonsDeliveryPlatform() {
|
|
51
|
+
const os = (0, platform_1.getPlatformOS)();
|
|
52
|
+
if (os === 'ios' || os === 'android') {
|
|
53
|
+
return 'mobile';
|
|
54
|
+
}
|
|
55
|
+
if (os === 'web') {
|
|
56
|
+
return 'desktop';
|
|
57
|
+
}
|
|
58
|
+
return 'unknown';
|
|
59
|
+
}
|
|
@@ -17,12 +17,13 @@
|
|
|
17
17
|
* React Native. No `require()`, so the ESM build stays bundler-clean.
|
|
18
18
|
*/
|
|
19
19
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
20
|
-
exports.OXY_OAUTH_RETURN_PATH_STORAGE_KEY = exports.OXY_CROSS_ORIGIN_RESTORE_ATTEMPTED_KEY = exports.OXY_SILENT_OAUTH_ATTEMPTED_KEY = exports.OXY_OAUTH_CODE_VERIFIER_STORAGE_KEY = exports.OXY_OAUTH_STATE_STORAGE_KEY = exports.DEFAULT_OAUTH_SCOPE = exports.OXY_AUTHORIZE_URL = void 0;
|
|
20
|
+
exports.OXY_OAUTH_RETURN_PATH_STORAGE_KEY = exports.OXY_CROSS_ORIGIN_RESTORE_ATTEMPTED_KEY = exports.OXY_SILENT_OAUTH_ATTEMPTED_KEY = exports.OXY_OAUTH_REDIRECT_URI_STORAGE_KEY = exports.OXY_OAUTH_CODE_VERIFIER_STORAGE_KEY = exports.OXY_OAUTH_STATE_STORAGE_KEY = exports.DEFAULT_OAUTH_SCOPE = exports.OXY_AUTHORIZE_URL = void 0;
|
|
21
21
|
exports.computeCodeChallenge = computeCodeChallenge;
|
|
22
22
|
exports.generatePkcePair = generatePkcePair;
|
|
23
23
|
exports.generateOAuthState = generateOAuthState;
|
|
24
24
|
exports.buildOAuthAuthorizeUrl = buildOAuthAuthorizeUrl;
|
|
25
25
|
exports.normalizeOAuthRedirectUri = normalizeOAuthRedirectUri;
|
|
26
|
+
exports.canonicalizeOAuthRedirectUri = canonicalizeOAuthRedirectUri;
|
|
26
27
|
exports.persistOAuthReturnPath = persistOAuthReturnPath;
|
|
27
28
|
exports.consumeOAuthReturnPath = consumeOAuthReturnPath;
|
|
28
29
|
exports.persistOAuthHandshake = persistOAuthHandshake;
|
|
@@ -147,12 +148,17 @@ function buildOAuthAuthorizeUrl(params) {
|
|
|
147
148
|
if (params.prompt) {
|
|
148
149
|
url.searchParams.set('prompt', params.prompt);
|
|
149
150
|
}
|
|
151
|
+
if (params.responseMode) {
|
|
152
|
+
url.searchParams.set('response_mode', params.responseMode);
|
|
153
|
+
}
|
|
150
154
|
return url.toString();
|
|
151
155
|
}
|
|
152
156
|
/** `sessionStorage` key for the OAuth CSRF `state` across an authorize redirect. */
|
|
153
157
|
exports.OXY_OAUTH_STATE_STORAGE_KEY = 'oxy_oauth_state';
|
|
154
158
|
/** `sessionStorage` key for the PKCE `code_verifier` across an authorize redirect. */
|
|
155
159
|
exports.OXY_OAUTH_CODE_VERIFIER_STORAGE_KEY = 'oxy_oauth_code_verifier';
|
|
160
|
+
/** `sessionStorage` key — the exact `redirect_uri` sent on the authorize request. */
|
|
161
|
+
exports.OXY_OAUTH_REDIRECT_URI_STORAGE_KEY = 'oxy.oauth_redirect_uri';
|
|
156
162
|
/** `sessionStorage` key — at most one silent OAuth attempt per navigation. */
|
|
157
163
|
exports.OXY_SILENT_OAUTH_ATTEMPTED_KEY = 'oxy.silent_oauth_attempted';
|
|
158
164
|
/** `sessionStorage` key — blocks further cross-origin auto-restore in this tab. */
|
|
@@ -179,6 +185,25 @@ function normalizeOAuthRedirectUri(input) {
|
|
|
179
185
|
return input;
|
|
180
186
|
}
|
|
181
187
|
}
|
|
188
|
+
/**
|
|
189
|
+
* Collapse `https://app.example/` → `https://app.example` for OAuth binding.
|
|
190
|
+
* Path-qualified redirect URIs are preserved — matches the API token exchange.
|
|
191
|
+
*/
|
|
192
|
+
function canonicalizeOAuthRedirectUri(redirectUri) {
|
|
193
|
+
try {
|
|
194
|
+
const parsed = new URL(redirectUri);
|
|
195
|
+
if (parsed.protocol !== 'https:' && parsed.protocol !== 'http:') {
|
|
196
|
+
return redirectUri;
|
|
197
|
+
}
|
|
198
|
+
if (parsed.pathname === '/' && !parsed.search && !parsed.hash) {
|
|
199
|
+
return parsed.origin;
|
|
200
|
+
}
|
|
201
|
+
return redirectUri;
|
|
202
|
+
}
|
|
203
|
+
catch {
|
|
204
|
+
return redirectUri;
|
|
205
|
+
}
|
|
206
|
+
}
|
|
182
207
|
/**
|
|
183
208
|
* Is this a safe same-origin path to restore into the address bar?
|
|
184
209
|
*
|
|
@@ -244,13 +269,16 @@ function consumeOAuthReturnPath() {
|
|
|
244
269
|
}
|
|
245
270
|
}
|
|
246
271
|
/** Persist the OAuth handshake for a full-page redirect return (web only). */
|
|
247
|
-
function persistOAuthHandshake(state, codeVerifier) {
|
|
272
|
+
function persistOAuthHandshake(state, codeVerifier, redirectUri) {
|
|
248
273
|
const store = globalThis.sessionStorage;
|
|
249
274
|
try {
|
|
250
275
|
if (!store)
|
|
251
276
|
throw new Error('sessionStorage is unavailable');
|
|
252
277
|
store.setItem(exports.OXY_OAUTH_STATE_STORAGE_KEY, state);
|
|
253
278
|
store.setItem(exports.OXY_OAUTH_CODE_VERIFIER_STORAGE_KEY, codeVerifier);
|
|
279
|
+
if (redirectUri) {
|
|
280
|
+
store.setItem(exports.OXY_OAUTH_REDIRECT_URI_STORAGE_KEY, canonicalizeOAuthRedirectUri(redirectUri));
|
|
281
|
+
}
|
|
254
282
|
return true;
|
|
255
283
|
}
|
|
256
284
|
catch (error) {
|
|
@@ -267,7 +295,8 @@ function readOAuthHandshake() {
|
|
|
267
295
|
const codeVerifier = store.getItem(exports.OXY_OAUTH_CODE_VERIFIER_STORAGE_KEY);
|
|
268
296
|
if (!state || !codeVerifier)
|
|
269
297
|
return null;
|
|
270
|
-
|
|
298
|
+
const redirectUri = store.getItem(exports.OXY_OAUTH_REDIRECT_URI_STORAGE_KEY) ?? undefined;
|
|
299
|
+
return redirectUri ? { state, codeVerifier, redirectUri } : { state, codeVerifier };
|
|
271
300
|
}
|
|
272
301
|
/** Drop persisted OAuth handshake keys after a successful or aborted return. */
|
|
273
302
|
function clearOAuthHandshake() {
|
|
@@ -275,6 +304,7 @@ function clearOAuthHandshake() {
|
|
|
275
304
|
try {
|
|
276
305
|
store?.removeItem(exports.OXY_OAUTH_STATE_STORAGE_KEY);
|
|
277
306
|
store?.removeItem(exports.OXY_OAUTH_CODE_VERIFIER_STORAGE_KEY);
|
|
307
|
+
store?.removeItem(exports.OXY_OAUTH_REDIRECT_URI_STORAGE_KEY);
|
|
278
308
|
// The return path belongs to this handshake. Leaving it behind would let a
|
|
279
309
|
// later, unrelated navigation in the same tab be redirected by it.
|
|
280
310
|
store?.removeItem(exports.OXY_OAUTH_RETURN_PATH_STORAGE_KEY);
|