@oxyhq/core 3.4.0 → 3.4.2
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/AuthManager.js +91 -319
- package/dist/cjs/CrossDomainAuth.js +19 -106
- package/dist/cjs/HttpService.js +49 -73
- package/dist/cjs/OxyServices.base.js +2 -2
- package/dist/cjs/i18n/index.js +7 -1
- package/dist/cjs/i18n/locales/ar-SA.json +18 -2
- package/dist/cjs/i18n/locales/ca-ES.json +18 -2
- package/dist/cjs/i18n/locales/de-DE.json +18 -2
- package/dist/cjs/i18n/locales/en-US.json +16 -2
- package/dist/cjs/i18n/locales/es-ES.json +16 -2
- package/dist/cjs/i18n/locales/fr-FR.json +18 -2
- package/dist/cjs/i18n/locales/it-IT.json +18 -2
- package/dist/cjs/i18n/locales/ja-JP.json +18 -2
- package/dist/cjs/i18n/locales/ko-KR.json +18 -2
- package/dist/cjs/i18n/locales/locales/ar-SA.json +18 -2
- package/dist/cjs/i18n/locales/locales/ca-ES.json +18 -2
- package/dist/cjs/i18n/locales/locales/de-DE.json +18 -2
- package/dist/cjs/i18n/locales/locales/en-US.json +17 -3
- package/dist/cjs/i18n/locales/locales/es-ES.json +16 -2
- package/dist/cjs/i18n/locales/locales/fr-FR.json +18 -2
- package/dist/cjs/i18n/locales/locales/it-IT.json +18 -2
- package/dist/cjs/i18n/locales/locales/ja-JP.json +18 -2
- package/dist/cjs/i18n/locales/locales/ko-KR.json +18 -2
- package/dist/cjs/i18n/locales/locales/pt-PT.json +18 -2
- package/dist/cjs/i18n/locales/locales/zh-CN.json +18 -2
- package/dist/cjs/i18n/locales/pt-PT.json +18 -2
- package/dist/cjs/i18n/locales/zh-CN.json +18 -2
- package/dist/cjs/mixins/OxyServices.auth.js +20 -63
- package/dist/cjs/mixins/OxyServices.fedcm.js +10 -12
- package/dist/cjs/mixins/OxyServices.popup.js +50 -299
- package/dist/cjs/mixins/OxyServices.redirect.js +84 -348
- package/dist/cjs/mixins/OxyServices.silent.js +204 -0
- package/dist/cjs/mixins/OxyServices.sso.js +4 -5
- package/dist/cjs/mixins/OxyServices.utility.js +6 -15
- package/dist/cjs/mixins/index.js +5 -6
- package/dist/cjs/server/index.js +21 -0
- package/dist/cjs/server/rateLimit.js +77 -0
- package/dist/cjs/shared/utils/debugUtils.js +1 -1
- package/dist/cjs/utils/accountUtils.js +4 -4
- package/dist/cjs/utils/authHelpers.js +21 -15
- package/dist/cjs/utils/coldBoot.js +3 -3
- package/dist/cjs/utils/fapiAutoDetect.js +1 -1
- package/dist/esm/.tsbuildinfo +1 -1
- package/dist/esm/AuthManager.js +91 -319
- package/dist/esm/CrossDomainAuth.js +19 -106
- package/dist/esm/HttpService.js +49 -73
- package/dist/esm/OxyServices.base.js +2 -2
- package/dist/esm/i18n/index.js +7 -1
- package/dist/esm/i18n/locales/ar-SA.json +18 -2
- package/dist/esm/i18n/locales/ca-ES.json +18 -2
- package/dist/esm/i18n/locales/de-DE.json +18 -2
- package/dist/esm/i18n/locales/en-US.json +16 -2
- package/dist/esm/i18n/locales/es-ES.json +16 -2
- package/dist/esm/i18n/locales/fr-FR.json +18 -2
- package/dist/esm/i18n/locales/it-IT.json +18 -2
- package/dist/esm/i18n/locales/ja-JP.json +18 -2
- package/dist/esm/i18n/locales/ko-KR.json +18 -2
- package/dist/esm/i18n/locales/locales/ar-SA.json +18 -2
- package/dist/esm/i18n/locales/locales/ca-ES.json +18 -2
- package/dist/esm/i18n/locales/locales/de-DE.json +18 -2
- package/dist/esm/i18n/locales/locales/en-US.json +17 -3
- package/dist/esm/i18n/locales/locales/es-ES.json +16 -2
- package/dist/esm/i18n/locales/locales/fr-FR.json +18 -2
- package/dist/esm/i18n/locales/locales/it-IT.json +18 -2
- package/dist/esm/i18n/locales/locales/ja-JP.json +18 -2
- package/dist/esm/i18n/locales/locales/ko-KR.json +18 -2
- package/dist/esm/i18n/locales/locales/pt-PT.json +18 -2
- package/dist/esm/i18n/locales/locales/zh-CN.json +18 -2
- package/dist/esm/i18n/locales/pt-PT.json +18 -2
- package/dist/esm/i18n/locales/zh-CN.json +18 -2
- package/dist/esm/mixins/OxyServices.auth.js +20 -63
- package/dist/esm/mixins/OxyServices.fedcm.js +10 -12
- package/dist/esm/mixins/OxyServices.popup.js +52 -301
- package/dist/esm/mixins/OxyServices.redirect.js +84 -349
- package/dist/esm/mixins/OxyServices.silent.js +202 -0
- package/dist/esm/mixins/OxyServices.sso.js +4 -5
- package/dist/esm/mixins/OxyServices.utility.js +6 -15
- package/dist/esm/mixins/index.js +5 -6
- package/dist/esm/server/index.js +17 -0
- package/dist/esm/server/rateLimit.js +71 -0
- package/dist/esm/shared/utils/debugUtils.js +1 -1
- package/dist/esm/utils/accountUtils.js +4 -4
- package/dist/esm/utils/authHelpers.js +21 -15
- package/dist/esm/utils/coldBoot.js +3 -3
- package/dist/esm/utils/fapiAutoDetect.js +1 -1
- package/dist/types/.tsbuildinfo +1 -1
- package/dist/types/AuthManager.d.ts +26 -53
- package/dist/types/AuthManagerTypes.d.ts +5 -9
- package/dist/types/CrossDomainAuth.d.ts +13 -52
- package/dist/types/HttpService.d.ts +9 -8
- package/dist/types/OxyServices.base.d.ts +1 -1
- package/dist/types/OxyServices.d.ts +4 -10
- package/dist/types/index.d.ts +1 -1
- package/dist/types/mixins/OxyServices.analytics.d.ts +1 -1
- package/dist/types/mixins/OxyServices.appData.d.ts +1 -1
- package/dist/types/mixins/OxyServices.applications.d.ts +1 -1
- package/dist/types/mixins/OxyServices.assets.d.ts +1 -1
- package/dist/types/mixins/OxyServices.auth.d.ts +10 -31
- package/dist/types/mixins/OxyServices.contacts.d.ts +1 -1
- package/dist/types/mixins/OxyServices.devices.d.ts +1 -1
- package/dist/types/mixins/OxyServices.features.d.ts +1 -1
- package/dist/types/mixins/OxyServices.fedcm.d.ts +5 -5
- package/dist/types/mixins/OxyServices.language.d.ts +1 -1
- package/dist/types/mixins/OxyServices.location.d.ts +1 -1
- package/dist/types/mixins/OxyServices.managedAccounts.d.ts +1 -1
- package/dist/types/mixins/OxyServices.payment.d.ts +1 -1
- package/dist/types/mixins/OxyServices.popup.d.ts +18 -120
- package/dist/types/mixins/OxyServices.privacy.d.ts +1 -1
- package/dist/types/mixins/OxyServices.redirect.d.ts +13 -174
- package/dist/types/mixins/OxyServices.reputation.d.ts +1 -1
- package/dist/types/mixins/OxyServices.security.d.ts +1 -1
- package/dist/types/mixins/OxyServices.silent.d.ts +131 -0
- package/dist/types/mixins/OxyServices.sso.d.ts +4 -5
- package/dist/types/mixins/OxyServices.topics.d.ts +1 -1
- package/dist/types/mixins/OxyServices.user.d.ts +1 -1
- package/dist/types/mixins/OxyServices.utility.d.ts +3 -8
- package/dist/types/mixins/OxyServices.workspaces.d.ts +1 -1
- package/dist/types/mixins/index.d.ts +3 -3
- package/dist/types/models/interfaces.d.ts +5 -16
- package/dist/types/models/session.d.ts +0 -2
- package/dist/types/server/index.d.ts +18 -0
- package/dist/types/server/rateLimit.d.ts +40 -0
- package/dist/types/shared/utils/debugUtils.d.ts +1 -1
- package/dist/types/utils/authHelpers.d.ts +4 -3
- package/dist/types/utils/coldBoot.d.ts +2 -2
- package/dist/types/utils/fapiAutoDetect.d.ts +1 -1
- package/package.json +25 -3
- package/src/AuthManager.ts +100 -370
- package/src/AuthManagerTypes.ts +5 -9
- package/src/CrossDomainAuth.ts +22 -129
- package/src/HttpService.ts +55 -73
- package/src/OxyServices.base.ts +2 -3
- package/src/OxyServices.ts +9 -11
- package/src/__tests__/authManager.cookiePath.test.ts +19 -17
- package/src/__tests__/authManager.security.test.ts +7 -3
- package/src/__tests__/crossDomainAuth.test.ts +26 -118
- package/src/i18n/index.ts +7 -1
- package/src/i18n/locales/ar-SA.json +18 -2
- package/src/i18n/locales/ca-ES.json +18 -2
- package/src/i18n/locales/de-DE.json +18 -2
- package/src/i18n/locales/en-US.json +17 -3
- package/src/i18n/locales/es-ES.json +16 -2
- package/src/i18n/locales/fr-FR.json +18 -2
- package/src/i18n/locales/it-IT.json +18 -2
- package/src/i18n/locales/ja-JP.json +18 -2
- package/src/i18n/locales/ko-KR.json +18 -2
- package/src/i18n/locales/pt-PT.json +18 -2
- package/src/i18n/locales/zh-CN.json +18 -2
- package/src/index.ts +1 -1
- package/src/mixins/OxyServices.auth.ts +23 -75
- package/src/mixins/OxyServices.fedcm.ts +10 -12
- package/src/mixins/OxyServices.redirect.ts +82 -371
- package/src/mixins/OxyServices.silent.ts +272 -0
- package/src/mixins/OxyServices.sso.ts +5 -6
- package/src/mixins/OxyServices.utility.ts +9 -22
- package/src/mixins/__tests__/appData.test.ts +1 -1
- package/src/mixins/__tests__/onTokensChanged.test.ts +1 -1
- package/src/mixins/__tests__/reputation.test.ts +1 -1
- package/src/mixins/__tests__/serviceAuth.test.ts +7 -5
- package/src/mixins/__tests__/silent.test.ts +102 -0
- package/src/mixins/__tests__/verifyChallenge.test.ts +9 -14
- package/src/mixins/index.ts +6 -8
- package/src/models/interfaces.ts +5 -16
- package/src/models/session.ts +1 -3
- package/src/server/index.ts +19 -0
- package/src/server/rateLimit.ts +170 -0
- package/src/shared/utils/debugUtils.ts +1 -1
- package/src/utils/accountUtils.ts +4 -4
- package/src/utils/authHelpers.ts +23 -15
- package/src/utils/coldBoot.ts +4 -4
- package/src/utils/fapiAutoDetect.ts +1 -1
- package/src/mixins/OxyServices.popup.ts +0 -631
- package/src/mixins/__tests__/popup.test.ts +0 -374
|
@@ -103,7 +103,9 @@
|
|
|
103
103
|
"createAccount": "创建账户",
|
|
104
104
|
"signIn": "登录",
|
|
105
105
|
"verify": "验证",
|
|
106
|
-
"resetPassword": "重置密码"
|
|
106
|
+
"resetPassword": "重置密码",
|
|
107
|
+
"signedOut": "已退出",
|
|
108
|
+
"close": "关闭"
|
|
107
109
|
},
|
|
108
110
|
"links": {
|
|
109
111
|
"recoverAccount": "恢复您的账户",
|
|
@@ -115,7 +117,10 @@
|
|
|
115
117
|
"password": "密码",
|
|
116
118
|
"confirmPassword": "确认密码"
|
|
117
119
|
},
|
|
118
|
-
"revoke": "Revoke"
|
|
120
|
+
"revoke": "Revoke",
|
|
121
|
+
"errors": {
|
|
122
|
+
"signOutAllFailed": "退出所有账户时出现问题。请重试。"
|
|
123
|
+
}
|
|
119
124
|
},
|
|
120
125
|
"notifications": {
|
|
121
126
|
"title": "Notifications",
|
|
@@ -198,5 +203,16 @@
|
|
|
198
203
|
"revoked": "Revoked access for {{name}}",
|
|
199
204
|
"revokeFailed": "Failed to revoke access"
|
|
200
205
|
}
|
|
206
|
+
},
|
|
207
|
+
"accountMenu": {
|
|
208
|
+
"label": "账户菜单",
|
|
209
|
+
"manage": "管理您的 Oxy 账户",
|
|
210
|
+
"addAnother": "添加其他账户",
|
|
211
|
+
"signOutAll": "退出所有账户",
|
|
212
|
+
"open": "账户菜单",
|
|
213
|
+
"openHint": "打开账户菜单",
|
|
214
|
+
"openWithUser": "{{name}} 的账户菜单",
|
|
215
|
+
"switching": "正在切换账户…",
|
|
216
|
+
"signOutAccount": "退出 {{name}}"
|
|
201
217
|
}
|
|
202
218
|
}
|
package/src/index.ts
CHANGED
|
@@ -46,7 +46,7 @@ export type {
|
|
|
46
46
|
export { CrossDomainAuth, createCrossDomainAuth } from './CrossDomainAuth';
|
|
47
47
|
export type { CrossDomainAuthOptions } from './CrossDomainAuth';
|
|
48
48
|
export type { FedCMAuthOptions, FedCMConfig, AuthorizedApp } from './mixins/OxyServices.fedcm';
|
|
49
|
-
export type {
|
|
49
|
+
export type { SilentAuthOptions } from './mixins/OxyServices.silent';
|
|
50
50
|
export type { RedirectAuthOptions } from './mixins/OxyServices.redirect';
|
|
51
51
|
export { ServiceCredentialMismatchError } from './mixins/OxyServices.auth';
|
|
52
52
|
export type { ServiceTokenResponse } from './mixins/OxyServices.auth';
|
|
@@ -34,8 +34,8 @@ export interface RefreshAllOptions {
|
|
|
34
34
|
* or unreachable endpoint with no useful answer coming back. As one step of
|
|
35
35
|
* the ordered cold-boot sequence, a stalled refresh is dead latency in front
|
|
36
36
|
* of the steps that actually hold the answer. A bounded abort lets cold boot
|
|
37
|
-
* fall through quickly. Omit (or pass `0`/negative) to wait indefinitely
|
|
38
|
-
*
|
|
37
|
+
* fall through quickly. Omit (or pass `0`/negative) to wait indefinitely.
|
|
38
|
+
* The abort is treated identically to a 401 — the
|
|
39
39
|
* "not signed in on this device" path — never an error.
|
|
40
40
|
*/
|
|
41
41
|
timeout?: number;
|
|
@@ -445,14 +445,10 @@ export function OxyServicesAuthMixin<T extends typeof OxyServicesBase>(Base: T)
|
|
|
445
445
|
// Plant the freshly-minted tokens, mirroring `claimSessionByToken`.
|
|
446
446
|
// `/auth/verify` returns the first access token (and refresh token) in
|
|
447
447
|
// its body, so installing it here means callers get an authenticated
|
|
448
|
-
// client without a second round-trip
|
|
449
|
-
//
|
|
450
|
-
// (C1 hardening), which 401s for a brand-new identity that has no
|
|
451
|
-
// bearer yet. `accessToken`/`refreshToken` are optional on
|
|
452
|
-
// SessionLoginResponse; only plant when an access token is present and
|
|
453
|
-
// default the refresh token to an empty string.
|
|
448
|
+
// client without a second round-trip. Refresh stays in the httpOnly
|
|
449
|
+
// cookie slot set by the API.
|
|
454
450
|
if (res?.accessToken) {
|
|
455
|
-
this.setTokens(res.accessToken
|
|
451
|
+
this.setTokens(res.accessToken);
|
|
456
452
|
}
|
|
457
453
|
|
|
458
454
|
return res;
|
|
@@ -533,31 +529,6 @@ export function OxyServicesAuthMixin<T extends typeof OxyServicesBase>(Base: T)
|
|
|
533
529
|
}
|
|
534
530
|
}
|
|
535
531
|
|
|
536
|
-
/**
|
|
537
|
-
* Get access token by session ID
|
|
538
|
-
*
|
|
539
|
-
* SECURITY: this endpoint requires the caller to already hold a
|
|
540
|
-
* bearer token whose user owns the referenced session (C1 hardening
|
|
541
|
-
* in the API). For the device-flow / QR sign-in case where the
|
|
542
|
-
* client has no bearer token yet, use `claimSessionByToken` instead.
|
|
543
|
-
*/
|
|
544
|
-
async getTokenBySession(sessionId: string): Promise<{ accessToken: string; expiresAt: string }> {
|
|
545
|
-
try {
|
|
546
|
-
const res = await this.makeRequest<{ accessToken: string; expiresAt: string }>(
|
|
547
|
-
'GET',
|
|
548
|
-
`/session/token/${sessionId}`,
|
|
549
|
-
undefined,
|
|
550
|
-
{ cache: false, retry: false }
|
|
551
|
-
);
|
|
552
|
-
|
|
553
|
-
this.setTokens(res.accessToken);
|
|
554
|
-
|
|
555
|
-
return res;
|
|
556
|
-
} catch (error) {
|
|
557
|
-
throw this.handleError(error);
|
|
558
|
-
}
|
|
559
|
-
}
|
|
560
|
-
|
|
561
532
|
/**
|
|
562
533
|
* Exchange a device-flow sessionToken for the first access token.
|
|
563
534
|
*
|
|
@@ -584,7 +555,6 @@ export function OxyServicesAuthMixin<T extends typeof OxyServicesBase>(Base: T)
|
|
|
584
555
|
options: { deviceFingerprint?: string } = {}
|
|
585
556
|
): Promise<{
|
|
586
557
|
accessToken: string;
|
|
587
|
-
refreshToken: string;
|
|
588
558
|
sessionId: string;
|
|
589
559
|
deviceId: string;
|
|
590
560
|
expiresAt: string;
|
|
@@ -593,7 +563,6 @@ export function OxyServicesAuthMixin<T extends typeof OxyServicesBase>(Base: T)
|
|
|
593
563
|
try {
|
|
594
564
|
const res = await this.makeRequest<{
|
|
595
565
|
accessToken: string;
|
|
596
|
-
refreshToken: string;
|
|
597
566
|
sessionId: string;
|
|
598
567
|
deviceId: string;
|
|
599
568
|
expiresAt: string;
|
|
@@ -608,7 +577,7 @@ export function OxyServicesAuthMixin<T extends typeof OxyServicesBase>(Base: T)
|
|
|
608
577
|
{ cache: false, retry: false }
|
|
609
578
|
);
|
|
610
579
|
|
|
611
|
-
this.setTokens(res.accessToken
|
|
580
|
+
this.setTokens(res.accessToken);
|
|
612
581
|
|
|
613
582
|
return res;
|
|
614
583
|
} catch (error) {
|
|
@@ -621,19 +590,14 @@ export function OxyServicesAuthMixin<T extends typeof OxyServicesBase>(Base: T)
|
|
|
621
590
|
* (Google-style multi-account rebuild).
|
|
622
591
|
*
|
|
623
592
|
* Calls `POST {sessionBaseUrl}/auth/refresh-all` with `credentials: 'include'`
|
|
624
|
-
* and NO bearer. The browser attaches every `
|
|
625
|
-
* server rotates each in parallel and returns one entry
|
|
593
|
+
* and NO bearer. The browser attaches every indexed `oxy_rt_${authuser}`
|
|
594
|
+
* cookie it has; the server rotates each in parallel and returns one entry
|
|
595
|
+
* per VALID account.
|
|
626
596
|
*
|
|
627
597
|
* Failure handling:
|
|
628
598
|
* - 401 → no signed-in accounts on this device → returns `{ accounts: [] }`
|
|
629
599
|
* (NOT an error; this is the cold-boot "not signed in" path).
|
|
630
|
-
* - 404 →
|
|
631
|
-
* `POST /auth/refresh` (single-slot) and wrap its response in the
|
|
632
|
-
* refresh-all shape so callers can treat the two paths uniformly. The
|
|
633
|
-
* fallback entry has `authuser: 0` (the legacy slot maps to slot 0 by
|
|
634
|
-
* convention) and a minimal `user` shape — consumers needing the full
|
|
635
|
-
* user must fetch it separately. Always exactly one account in this
|
|
636
|
-
* shape.
|
|
600
|
+
* - 404 → endpoint not deployed → returns `{ accounts: [] }`.
|
|
637
601
|
* - Any other non-2xx → throws via `handleError`.
|
|
638
602
|
*
|
|
639
603
|
* The refresh cookie itself never enters JS — only the rotated access
|
|
@@ -682,22 +646,7 @@ export function OxyServicesAuthMixin<T extends typeof OxyServicesBase>(Base: T)
|
|
|
682
646
|
}
|
|
683
647
|
|
|
684
648
|
if (response.status === 404) {
|
|
685
|
-
|
|
686
|
-
// caller can treat both paths identically.
|
|
687
|
-
const legacy = await this._refreshCookieRaw();
|
|
688
|
-
if (!legacy) {
|
|
689
|
-
return { accounts: [] };
|
|
690
|
-
}
|
|
691
|
-
const fallbackAccount: RefreshAllAccount = {
|
|
692
|
-
authuser: 0,
|
|
693
|
-
accessToken: legacy.accessToken,
|
|
694
|
-
expiresAt: legacy.expiresAt,
|
|
695
|
-
sessionId: this._decodeSessionIdFromAccessToken(legacy.accessToken) ?? '',
|
|
696
|
-
// Legacy /auth/refresh does NOT project the user shape; the caller
|
|
697
|
-
// (AuthManager) is expected to hydrate via /users/me after planting.
|
|
698
|
-
user: null,
|
|
699
|
-
};
|
|
700
|
-
return { accounts: [fallbackAccount] };
|
|
649
|
+
return { accounts: [] };
|
|
701
650
|
}
|
|
702
651
|
|
|
703
652
|
if (!response.ok) {
|
|
@@ -715,7 +664,7 @@ export function OxyServicesAuthMixin<T extends typeof OxyServicesBase>(Base: T)
|
|
|
715
664
|
continue;
|
|
716
665
|
}
|
|
717
666
|
const e = entry as {
|
|
718
|
-
authuser?: number
|
|
667
|
+
authuser?: number;
|
|
719
668
|
accessToken?: string;
|
|
720
669
|
expiresAt?: string;
|
|
721
670
|
sessionId?: string;
|
|
@@ -728,11 +677,11 @@ export function OxyServicesAuthMixin<T extends typeof OxyServicesBase>(Base: T)
|
|
|
728
677
|
if (!userId || !e.user.username) {
|
|
729
678
|
continue;
|
|
730
679
|
}
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
680
|
+
if (typeof e.authuser !== 'number') {
|
|
681
|
+
continue;
|
|
682
|
+
}
|
|
734
683
|
accounts.push({
|
|
735
|
-
authuser,
|
|
684
|
+
authuser: e.authuser,
|
|
736
685
|
accessToken: e.accessToken,
|
|
737
686
|
expiresAt: e.expiresAt,
|
|
738
687
|
sessionId: e.sessionId,
|
|
@@ -755,9 +704,8 @@ export function OxyServicesAuthMixin<T extends typeof OxyServicesBase>(Base: T)
|
|
|
755
704
|
*
|
|
756
705
|
* When `authuser` is provided, the server rotates ONLY that slot
|
|
757
706
|
* (`oxy_rt_${authuser}`) — sibling accounts on the same device stay
|
|
758
|
-
* untouched. When omitted, the server picks the lowest indexed slot
|
|
759
|
-
*
|
|
760
|
-
* enters JS.
|
|
707
|
+
* untouched. When omitted, the server picks the lowest indexed slot present.
|
|
708
|
+
* The refresh cookie itself never enters JS.
|
|
761
709
|
*
|
|
762
710
|
* Returns `null` on 401 (no cookie / expired / reused) so the caller can
|
|
763
711
|
* fall through cleanly to the unauthenticated path.
|
|
@@ -815,9 +763,7 @@ export function OxyServicesAuthMixin<T extends typeof OxyServicesBase>(Base: T)
|
|
|
815
763
|
|
|
816
764
|
/**
|
|
817
765
|
* Internal: raw `POST /auth/refresh[?authuser=N]` call returning the
|
|
818
|
-
* minted access token. Returns `null` on 401 / non-2xx.
|
|
819
|
-
* implementation of `refreshTokenViaCookie` and the legacy fallback for
|
|
820
|
-
* `refreshAllSessions` against older servers.
|
|
766
|
+
* minted access token. Returns `null` on 401 / non-2xx.
|
|
821
767
|
*
|
|
822
768
|
* @internal
|
|
823
769
|
*/
|
|
@@ -851,11 +797,13 @@ export function OxyServicesAuthMixin<T extends typeof OxyServicesBase>(Base: T)
|
|
|
851
797
|
return null;
|
|
852
798
|
}
|
|
853
799
|
const expiresAt = typeof payload.expiresAt === 'string' ? payload.expiresAt : '';
|
|
854
|
-
|
|
800
|
+
if (typeof payload.authuser !== 'number') {
|
|
801
|
+
return null;
|
|
802
|
+
}
|
|
855
803
|
return {
|
|
856
804
|
accessToken: payload.accessToken,
|
|
857
805
|
expiresAt,
|
|
858
|
-
authuser:
|
|
806
|
+
authuser: payload.authuser,
|
|
859
807
|
};
|
|
860
808
|
}
|
|
861
809
|
|
|
@@ -175,7 +175,7 @@ let fedCMActiveController: AbortController | null = null;
|
|
|
175
175
|
* - Firefox: Not yet supported (fallback required)
|
|
176
176
|
*
|
|
177
177
|
* Key Features:
|
|
178
|
-
* - No redirects or
|
|
178
|
+
* - No redirects or secondary windows required
|
|
179
179
|
* - Browser-native UI prompts
|
|
180
180
|
* - Privacy-preserving (IdP can't track users)
|
|
181
181
|
* - Automatic SSO across domains
|
|
@@ -245,7 +245,7 @@ export function OxyServicesFedCMMixin<T extends typeof OxyServicesBase>(Base: T)
|
|
|
245
245
|
*
|
|
246
246
|
* This provides a Google-style authentication experience:
|
|
247
247
|
* - Browser shows native "Sign in with Oxy" prompt
|
|
248
|
-
* - No redirect or
|
|
248
|
+
* - No redirect or secondary window required
|
|
249
249
|
* - User approves → credential exchange happens in browser
|
|
250
250
|
* - All apps automatically get SSO after first sign-in
|
|
251
251
|
*
|
|
@@ -259,8 +259,8 @@ export function OxyServicesFedCMMixin<T extends typeof OxyServicesBase>(Base: T)
|
|
|
259
259
|
* const session = await oxyServices.signInWithFedCM();
|
|
260
260
|
* console.log('Signed in:', session.user);
|
|
261
261
|
* } catch (error) {
|
|
262
|
-
* // Fallback to
|
|
263
|
-
*
|
|
262
|
+
* // Fallback to redirect auth
|
|
263
|
+
* oxyServices.signInWithRedirect();
|
|
264
264
|
* }
|
|
265
265
|
* ```
|
|
266
266
|
*/
|
|
@@ -340,11 +340,10 @@ export function OxyServicesFedCMMixin<T extends typeof OxyServicesBase>(Base: T)
|
|
|
340
340
|
// Exchange FedCM ID token for Oxy session
|
|
341
341
|
const session = await this.exchangeIdTokenForSession(credential.token);
|
|
342
342
|
|
|
343
|
-
// Store access token in HttpService.
|
|
344
|
-
//
|
|
345
|
-
// an empty string when the exchange did not return one.
|
|
343
|
+
// Store the access token in HttpService. Refresh stays in the httpOnly
|
|
344
|
+
// cookie slot set by the API.
|
|
346
345
|
if (session?.accessToken) {
|
|
347
|
-
this.httpService.setTokens(session.accessToken
|
|
346
|
+
this.httpService.setTokens(session.accessToken);
|
|
348
347
|
}
|
|
349
348
|
|
|
350
349
|
// Store the user ID as loginHint for future FedCM requests — only now, after
|
|
@@ -513,11 +512,10 @@ export function OxyServicesFedCMMixin<T extends typeof OxyServicesBase>(Base: T)
|
|
|
513
512
|
return null;
|
|
514
513
|
}
|
|
515
514
|
|
|
516
|
-
//
|
|
517
|
-
//
|
|
518
|
-
// the exchange did not return one.
|
|
515
|
+
// Store the access token. Refresh stays in the httpOnly cookie slot set by
|
|
516
|
+
// the API.
|
|
519
517
|
if (session.accessToken) {
|
|
520
|
-
this.httpService.setTokens(session.accessToken
|
|
518
|
+
this.httpService.setTokens(session.accessToken);
|
|
521
519
|
debug.log('Silent SSO: Access token set');
|
|
522
520
|
} else {
|
|
523
521
|
debug.warn('Silent SSO: No accessToken in session response');
|