@oxyhq/core 12.10.0 → 12.10.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/HttpService.js +22 -12
- package/dist/cjs/i18n/locales/ar-SA.json +4 -0
- package/dist/cjs/i18n/locales/ca-ES.json +4 -0
- package/dist/cjs/i18n/locales/de-DE.json +4 -0
- package/dist/cjs/i18n/locales/en-US.json +69 -3
- package/dist/cjs/i18n/locales/es-ES.json +68 -2
- package/dist/cjs/i18n/locales/fr-FR.json +4 -0
- package/dist/cjs/i18n/locales/it-IT.json +4 -0
- package/dist/cjs/i18n/locales/ja-JP.json +4 -0
- package/dist/cjs/i18n/locales/ko-KR.json +4 -0
- package/dist/cjs/i18n/locales/locales/ar-SA.json +4 -0
- package/dist/cjs/i18n/locales/locales/ca-ES.json +4 -0
- package/dist/cjs/i18n/locales/locales/de-DE.json +4 -0
- package/dist/cjs/i18n/locales/locales/en-US.json +69 -3
- package/dist/cjs/i18n/locales/locales/es-ES.json +68 -2
- package/dist/cjs/i18n/locales/locales/fr-FR.json +4 -0
- package/dist/cjs/i18n/locales/locales/it-IT.json +4 -0
- package/dist/cjs/i18n/locales/locales/ja-JP.json +4 -0
- package/dist/cjs/i18n/locales/locales/ko-KR.json +4 -0
- package/dist/cjs/i18n/locales/locales/pt-PT.json +4 -0
- package/dist/cjs/i18n/locales/locales/zh-CN.json +4 -0
- package/dist/cjs/i18n/locales/pt-PT.json +4 -0
- package/dist/cjs/i18n/locales/zh-CN.json +4 -0
- package/dist/cjs/mixins/OxyServices.auth.js +47 -19
- package/dist/cjs/mixins/OxyServices.connectedApps.js +6 -1
- package/dist/cjs/mixins/OxyServices.deviceBoot.js +9 -2
- package/dist/cjs/mixins/OxyServices.user.js +2 -0
- package/dist/cjs/session/accountDialogController.js +7 -5
- package/dist/esm/.tsbuildinfo +1 -1
- package/dist/esm/HttpService.js +22 -12
- package/dist/esm/i18n/locales/ar-SA.json +4 -0
- package/dist/esm/i18n/locales/ca-ES.json +4 -0
- package/dist/esm/i18n/locales/de-DE.json +4 -0
- package/dist/esm/i18n/locales/en-US.json +69 -3
- package/dist/esm/i18n/locales/es-ES.json +68 -2
- package/dist/esm/i18n/locales/fr-FR.json +4 -0
- package/dist/esm/i18n/locales/it-IT.json +4 -0
- package/dist/esm/i18n/locales/ja-JP.json +4 -0
- package/dist/esm/i18n/locales/ko-KR.json +4 -0
- package/dist/esm/i18n/locales/locales/ar-SA.json +4 -0
- package/dist/esm/i18n/locales/locales/ca-ES.json +4 -0
- package/dist/esm/i18n/locales/locales/de-DE.json +4 -0
- package/dist/esm/i18n/locales/locales/en-US.json +69 -3
- package/dist/esm/i18n/locales/locales/es-ES.json +68 -2
- package/dist/esm/i18n/locales/locales/fr-FR.json +4 -0
- package/dist/esm/i18n/locales/locales/it-IT.json +4 -0
- package/dist/esm/i18n/locales/locales/ja-JP.json +4 -0
- package/dist/esm/i18n/locales/locales/ko-KR.json +4 -0
- package/dist/esm/i18n/locales/locales/pt-PT.json +4 -0
- package/dist/esm/i18n/locales/locales/zh-CN.json +4 -0
- package/dist/esm/i18n/locales/pt-PT.json +4 -0
- package/dist/esm/i18n/locales/zh-CN.json +4 -0
- package/dist/esm/mixins/OxyServices.auth.js +47 -19
- package/dist/esm/mixins/OxyServices.connectedApps.js +6 -1
- package/dist/esm/mixins/OxyServices.deviceBoot.js +9 -2
- package/dist/esm/mixins/OxyServices.user.js +2 -0
- package/dist/esm/session/accountDialogController.js +7 -5
- package/dist/types/.tsbuildinfo +1 -1
- package/dist/types/HttpService.d.ts +14 -0
- package/dist/types/session/accountDialogController.d.ts +7 -2
- package/package.json +1 -1
- package/src/HttpService.ts +37 -14
- package/src/__tests__/httpServiceAuthSelfAwait.test.ts +108 -0
- package/src/__tests__/httpServiceQueueDeadlock.test.ts +128 -0
- package/src/i18n/locales/ar-SA.json +4 -0
- package/src/i18n/locales/ca-ES.json +4 -0
- package/src/i18n/locales/de-DE.json +4 -0
- package/src/i18n/locales/en-US.json +69 -3
- package/src/i18n/locales/es-ES.json +68 -2
- package/src/i18n/locales/fr-FR.json +4 -0
- package/src/i18n/locales/it-IT.json +4 -0
- package/src/i18n/locales/ja-JP.json +4 -0
- package/src/i18n/locales/ko-KR.json +4 -0
- package/src/i18n/locales/pt-PT.json +4 -0
- package/src/i18n/locales/zh-CN.json +4 -0
- package/src/mixins/OxyServices.auth.ts +39 -19
- package/src/mixins/OxyServices.connectedApps.ts +6 -1
- package/src/mixins/OxyServices.deviceBoot.ts +7 -2
- package/src/mixins/OxyServices.user.ts +2 -0
- package/src/mixins/__tests__/OxyServices.deviceBoot.test.ts +4 -2
- package/src/mixins/__tests__/commonsSignIn.test.ts +4 -4
- package/src/mixins/__tests__/preSessionSkipAuth.test.ts +152 -0
- package/src/mixins/__tests__/webauthnAuth.test.ts +6 -6
- package/src/session/__tests__/accountDialogController.test.ts +3 -3
- package/src/session/accountDialogController.ts +7 -6
|
@@ -112,6 +112,10 @@
|
|
|
112
112
|
}
|
|
113
113
|
},
|
|
114
114
|
"accountSwitcher": {
|
|
115
|
+
"sections": {
|
|
116
|
+
"yourAccounts": "내 계정"
|
|
117
|
+
},
|
|
118
|
+
"loading": "계정을 불러오는 중...",
|
|
115
119
|
"qrHeadline": "Oxy ID로 로그인",
|
|
116
120
|
"signInWithOxy": "Oxy로 로그인",
|
|
117
121
|
"useIdentityOnDevice": "Commons가 없으신가요? 이 기기의 패스키를 사용하세요",
|
|
@@ -112,6 +112,10 @@
|
|
|
112
112
|
}
|
|
113
113
|
},
|
|
114
114
|
"accountSwitcher": {
|
|
115
|
+
"sections": {
|
|
116
|
+
"yourAccounts": "As suas contas"
|
|
117
|
+
},
|
|
118
|
+
"loading": "A carregar contas...",
|
|
115
119
|
"qrHeadline": "Inicie sessão com a sua identidade Oxy",
|
|
116
120
|
"signInWithOxy": "Iniciar sessão com Oxy",
|
|
117
121
|
"useIdentityOnDevice": "Não tem o Commons? Use uma chave de acesso neste dispositivo",
|
|
@@ -112,6 +112,10 @@
|
|
|
112
112
|
}
|
|
113
113
|
},
|
|
114
114
|
"accountSwitcher": {
|
|
115
|
+
"sections": {
|
|
116
|
+
"yourAccounts": "As suas contas"
|
|
117
|
+
},
|
|
118
|
+
"loading": "A carregar contas...",
|
|
115
119
|
"qrHeadline": "Inicie sessão com a sua identidade Oxy",
|
|
116
120
|
"signInWithOxy": "Iniciar sessão com Oxy",
|
|
117
121
|
"useIdentityOnDevice": "Não tem o Commons? Use uma chave de acesso neste dispositivo",
|
|
@@ -182,7 +182,7 @@ export function OxyServicesAuthMixin(Base) {
|
|
|
182
182
|
* @internal
|
|
183
183
|
*/
|
|
184
184
|
async _doFetchServiceToken(key, secret, cacheKey, secretBuf) {
|
|
185
|
-
const response = await this.makeRequest('POST', '/auth/service-token', { apiKey: key, apiSecret: secret }, { cache: false, retry: false });
|
|
185
|
+
const response = await this.makeRequest('POST', '/auth/service-token', { apiKey: key, apiSecret: secret }, { cache: false, retry: false, skipAuth: true });
|
|
186
186
|
const expiresAt = Date.now() + response.expiresIn * 1000;
|
|
187
187
|
// Update the entry in-place so any caller that already grabbed a reference
|
|
188
188
|
// (via `_serviceTokenCache.get(...)`) sees the fresh state.
|
|
@@ -279,7 +279,7 @@ export function OxyServicesAuthMixin(Base) {
|
|
|
279
279
|
publicKey,
|
|
280
280
|
signature,
|
|
281
281
|
timestamp,
|
|
282
|
-
}, { cache: false });
|
|
282
|
+
}, { cache: false, skipAuth: true });
|
|
283
283
|
if (!res || (typeof res === 'object' && Object.keys(res).length === 0)) {
|
|
284
284
|
throw new OxyAuthenticationError('Registration failed', 'REGISTER_FAILED', 400);
|
|
285
285
|
}
|
|
@@ -303,7 +303,7 @@ export function OxyServicesAuthMixin(Base) {
|
|
|
303
303
|
try {
|
|
304
304
|
return await this.makeRequest('POST', '/auth/challenge', {
|
|
305
305
|
publicKey,
|
|
306
|
-
}, { cache: false, ...requestOptions });
|
|
306
|
+
}, { cache: false, skipAuth: true, ...requestOptions });
|
|
307
307
|
}
|
|
308
308
|
catch (error) {
|
|
309
309
|
throw this.handleError(error);
|
|
@@ -332,7 +332,7 @@ export function OxyServicesAuthMixin(Base) {
|
|
|
332
332
|
timestamp,
|
|
333
333
|
deviceName,
|
|
334
334
|
deviceFingerprint,
|
|
335
|
-
}, { cache: false, ...requestOptions });
|
|
335
|
+
}, { cache: false, skipAuth: true, ...requestOptions });
|
|
336
336
|
// Plant the freshly-minted tokens, mirroring `claimSessionByToken`.
|
|
337
337
|
// `/auth/verify` returns the first access token (and refresh token) in
|
|
338
338
|
// its body, so installing it here means callers get an authenticated
|
|
@@ -355,7 +355,7 @@ export function OxyServicesAuthMixin(Base) {
|
|
|
355
355
|
*/
|
|
356
356
|
async checkPublicKeyRegistered(publicKey) {
|
|
357
357
|
try {
|
|
358
|
-
return await this.makeRequest('GET', `/auth/check-publickey/${encodeURIComponent(publicKey)}`, undefined, { cache: false });
|
|
358
|
+
return await this.makeRequest('GET', `/auth/check-publickey/${encodeURIComponent(publicKey)}`, undefined, { cache: false, skipAuth: true });
|
|
359
359
|
}
|
|
360
360
|
catch (error) {
|
|
361
361
|
throw this.handleError(error);
|
|
@@ -366,7 +366,12 @@ export function OxyServicesAuthMixin(Base) {
|
|
|
366
366
|
*/
|
|
367
367
|
async getUserByPublicKey(publicKey) {
|
|
368
368
|
try {
|
|
369
|
-
const user = await this.makeRequest('GET', `/auth/user/${encodeURIComponent(publicKey)}`, undefined, {
|
|
369
|
+
const user = await this.makeRequest('GET', `/auth/user/${encodeURIComponent(publicKey)}`, undefined, {
|
|
370
|
+
cache: true,
|
|
371
|
+
cacheTTL: 2 * 60 * 1000,
|
|
372
|
+
// Public lookup by public key (pre-session) — skip the bearer preflight.
|
|
373
|
+
skipAuth: true,
|
|
374
|
+
});
|
|
370
375
|
return normalizeUserIdentity(user);
|
|
371
376
|
}
|
|
372
377
|
catch (error) {
|
|
@@ -437,7 +442,9 @@ export function OxyServicesAuthMixin(Base) {
|
|
|
437
442
|
const res = await this.makeRequest('POST', '/auth/session/claim', {
|
|
438
443
|
sessionToken,
|
|
439
444
|
...(options.deviceFingerprint ? { deviceFingerprint: options.deviceFingerprint } : {}),
|
|
440
|
-
},
|
|
445
|
+
},
|
|
446
|
+
// Body-authenticated device-flow claim (no bearer) — skip the preflight.
|
|
447
|
+
{ cache: false, retry: false, skipAuth: true });
|
|
441
448
|
this.setTokens(res.accessToken);
|
|
442
449
|
return res;
|
|
443
450
|
}
|
|
@@ -521,7 +528,11 @@ export function OxyServicesAuthMixin(Base) {
|
|
|
521
528
|
// QR. Reuses the platform-safe random generator.
|
|
522
529
|
const sessionToken = await SignatureService.generateChallenge();
|
|
523
530
|
const expiresAt = Date.now() + COMMONS_SIGN_IN_EXPIRY_MS;
|
|
524
|
-
const res = await this.makeRequest('POST', '/auth/session/create', { sessionToken, expiresAt, clientId: params.clientId },
|
|
531
|
+
const res = await this.makeRequest('POST', '/auth/session/create', { sessionToken, expiresAt, clientId: params.clientId },
|
|
532
|
+
// Public/pre-session (no bearer): skip the preflight so a stale
|
|
533
|
+
// near-expiry token cannot re-enter refreshAccessToken while the
|
|
534
|
+
// refresh handler is already in flight (self-await hang).
|
|
535
|
+
{ cache: false, skipAuth: true });
|
|
525
536
|
return {
|
|
526
537
|
sessionToken,
|
|
527
538
|
authorizeCode: res.authorizeCode,
|
|
@@ -545,7 +556,11 @@ export function OxyServicesAuthMixin(Base) {
|
|
|
545
556
|
*/
|
|
546
557
|
async pollCommonsSignIn(sessionToken) {
|
|
547
558
|
try {
|
|
548
|
-
return await this.makeRequest('GET', `/auth/session/status/${encodeURIComponent(sessionToken)}`, undefined,
|
|
559
|
+
return await this.makeRequest('GET', `/auth/session/status/${encodeURIComponent(sessionToken)}`, undefined,
|
|
560
|
+
// Public/pre-session (no bearer): a preflight here is wrong per se and,
|
|
561
|
+
// if ever reached while a refresh is pending, would re-enter
|
|
562
|
+
// refreshAccessToken and await the very promise it runs inside.
|
|
563
|
+
{ cache: false, retry: false, skipAuth: true });
|
|
549
564
|
}
|
|
550
565
|
catch (error) {
|
|
551
566
|
throw this.handleError(error);
|
|
@@ -563,7 +578,10 @@ export function OxyServicesAuthMixin(Base) {
|
|
|
563
578
|
*/
|
|
564
579
|
async getCommonsApprovalInfo(authorizeCode) {
|
|
565
580
|
try {
|
|
566
|
-
const raw = await this.makeRequest('GET', `/auth/session/approve-info/${encodeURIComponent(authorizeCode)}`, undefined,
|
|
581
|
+
const raw = await this.makeRequest('GET', `/auth/session/approve-info/${encodeURIComponent(authorizeCode)}`, undefined,
|
|
582
|
+
// Public (no auth required) — skip the bearer preflight (avoids the
|
|
583
|
+
// pre-session self-await class).
|
|
584
|
+
{ cache: false, skipAuth: true });
|
|
567
585
|
return {
|
|
568
586
|
application: raw.application,
|
|
569
587
|
scopes: raw.scopes,
|
|
@@ -610,7 +628,9 @@ export function OxyServicesAuthMixin(Base) {
|
|
|
610
628
|
timestamp: signed.timestamp,
|
|
611
629
|
...(params.deviceName ? { deviceName: params.deviceName } : {}),
|
|
612
630
|
...(params.deviceFingerprint ? { deviceFingerprint: params.deviceFingerprint } : {}),
|
|
613
|
-
},
|
|
631
|
+
},
|
|
632
|
+
// Key-signed, cookieless (no bearer) — skip the preflight.
|
|
633
|
+
{ cache: false, skipAuth: true });
|
|
614
634
|
}
|
|
615
635
|
catch (error) {
|
|
616
636
|
throw this.handleError(error);
|
|
@@ -624,7 +644,9 @@ export function OxyServicesAuthMixin(Base) {
|
|
|
624
644
|
*/
|
|
625
645
|
async denyCommonsSignIn(authorizeCode) {
|
|
626
646
|
try {
|
|
627
|
-
return await this.makeRequest('POST', `/auth/session/deny/${encodeURIComponent(authorizeCode)}`, undefined,
|
|
647
|
+
return await this.makeRequest('POST', `/auth/session/deny/${encodeURIComponent(authorizeCode)}`, undefined,
|
|
648
|
+
// Public (no auth required) — skip the bearer preflight.
|
|
649
|
+
{ cache: false, skipAuth: true });
|
|
628
650
|
}
|
|
629
651
|
catch (error) {
|
|
630
652
|
throw this.handleError(error);
|
|
@@ -735,7 +757,8 @@ export function OxyServicesAuthMixin(Base) {
|
|
|
735
757
|
*/
|
|
736
758
|
async checkUsernameAvailability(username) {
|
|
737
759
|
try {
|
|
738
|
-
|
|
760
|
+
// Public availability lookup (pre-session) — skip the bearer preflight.
|
|
761
|
+
return await this.makeRequest('GET', `/auth/check-username/${username}`, undefined, { cache: false, skipAuth: true });
|
|
739
762
|
}
|
|
740
763
|
catch (error) {
|
|
741
764
|
throw this.handleError(error);
|
|
@@ -746,7 +769,8 @@ export function OxyServicesAuthMixin(Base) {
|
|
|
746
769
|
*/
|
|
747
770
|
async checkEmailAvailability(email) {
|
|
748
771
|
try {
|
|
749
|
-
|
|
772
|
+
// Public availability lookup (pre-session) — skip the bearer preflight.
|
|
773
|
+
return await this.makeRequest('GET', `/auth/check-email/${email}`, undefined, { cache: false, skipAuth: true });
|
|
750
774
|
}
|
|
751
775
|
catch (error) {
|
|
752
776
|
throw this.handleError(error);
|
|
@@ -765,7 +789,7 @@ export function OxyServicesAuthMixin(Base) {
|
|
|
765
789
|
*/
|
|
766
790
|
async webauthnRegisterOptions(username) {
|
|
767
791
|
try {
|
|
768
|
-
return await this.makeRequest('POST', '/auth/webauthn/register/options', { ...(username !== undefined ? { username } : {}) }, { cache: false });
|
|
792
|
+
return await this.makeRequest('POST', '/auth/webauthn/register/options', { ...(username !== undefined ? { username } : {}) }, { cache: false, ...(username !== undefined ? { skipAuth: true } : {}) });
|
|
769
793
|
}
|
|
770
794
|
catch (error) {
|
|
771
795
|
throw this.handleError(error);
|
|
@@ -786,7 +810,7 @@ export function OxyServicesAuthMixin(Base) {
|
|
|
786
810
|
*/
|
|
787
811
|
async webauthnRegisterVerify(response, envelope = {}) {
|
|
788
812
|
try {
|
|
789
|
-
const res = await this.makeRequest('POST', '/auth/webauthn/register/verify', { response, ...envelope }, { cache: false });
|
|
813
|
+
const res = await this.makeRequest('POST', '/auth/webauthn/register/verify', { response, ...envelope }, { cache: false, ...(envelope.username !== undefined ? { skipAuth: true } : {}) });
|
|
790
814
|
if (res && typeof res === 'object') {
|
|
791
815
|
const record = res;
|
|
792
816
|
// Signup branch: mints a session (LoginSessionResult, carries
|
|
@@ -824,7 +848,9 @@ export function OxyServicesAuthMixin(Base) {
|
|
|
824
848
|
*/
|
|
825
849
|
async webauthnLoginOptions(username) {
|
|
826
850
|
try {
|
|
827
|
-
return await this.makeRequest('POST', '/auth/webauthn/login/options', { ...(username !== undefined ? { username } : {}) },
|
|
851
|
+
return await this.makeRequest('POST', '/auth/webauthn/login/options', { ...(username !== undefined ? { username } : {}) },
|
|
852
|
+
// Pre-session login ceremony — skip the bearer preflight.
|
|
853
|
+
{ cache: false, skipAuth: true });
|
|
828
854
|
}
|
|
829
855
|
catch (error) {
|
|
830
856
|
throw this.handleError(error);
|
|
@@ -840,7 +866,9 @@ export function OxyServicesAuthMixin(Base) {
|
|
|
840
866
|
*/
|
|
841
867
|
async webauthnLoginVerify(response, envelope = {}) {
|
|
842
868
|
try {
|
|
843
|
-
const res = await this.makeRequest('POST', '/auth/webauthn/login/verify', { response, ...envelope },
|
|
869
|
+
const res = await this.makeRequest('POST', '/auth/webauthn/login/verify', { response, ...envelope },
|
|
870
|
+
// Pre-session login ceremony — skip the bearer preflight.
|
|
871
|
+
{ cache: false, skipAuth: true });
|
|
844
872
|
const parsed = safeParseContract(loginResultSchema, res);
|
|
845
873
|
if (!parsed) {
|
|
846
874
|
throw new Error('auth/webauthn/login/verify returned an unexpected response shape');
|
|
@@ -867,7 +895,7 @@ export function OxyServicesAuthMixin(Base) {
|
|
|
867
895
|
clientId: params.clientId,
|
|
868
896
|
redirectUri: params.redirectUri,
|
|
869
897
|
codeVerifier: params.codeVerifier,
|
|
870
|
-
}, { cache: false });
|
|
898
|
+
}, { cache: false, skipAuth: true });
|
|
871
899
|
const payload = res.data ??
|
|
872
900
|
res;
|
|
873
901
|
if (!payload || typeof payload !== 'object') {
|
|
@@ -16,7 +16,12 @@ export function OxyServicesConnectedAppsMixin(Base) {
|
|
|
16
16
|
*/
|
|
17
17
|
async getPublicApplication(clientId) {
|
|
18
18
|
try {
|
|
19
|
-
const res = await this.makeRequest('GET', `/auth/oauth/client/${encodeURIComponent(clientId)}`, undefined, {
|
|
19
|
+
const res = await this.makeRequest('GET', `/auth/oauth/client/${encodeURIComponent(clientId)}`, undefined, {
|
|
20
|
+
cache: true,
|
|
21
|
+
cacheTTL: CACHE_TIMES.MEDIUM,
|
|
22
|
+
// Public client metadata (pre-session consent UI) — skip the bearer preflight.
|
|
23
|
+
skipAuth: true,
|
|
24
|
+
});
|
|
20
25
|
return res.application;
|
|
21
26
|
}
|
|
22
27
|
catch (error) {
|
|
@@ -41,7 +41,11 @@ export function OxyServicesDeviceBootMixin(Base) {
|
|
|
41
41
|
*/
|
|
42
42
|
async mintFromDeviceSecret(deviceId, deviceSecret) {
|
|
43
43
|
try {
|
|
44
|
-
const res = await this.makeRequest('POST', '/session/device/token', { deviceId, deviceSecret },
|
|
44
|
+
const res = await this.makeRequest('POST', '/session/device/token', { deviceId, deviceSecret },
|
|
45
|
+
// `bypassQueue`: this mint is the control-plane call the auth lane
|
|
46
|
+
// depends on — it must run even when every RequestQueue slot is parked
|
|
47
|
+
// awaiting it, or the whole client deadlocks. See RequestOptions.bypassQueue.
|
|
48
|
+
{ cache: false, skipAuth: true, retry: false, bypassQueue: true });
|
|
45
49
|
const parsed = safeParseContract(deviceTokenMintResponseSchema, res);
|
|
46
50
|
if (!parsed) {
|
|
47
51
|
throw new Error('session/device/token returned an unexpected response shape');
|
|
@@ -69,7 +73,10 @@ export function OxyServicesDeviceBootMixin(Base) {
|
|
|
69
73
|
/** Redeem a hub sync ticket for a fresh device secret (public). */
|
|
70
74
|
async redeemHubTicket(ticket, returnOrigin) {
|
|
71
75
|
try {
|
|
72
|
-
const res = await this.makeRequest('POST', '/session/device/redeem-ticket', { ticket, returnOrigin },
|
|
76
|
+
const res = await this.makeRequest('POST', '/session/device/redeem-ticket', { ticket, returnOrigin },
|
|
77
|
+
// Public device-hub sync mint (bearer-less). Same control-plane class as
|
|
78
|
+
// the device-secret mint — bypassQueue so it never waits for a slot.
|
|
79
|
+
{ cache: false, skipAuth: true, bypassQueue: true });
|
|
73
80
|
const parsed = safeParseContract(deviceHubTicketRedeemResponseSchema, res);
|
|
74
81
|
if (!parsed) {
|
|
75
82
|
throw new Error('session/device/redeem-ticket returned an unexpected response shape');
|
|
@@ -56,6 +56,8 @@ export function OxyServicesUserMixin(Base) {
|
|
|
56
56
|
return await this.makeRequest('GET', `/auth/lookup/${encodeURIComponent(username)}`, undefined, {
|
|
57
57
|
cache: true,
|
|
58
58
|
cacheTTL: 60 * 1000, // 1 minute cache
|
|
59
|
+
// Public login-flow lookup (pre-session) — skip the bearer preflight.
|
|
60
|
+
skipAuth: true,
|
|
59
61
|
});
|
|
60
62
|
}
|
|
61
63
|
/**
|
|
@@ -35,6 +35,13 @@
|
|
|
35
35
|
* password, social login, and 2FA were removed ecosystem-wide. Account
|
|
36
36
|
* creation (`signup` view) is the same two identity backends: a passkey
|
|
37
37
|
* ceremony on web, or a Commons-created identity.
|
|
38
|
+
*
|
|
39
|
+
* The controller owns NO surface PRESENTATION: whether the account dialog is
|
|
40
|
+
* mounted, visible, or dismissed is the job of the shared surface stack
|
|
41
|
+
* (`@oxyhq/services` presents the `AccountDialog` surface into `@oxyhq/bloom`'s
|
|
42
|
+
* stack). This is a headless state machine only — it exposes `setView` /
|
|
43
|
+
* `add` / `startSignup` (the view axis) and `cancelSignIn` (device-flow
|
|
44
|
+
* teardown), never an `open` / `close` / `visible`.
|
|
38
45
|
*/
|
|
39
46
|
import { logger } from '../logger/index.js';
|
|
40
47
|
import { extractErrorStatus } from '../utils/errorUtils.js';
|
|
@@ -248,11 +255,6 @@ export class AccountDialogController {
|
|
|
248
255
|
this.view = view;
|
|
249
256
|
this.emit();
|
|
250
257
|
}
|
|
251
|
-
/** Return to the account list and cancel any in-flight sign-in flow. */
|
|
252
|
-
close() {
|
|
253
|
-
this.cancelSignIn();
|
|
254
|
-
this.setView('accounts');
|
|
255
|
-
}
|
|
256
258
|
/** Switch to the "add account" view (the sign-in entry chooser). */
|
|
257
259
|
add() {
|
|
258
260
|
this.setView('add');
|