@oxy.so/core 4.5.0-oxy-one.0 → 4.5.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/README.md +1 -1
- package/dist/cjs/HttpService.js +63 -19
- package/dist/cjs/api/accounts.js +10 -3
- package/dist/cjs/api/agency.js +3 -1
- package/dist/cjs/api/apps.js +15 -4
- package/dist/cjs/api/assets.js +49 -12
- package/dist/cjs/api/auth.js +37 -11
- package/dist/cjs/api/billing.js +24 -7
- package/dist/cjs/api/civic.js +14 -4
- package/dist/cjs/api/follows.js +9 -2
- package/dist/cjs/api/identity.js +31 -9
- package/dist/cjs/api/nodes.js +3 -1
- package/dist/cjs/api/privacy.js +8 -2
- package/dist/cjs/api/session.js +15 -4
- package/dist/cjs/api/store.js +15 -5
- package/dist/cjs/api/topics.js +10 -3
- package/dist/cjs/api/users.js +16 -4
- package/dist/cjs/boot/sessionColdBoot.js +40 -13
- package/dist/cjs/constants/version.js +6 -6
- package/dist/cjs/crypto/identityMarker.js +3 -1
- package/dist/cjs/crypto/identityProof.js +6 -1
- package/dist/cjs/crypto/keyManager.js +87 -32
- package/dist/cjs/crypto/recoveryPhrase.js +2 -2
- package/dist/cjs/crypto/signatureService.js +3 -4
- package/dist/cjs/i18n/index.js +16 -3
- package/dist/cjs/i18n/locales/ar-SA.js +366 -366
- package/dist/cjs/i18n/locales/ca-ES.js +366 -366
- package/dist/cjs/i18n/locales/de-DE.js +366 -366
- package/dist/cjs/i18n/locales/en-US.js +1994 -1994
- package/dist/cjs/i18n/locales/es-ES.js +1994 -1994
- package/dist/cjs/i18n/locales/fr-FR.js +366 -366
- package/dist/cjs/i18n/locales/it-IT.js +366 -366
- package/dist/cjs/i18n/locales/ja-JP.js +366 -366
- package/dist/cjs/i18n/locales/ko-KR.js +366 -366
- package/dist/cjs/i18n/locales/pt-PT.js +366 -366
- package/dist/cjs/i18n/locales/zh-CN.js +366 -366
- package/dist/cjs/inference/OxyInferenceClient.js +12 -18
- package/dist/cjs/models/interfaces.js +11 -11
- package/dist/cjs/server/OxyServer.js +86 -28
- package/dist/cjs/server/agentAccount.js +6 -2
- package/dist/cjs/server/aliaMachineCredential.js +39 -14
- package/dist/cjs/server/auth.js +5 -4
- package/dist/cjs/server/capabilityTicket.js +5 -5
- package/dist/cjs/server/index.js +2 -1
- package/dist/cjs/server/liveCapabilityTicket.js +4 -1
- package/dist/cjs/server/middleware.js +61 -42
- package/dist/cjs/server/namespaces.js +28 -7
- package/dist/cjs/server/requesterAssertion.js +36 -30
- package/dist/cjs/server/serviceTokenLifetime.js +7 -4
- package/dist/cjs/server/traffic.js +53 -14
- package/dist/cjs/server/trafficNodeHttp.js +33 -8
- package/dist/cjs/server/workloadIdentity.client.js +4 -0
- package/dist/cjs/server/workloadIdentity.js +28 -1
- package/dist/cjs/session/SessionClient.js +54 -17
- package/dist/cjs/session/accountDelegationAccess.js +4 -6
- package/dist/cjs/session/accountDialogController.js +1 -1
- package/dist/cjs/session/authStateStore.js +18 -9
- package/dist/cjs/session/identityPin.js +6 -2
- package/dist/cjs/session/refresh.js +81 -23
- package/dist/cjs/session/sharedDeviceCredential.js +28 -15
- package/dist/cjs/shared/utils/errorUtils.js +1 -1
- package/dist/cjs/shared/utils/networkUtils.js +1 -1
- package/dist/cjs/shared/utils/themeUtils.js +1 -1
- package/dist/cjs/utils/accountCacheSweep.js +3 -1
- package/dist/cjs/utils/accountUtils.js +1 -3
- package/dist/cjs/utils/asyncUtils.js +1 -1
- package/dist/cjs/utils/authHelpers.js +2 -1
- package/dist/cjs/utils/avatarUtils.js +4 -2
- package/dist/cjs/utils/cache.js +1 -1
- package/dist/cjs/utils/cacheKey.js +3 -1
- package/dist/cjs/utils/deviceManager.js +4 -4
- package/dist/cjs/utils/errorUtils.js +6 -4
- package/dist/cjs/utils/languageUtils.js +404 -57
- package/dist/cjs/utils/profileLinks.js +1 -3
- package/dist/cjs/utils/requestUtils.js +7 -1
- package/dist/cjs/utils/userIdentity.js +1 -1
- package/dist/cjs/utils/validationUtils.js +5 -6
- package/dist/esm/HttpService.js +64 -20
- package/dist/esm/api/accounts.js +11 -4
- package/dist/esm/api/agency.js +3 -1
- package/dist/esm/api/apps.js +15 -4
- package/dist/esm/api/assets.js +49 -12
- package/dist/esm/api/auth.js +37 -11
- package/dist/esm/api/billing.js +25 -8
- package/dist/esm/api/civic.js +14 -4
- package/dist/esm/api/follows.js +9 -2
- package/dist/esm/api/identity.js +31 -9
- package/dist/esm/api/nodes.js +3 -1
- package/dist/esm/api/privacy.js +8 -2
- package/dist/esm/api/session.js +15 -4
- package/dist/esm/api/store.js +15 -5
- package/dist/esm/api/topics.js +10 -3
- package/dist/esm/api/users.js +16 -4
- package/dist/esm/boot/sessionColdBoot.js +41 -14
- package/dist/esm/constants/version.js +6 -6
- package/dist/esm/crypto/identityMarker.js +3 -1
- package/dist/esm/crypto/identityProof.js +6 -1
- package/dist/esm/crypto/internal.js +1 -1
- package/dist/esm/crypto/keyManager.js +87 -32
- package/dist/esm/crypto/recoveryPhrase.js +2 -2
- package/dist/esm/crypto/signatureService.js +3 -4
- package/dist/esm/i18n/index.js +16 -3
- package/dist/esm/i18n/locales/ar-SA.js +366 -366
- package/dist/esm/i18n/locales/ca-ES.js +366 -366
- package/dist/esm/i18n/locales/de-DE.js +366 -366
- package/dist/esm/i18n/locales/en-US.js +1994 -1994
- package/dist/esm/i18n/locales/es-ES.js +1994 -1994
- package/dist/esm/i18n/locales/fr-FR.js +366 -366
- package/dist/esm/i18n/locales/it-IT.js +366 -366
- package/dist/esm/i18n/locales/ja-JP.js +366 -366
- package/dist/esm/i18n/locales/ko-KR.js +366 -366
- package/dist/esm/i18n/locales/pt-PT.js +366 -366
- package/dist/esm/i18n/locales/zh-CN.js +366 -366
- package/dist/esm/index.js +1 -1
- package/dist/esm/inference/OxyInferenceClient.js +13 -19
- package/dist/esm/models/interfaces.js +11 -11
- package/dist/esm/server/OxyServer.js +87 -29
- package/dist/esm/server/agentAccount.js +6 -2
- package/dist/esm/server/aliaMachineCredential.js +39 -14
- package/dist/esm/server/auth.js +6 -5
- package/dist/esm/server/capabilityTicket.js +6 -6
- package/dist/esm/server/index.js +5 -5
- package/dist/esm/server/liveCapabilityTicket.js +6 -3
- package/dist/esm/server/middleware.js +62 -43
- package/dist/esm/server/namespaces.js +31 -10
- package/dist/esm/server/requesterAssertion.js +36 -30
- package/dist/esm/server/serviceTokenLifetime.js +7 -4
- package/dist/esm/server/traffic.js +55 -16
- package/dist/esm/server/trafficNodeHttp.js +34 -9
- package/dist/esm/server/userInvalidation.js +1 -1
- package/dist/esm/server/workloadIdentity.client.js +3 -0
- package/dist/esm/server/workloadIdentity.js +27 -1
- package/dist/esm/session/SessionClient.js +54 -17
- package/dist/esm/session/accountDelegationAccess.js +5 -7
- package/dist/esm/session/accountDialogController.js +1 -1
- package/dist/esm/session/authStateStore.js +18 -9
- package/dist/esm/session/identityPin.js +6 -2
- package/dist/esm/session/refresh.js +82 -24
- package/dist/esm/session/sharedDeviceCredential.js +28 -15
- package/dist/esm/shared/utils/errorUtils.js +1 -1
- package/dist/esm/shared/utils/networkUtils.js +1 -1
- package/dist/esm/shared/utils/themeUtils.js +1 -1
- package/dist/esm/utils/accountCacheSweep.js +3 -1
- package/dist/esm/utils/accountUtils.js +1 -3
- package/dist/esm/utils/asyncUtils.js +1 -1
- package/dist/esm/utils/authHelpers.js +2 -1
- package/dist/esm/utils/avatarUtils.js +4 -2
- package/dist/esm/utils/cache.js +1 -1
- package/dist/esm/utils/cacheKey.js +3 -1
- package/dist/esm/utils/deviceManager.js +4 -4
- package/dist/esm/utils/errorUtils.js +6 -4
- package/dist/esm/utils/languageUtils.js +404 -57
- package/dist/esm/utils/profileLinks.js +1 -3
- package/dist/esm/utils/requestUtils.js +7 -1
- package/dist/esm/utils/userIdentity.js +1 -1
- package/dist/esm/utils/validationUtils.js +5 -6
- package/dist/types/HttpService.d.ts +1 -1
- package/dist/types/api/accounts.d.ts +1 -1
- package/dist/types/api/apps.d.ts +4 -4
- package/dist/types/api/assets.d.ts +2 -0
- package/dist/types/api/auth.d.ts +8 -3
- package/dist/types/crypto/internal.d.ts +1 -1
- package/dist/types/index.d.ts +4 -4
- package/dist/types/server/index.d.ts +6 -6
- package/dist/types/server/requesterAssertion.d.ts +2 -2
- package/dist/types/server/workloadIdentity.client.d.ts +5 -1
- package/dist/types/server/workloadIdentity.d.ts +26 -0
- package/dist/types/session/accountDelegationAccess.d.ts +1 -1
- package/dist/types/session/index.d.ts +1 -1
- package/dist/types/utils/userIdentity.d.ts +1 -1
- package/dist/types/utils/validationUtils.d.ts +4 -5
- package/package.json +2 -3
- package/src/HttpService.ts +183 -53
- package/src/OxyServices.errors.ts +7 -3
- package/src/OxyServices.ts +6 -2
- package/src/api/accounts.ts +76 -26
- package/src/api/agency.ts +24 -9
- package/src/api/appData.ts +12 -2
- package/src/api/apps.ts +81 -31
- package/src/api/assets.ts +122 -40
- package/src/api/auth.ts +154 -79
- package/src/api/billing.ts +112 -65
- package/src/api/civic.ts +61 -19
- package/src/api/contacts.ts +4 -1
- package/src/api/devices.ts +54 -21
- package/src/api/follows.ts +88 -31
- package/src/api/identity.ts +101 -33
- package/src/api/linkedAccounts.ts +26 -8
- package/src/api/nodes.ts +18 -6
- package/src/api/notifications.ts +26 -6
- package/src/api/privacy.ts +42 -8
- package/src/api/reputation.ts +18 -7
- package/src/api/session.ts +23 -5
- package/src/api/store.ts +81 -31
- package/src/api/topics.ts +18 -6
- package/src/api/users.ts +98 -35
- package/src/boot/sessionColdBoot.ts +60 -19
- package/src/civic/payloads.ts +1 -4
- package/src/client/context.ts +6 -1
- package/src/constants/version.ts +7 -6
- package/src/crypto/aead.ts +1 -5
- package/src/crypto/ecdh.ts +1 -4
- package/src/crypto/identityDerivations.ts +5 -1
- package/src/crypto/identityMarker.ts +3 -1
- package/src/crypto/identityProof.ts +6 -1
- package/src/crypto/index.ts +11 -11
- package/src/crypto/internal.ts +6 -1
- package/src/crypto/keyManager.ts +348 -98
- package/src/crypto/recoveryPhrase.ts +14 -9
- package/src/crypto/registrationPow.ts +1 -1
- package/src/crypto/signatureService.ts +14 -6
- package/src/i18n/accountCategoryLabels.ts +1 -4
- package/src/i18n/accountRoleLabels.ts +1 -4
- package/src/i18n/index.ts +25 -7
- package/src/i18n/locales/ar-SA.ts +375 -366
- package/src/i18n/locales/ca-ES.ts +382 -366
- package/src/i18n/locales/de-DE.ts +387 -366
- package/src/i18n/locales/en-US.ts +2034 -1994
- package/src/i18n/locales/es-ES.ts +2043 -1994
- package/src/i18n/locales/fr-FR.ts +387 -366
- package/src/i18n/locales/it-IT.ts +380 -366
- package/src/i18n/locales/ja-JP.ts +380 -366
- package/src/i18n/locales/ko-KR.ts +377 -366
- package/src/i18n/locales/pt-PT.ts +383 -366
- package/src/i18n/locales/zh-CN.ts +373 -366
- package/src/i18n/trustTierLabels.ts +1 -4
- package/src/index.ts +371 -349
- package/src/inference/OxyInferenceClient.ts +784 -780
- package/src/models/interfaces.ts +30 -27
- package/src/server/OxyServer.ts +227 -68
- package/src/server/agentAccount.ts +8 -2
- package/src/server/aliaMachineCredential.ts +57 -16
- package/src/server/auth.ts +9 -5
- package/src/server/capabilityTicket.ts +30 -21
- package/src/server/index.ts +29 -6
- package/src/server/liveCapabilityTicket.ts +31 -9
- package/src/server/middleware.ts +212 -121
- package/src/server/namespaces.ts +247 -94
- package/src/server/rateLimit.ts +2 -4
- package/src/server/requesterAssertion.ts +93 -54
- package/src/server/serviceTokenLifetime.ts +9 -4
- package/src/server/traffic.ts +117 -23
- package/src/server/trafficNodeHttp.ts +61 -14
- package/src/server/userInvalidation.ts +1 -4
- package/src/server/workloadIdentity.client.ts +12 -1
- package/src/server/workloadIdentity.ts +52 -5
- package/src/session/SessionClient.ts +170 -49
- package/src/session/accountDelegationAccess.ts +24 -31
- package/src/session/accountDialogController.ts +59 -14
- package/src/session/accountSwitchTargets.ts +10 -15
- package/src/session/authStateStore.ts +121 -81
- package/src/session/deviceDirectory.ts +1 -3
- package/src/session/identityPin.ts +10 -11
- package/src/session/identitySession.ts +3 -1
- package/src/session/index.ts +87 -82
- package/src/session/refresh.ts +138 -44
- package/src/session/sessionClientHost.ts +1 -3
- package/src/session/sharedDeviceCredential.ts +35 -14
- package/src/session/socketLoader.ts +9 -2
- package/src/shared/utils/errorUtils.ts +5 -2
- package/src/shared/utils/networkUtils.ts +5 -8
- package/src/shared/utils/themeUtils.ts +2 -6
- package/src/types/buffer.d.ts +66 -21
- package/src/types/expo-secure-store.d.ts +5 -1
- package/src/utils/accountCacheSweep.ts +4 -5
- package/src/utils/accountUtils.ts +107 -108
- package/src/utils/apiUtils.ts +3 -3
- package/src/utils/asyncUtils.ts +2 -2
- package/src/utils/authHelpers.ts +10 -5
- package/src/utils/avatarUtils.ts +11 -6
- package/src/utils/cache.ts +9 -10
- package/src/utils/cacheKey.ts +5 -1
- package/src/utils/coldBoot.ts +1 -3
- package/src/utils/commonsDelivery.ts +1 -4
- package/src/utils/deviceManager.ts +15 -14
- package/src/utils/errorUtils.ts +68 -86
- package/src/utils/languageUtils.ts +407 -58
- package/src/utils/oauthPkce.ts +1 -4
- package/src/utils/platform.ts +0 -1
- package/src/utils/profileLinks.ts +2 -5
- package/src/utils/requestUtils.ts +18 -14
- package/src/utils/sessionUtils.ts +34 -33
- package/src/utils/userHandle.ts +3 -1
- package/src/utils/userIdentity.ts +1 -1
- package/src/utils/validationUtils.ts +11 -9
package/src/api/auth.ts
CHANGED
|
@@ -57,7 +57,8 @@ import { isAndroid } from '../utils/platform';
|
|
|
57
57
|
// use: an app that never signs anything must not ship secp256k1.
|
|
58
58
|
const loadKeyManager = async () => (await import('../crypto/internal')).KeyManager;
|
|
59
59
|
const loadSignatureService = async () => (await import('../crypto/internal')).SignatureService;
|
|
60
|
-
const loadCommonsBridge = async () =>
|
|
60
|
+
const loadCommonsBridge = async () =>
|
|
61
|
+
(await import('../crypto/internal')).loadCommonsIdentityBridge();
|
|
61
62
|
|
|
62
63
|
/**
|
|
63
64
|
* Default lifetime of a "Sign in with Oxy" device-flow session / authorize code.
|
|
@@ -454,7 +455,6 @@ interface CommonsSessionCreateResponse {
|
|
|
454
455
|
sessionToken?: string;
|
|
455
456
|
}
|
|
456
457
|
|
|
457
|
-
|
|
458
458
|
/** The device-session fields a sign-in may carry. */
|
|
459
459
|
export interface SignInDeviceOptions {
|
|
460
460
|
deviceName?: string;
|
|
@@ -474,7 +474,10 @@ export interface ClaimedSession {
|
|
|
474
474
|
}
|
|
475
475
|
|
|
476
476
|
/** The body fields a session-ending call sends: the options, plus the device proof. */
|
|
477
|
-
async function signInEnvelope(
|
|
477
|
+
async function signInEnvelope(
|
|
478
|
+
ctx: OxyContext,
|
|
479
|
+
options: SignInDeviceOptions = {},
|
|
480
|
+
): Promise<Record<string, unknown>> {
|
|
478
481
|
const { device: explicit, deviceName, deviceFingerprint } = options;
|
|
479
482
|
const device = explicit === undefined ? await ctx.oxy.session.readDeviceProof() : explicit;
|
|
480
483
|
return {
|
|
@@ -508,7 +511,9 @@ export class AuthEmailApi {
|
|
|
508
511
|
* (`purpose: 'signup'`). The answer is the same whether or not the address
|
|
509
512
|
* already has an account; nothing is revealed about who has one.
|
|
510
513
|
*/
|
|
511
|
-
async startVerification(
|
|
514
|
+
async startVerification(
|
|
515
|
+
request: EmailVerificationStartRequest,
|
|
516
|
+
): Promise<EmailVerificationStartResponse> {
|
|
512
517
|
const res = await this.ctx.request<unknown>('POST', '/auth/email/verify/start', request, {
|
|
513
518
|
cache: false,
|
|
514
519
|
skipAuth: true,
|
|
@@ -523,7 +528,10 @@ export class AuthEmailApi {
|
|
|
523
528
|
* short-lived one-use ticket, which a sign-up passes (with the email) to
|
|
524
529
|
* {@link AuthApi.signUp}.
|
|
525
530
|
*/
|
|
526
|
-
async confirmVerification(
|
|
531
|
+
async confirmVerification(
|
|
532
|
+
verificationId: string,
|
|
533
|
+
code: string,
|
|
534
|
+
): Promise<EmailVerificationConfirmResponse> {
|
|
527
535
|
const res = await this.ctx.request<unknown>(
|
|
528
536
|
'POST',
|
|
529
537
|
'/auth/email/verify/confirm',
|
|
@@ -540,8 +548,12 @@ export class AuthEmailApi {
|
|
|
540
548
|
* answer is the same whether or not the account exists. Keep
|
|
541
549
|
* `requestSecret` in memory only.
|
|
542
550
|
*/
|
|
543
|
-
async start(
|
|
544
|
-
|
|
551
|
+
async start(
|
|
552
|
+
identifier: string,
|
|
553
|
+
options: { device?: DeviceProof | null } = {},
|
|
554
|
+
): Promise<EmailSignInStartResponse> {
|
|
555
|
+
const device =
|
|
556
|
+
options.device === undefined ? await this.ctx.oxy.session.readDeviceProof() : options.device;
|
|
545
557
|
const res = await this.ctx.request<unknown>(
|
|
546
558
|
'POST',
|
|
547
559
|
'/auth/signin/email/start',
|
|
@@ -609,14 +621,15 @@ export class AuthEmailApi {
|
|
|
609
621
|
if (!parsed) throw new Error('auth/signin/email/link returned an unexpected response shape');
|
|
610
622
|
return parsed;
|
|
611
623
|
}
|
|
612
|
-
|
|
613
624
|
}
|
|
614
625
|
|
|
615
626
|
/** `oxy.auth.password` — password sign-in and setting the password. */
|
|
616
627
|
export class AuthPasswordApi {
|
|
617
628
|
constructor(private readonly ctx: OxyContext) {}
|
|
618
629
|
|
|
619
|
-
async signIn(
|
|
630
|
+
async signIn(
|
|
631
|
+
request: { identifier: string; password: string } & SignInDeviceOptions,
|
|
632
|
+
): Promise<SignInStepResult> {
|
|
620
633
|
const { identifier, password, ...options } = request;
|
|
621
634
|
const res = await this.ctx.request<unknown>(
|
|
622
635
|
'POST',
|
|
@@ -627,10 +640,15 @@ export class AuthPasswordApi {
|
|
|
627
640
|
return signInStep(this.ctx, res, 'auth/signin/password');
|
|
628
641
|
}
|
|
629
642
|
|
|
630
|
-
async set(request: {
|
|
631
|
-
|
|
643
|
+
async set(request: {
|
|
644
|
+
newPassword: string;
|
|
645
|
+
reauth: ReauthProof;
|
|
646
|
+
revokeOtherSessions?: boolean;
|
|
647
|
+
}): Promise<{ success: true }> {
|
|
648
|
+
return this.ctx.request<{ success: true }>('PUT', '/users/me/password', request, {
|
|
649
|
+
cache: false,
|
|
650
|
+
});
|
|
632
651
|
}
|
|
633
|
-
|
|
634
652
|
}
|
|
635
653
|
|
|
636
654
|
/** `oxy.auth.totp` — the account’s authenticator app. */
|
|
@@ -638,30 +656,47 @@ export class AuthTotpApi {
|
|
|
638
656
|
constructor(private readonly ctx: OxyContext) {}
|
|
639
657
|
|
|
640
658
|
async enroll(): Promise<TotpEnrollResponse> {
|
|
641
|
-
const res = await this.ctx.request<unknown>('POST', '/users/me/totp/enroll', undefined, {
|
|
659
|
+
const res = await this.ctx.request<unknown>('POST', '/users/me/totp/enroll', undefined, {
|
|
660
|
+
cache: false,
|
|
661
|
+
});
|
|
642
662
|
const parsed = safeParseContract(totpEnrollResponseSchema, res);
|
|
643
663
|
if (!parsed) throw new Error('users/me/totp/enroll returned an unexpected response shape');
|
|
644
664
|
return parsed;
|
|
645
665
|
}
|
|
646
666
|
|
|
647
667
|
async confirm(code: string, reauth: ReauthProof): Promise<string[]> {
|
|
648
|
-
const res = await this.ctx.request<unknown>(
|
|
668
|
+
const res = await this.ctx.request<unknown>(
|
|
669
|
+
'POST',
|
|
670
|
+
'/users/me/totp/confirm',
|
|
671
|
+
{ code, reauth },
|
|
672
|
+
{ cache: false },
|
|
673
|
+
);
|
|
649
674
|
const parsed = safeParseContract(totpBackupCodesResponseSchema, res);
|
|
650
675
|
if (!parsed) throw new Error('users/me/totp/confirm returned an unexpected response shape');
|
|
651
676
|
return parsed.backupCodes;
|
|
652
677
|
}
|
|
653
678
|
|
|
654
679
|
async disable(reauth: ReauthProof): Promise<{ success: true }> {
|
|
655
|
-
return this.ctx.request<{ success: true }>(
|
|
680
|
+
return this.ctx.request<{ success: true }>(
|
|
681
|
+
'POST',
|
|
682
|
+
'/users/me/totp/disable',
|
|
683
|
+
{ reauth },
|
|
684
|
+
{ cache: false },
|
|
685
|
+
);
|
|
656
686
|
}
|
|
657
687
|
|
|
658
688
|
async regenerateBackupCodes(reauth: ReauthProof): Promise<string[]> {
|
|
659
|
-
const res = await this.ctx.request<unknown>(
|
|
689
|
+
const res = await this.ctx.request<unknown>(
|
|
690
|
+
'POST',
|
|
691
|
+
'/users/me/totp/backup-codes',
|
|
692
|
+
{ reauth },
|
|
693
|
+
{ cache: false },
|
|
694
|
+
);
|
|
660
695
|
const parsed = safeParseContract(totpBackupCodesResponseSchema, res);
|
|
661
|
-
if (!parsed)
|
|
696
|
+
if (!parsed)
|
|
697
|
+
throw new Error('users/me/totp/backup-codes returned an unexpected response shape');
|
|
662
698
|
return parsed.backupCodes;
|
|
663
699
|
}
|
|
664
|
-
|
|
665
700
|
}
|
|
666
701
|
|
|
667
702
|
/** `oxy.auth.oauth` — a relying party’s OAuth authorization-code exchange. */
|
|
@@ -699,12 +734,15 @@ export class AuthOAuthApi {
|
|
|
699
734
|
* session that looks alive and cannot refresh.
|
|
700
735
|
*/
|
|
701
736
|
/** `plantTokens: false` defers bearer installation to a validated provider commit. */
|
|
702
|
-
async exchangeCode(
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
737
|
+
async exchangeCode(
|
|
738
|
+
params: {
|
|
739
|
+
code: string;
|
|
740
|
+
clientId: string;
|
|
741
|
+
redirectUri: string;
|
|
742
|
+
codeVerifier: string;
|
|
743
|
+
},
|
|
744
|
+
options: { plantTokens?: boolean } = {},
|
|
745
|
+
): Promise<OAuthTokenExchangeResult> {
|
|
708
746
|
const form = new URLSearchParams({
|
|
709
747
|
grant_type: 'authorization_code',
|
|
710
748
|
code: params.code,
|
|
@@ -712,12 +750,10 @@ export class AuthOAuthApi {
|
|
|
712
750
|
client_id: params.clientId,
|
|
713
751
|
code_verifier: params.codeVerifier,
|
|
714
752
|
});
|
|
715
|
-
const res = await this.ctx.request<unknown>(
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
{ cache: false, skipAuth: true },
|
|
720
|
-
);
|
|
753
|
+
const res = await this.ctx.request<unknown>('POST', '/auth/oauth/token', form, {
|
|
754
|
+
cache: false,
|
|
755
|
+
skipAuth: true,
|
|
756
|
+
});
|
|
721
757
|
if (!res || typeof res !== 'object') {
|
|
722
758
|
throw new Error('auth/oauth/token returned an unexpected response shape');
|
|
723
759
|
}
|
|
@@ -773,12 +809,9 @@ export class AuthOAuthApi {
|
|
|
773
809
|
* The response is a flat JSON document — no `{ data }` wrapper.
|
|
774
810
|
*/
|
|
775
811
|
async userInfo(): Promise<OAuthUserInfoResponse> {
|
|
776
|
-
const res = await this.ctx.request<unknown>(
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
undefined,
|
|
780
|
-
{ cache: false },
|
|
781
|
-
);
|
|
812
|
+
const res = await this.ctx.request<unknown>('GET', '/auth/oauth/userinfo', undefined, {
|
|
813
|
+
cache: false,
|
|
814
|
+
});
|
|
782
815
|
if (!res || typeof res !== 'object') {
|
|
783
816
|
throw new Error('auth/oauth/userinfo returned an unexpected response shape');
|
|
784
817
|
}
|
|
@@ -796,7 +829,6 @@ export class AuthOAuthApi {
|
|
|
796
829
|
...(typeof record.picture === 'string' ? { picture: record.picture } : {}),
|
|
797
830
|
};
|
|
798
831
|
}
|
|
799
|
-
|
|
800
832
|
}
|
|
801
833
|
|
|
802
834
|
/**
|
|
@@ -899,7 +931,7 @@ export class AuthCommonsApi {
|
|
|
899
931
|
// Public/pre-session (no bearer): a preflight here is wrong per se and,
|
|
900
932
|
// if ever reached while a refresh is pending, would re-enter
|
|
901
933
|
// refreshAccessToken and await the very promise it runs inside.
|
|
902
|
-
{ cache: false, retry: false, skipAuth: true }
|
|
934
|
+
{ cache: false, retry: false, skipAuth: true },
|
|
903
935
|
);
|
|
904
936
|
|
|
905
937
|
if (res === null || typeof res !== 'object') {
|
|
@@ -1070,7 +1102,7 @@ export class AuthCommonsApi {
|
|
|
1070
1102
|
undefined,
|
|
1071
1103
|
// Public (no auth required) — skip the bearer preflight (avoids the
|
|
1072
1104
|
// pre-session self-await class).
|
|
1073
|
-
{ cache: false, skipAuth: true }
|
|
1105
|
+
{ cache: false, skipAuth: true },
|
|
1074
1106
|
);
|
|
1075
1107
|
return {
|
|
1076
1108
|
application: raw.application,
|
|
@@ -1136,7 +1168,7 @@ export class AuthCommonsApi {
|
|
|
1136
1168
|
...(params.deviceFingerprint ? { deviceFingerprint: params.deviceFingerprint } : {}),
|
|
1137
1169
|
},
|
|
1138
1170
|
// Key-signed, cookieless (no bearer) — skip the preflight.
|
|
1139
|
-
{ cache: false, skipAuth: true }
|
|
1171
|
+
{ cache: false, skipAuth: true },
|
|
1140
1172
|
);
|
|
1141
1173
|
}
|
|
1142
1174
|
|
|
@@ -1160,10 +1192,9 @@ export class AuthCommonsApi {
|
|
|
1160
1192
|
`/auth/session/deny/${encodeURIComponent(authorizeCode)}`,
|
|
1161
1193
|
reason ? { reason } : undefined,
|
|
1162
1194
|
// Public (no auth required) — skip the bearer preflight.
|
|
1163
|
-
{ cache: false, skipAuth: true }
|
|
1195
|
+
{ cache: false, skipAuth: true },
|
|
1164
1196
|
);
|
|
1165
1197
|
}
|
|
1166
|
-
|
|
1167
1198
|
}
|
|
1168
1199
|
|
|
1169
1200
|
/** Bot entry uses caller-owned keys and the normal account session lane. */
|
|
@@ -1172,15 +1203,19 @@ export class AuthAgentApi {
|
|
|
1172
1203
|
|
|
1173
1204
|
async requestChallenge(publicKey: string): Promise<AgentProofClaims> {
|
|
1174
1205
|
const body = agentChallengeRequestSchema.parse({ publicKey });
|
|
1175
|
-
const response = await this.ctx.request<unknown>('POST', '/auth/agent/challenge', body,
|
|
1176
|
-
|
|
1206
|
+
const response = await this.ctx.request<unknown>('POST', '/auth/agent/challenge', body, {
|
|
1207
|
+
cache: false,
|
|
1208
|
+
skipAuth: true,
|
|
1209
|
+
});
|
|
1177
1210
|
return agentProofClaimsSchema.parse(response);
|
|
1178
1211
|
}
|
|
1179
1212
|
|
|
1180
1213
|
async verify(publicKey: string, proof: AgentSignature): Promise<LoginResult> {
|
|
1181
1214
|
const body = agentVerifyRequestSchema.parse({ publicKey, ...proof });
|
|
1182
|
-
const response = await this.ctx.request<unknown>('POST', '/auth/agent/verify', body,
|
|
1183
|
-
|
|
1215
|
+
const response = await this.ctx.request<unknown>('POST', '/auth/agent/verify', body, {
|
|
1216
|
+
cache: false,
|
|
1217
|
+
skipAuth: true,
|
|
1218
|
+
});
|
|
1184
1219
|
return plantSession(this.ctx, response, 'auth/agent/verify');
|
|
1185
1220
|
}
|
|
1186
1221
|
}
|
|
@@ -1208,17 +1243,23 @@ export class AuthApi {
|
|
|
1208
1243
|
}
|
|
1209
1244
|
|
|
1210
1245
|
/**
|
|
1211
|
-
* Register a new
|
|
1212
|
-
*
|
|
1213
|
-
*
|
|
1246
|
+
* Register a new account for a public key, together with its username.
|
|
1247
|
+
*
|
|
1248
|
+
* The username is required: the server writes it in the same insert as the
|
|
1249
|
+
* key, so an account never exists without one. A taken username is a 409
|
|
1250
|
+
* (`Username already taken`), as is a key that is already registered
|
|
1251
|
+
* (`Identity already registered`).
|
|
1252
|
+
*
|
|
1214
1253
|
* @param publicKey - The user's ECDSA public key (hex)
|
|
1215
1254
|
* @param signature - Signature of the registration request
|
|
1216
1255
|
* @param timestamp - Timestamp when the signature was created
|
|
1256
|
+
* @param username - The account's username
|
|
1217
1257
|
*/
|
|
1218
1258
|
async registerKey(
|
|
1219
1259
|
publicKey: string,
|
|
1220
1260
|
signature: string,
|
|
1221
|
-
timestamp: number
|
|
1261
|
+
timestamp: number,
|
|
1262
|
+
username: string,
|
|
1222
1263
|
): Promise<{ message: string; user: User }> {
|
|
1223
1264
|
// Advisory for now (server soft-enforces — see
|
|
1224
1265
|
// `SessionController.register`), but solved unconditionally so every
|
|
@@ -1226,12 +1267,18 @@ export class AuthApi {
|
|
|
1226
1267
|
const { solveRegistrationPow } = await import('../crypto/internal');
|
|
1227
1268
|
const powNonce = await solveRegistrationPow(publicKey, timestamp);
|
|
1228
1269
|
|
|
1229
|
-
const res = await this.ctx.request<{ message: string; user: User }>(
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
|
|
1270
|
+
const res = await this.ctx.request<{ message: string; user: User }>(
|
|
1271
|
+
'POST',
|
|
1272
|
+
'/auth/register',
|
|
1273
|
+
{
|
|
1274
|
+
publicKey,
|
|
1275
|
+
signature,
|
|
1276
|
+
timestamp,
|
|
1277
|
+
username,
|
|
1278
|
+
powNonce,
|
|
1279
|
+
},
|
|
1280
|
+
{ cache: false, skipAuth: true },
|
|
1281
|
+
);
|
|
1235
1282
|
|
|
1236
1283
|
if (!res || (typeof res === 'object' && Object.keys(res).length === 0)) {
|
|
1237
1284
|
throw new OxyAuthenticationError('Registration failed', 'REGISTER_FAILED', 400);
|
|
@@ -1254,14 +1301,19 @@ export class AuthApi {
|
|
|
1254
1301
|
publicKey: string,
|
|
1255
1302
|
requestOptions?: { retry?: boolean; timeout?: number },
|
|
1256
1303
|
): Promise<ChallengeResponse> {
|
|
1257
|
-
return this.ctx.request<ChallengeResponse>(
|
|
1258
|
-
|
|
1259
|
-
|
|
1304
|
+
return this.ctx.request<ChallengeResponse>(
|
|
1305
|
+
'POST',
|
|
1306
|
+
'/auth/challenge',
|
|
1307
|
+
{
|
|
1308
|
+
publicKey,
|
|
1309
|
+
},
|
|
1310
|
+
{ cache: false, skipAuth: true, ...requestOptions },
|
|
1311
|
+
);
|
|
1260
1312
|
}
|
|
1261
1313
|
|
|
1262
1314
|
/**
|
|
1263
1315
|
* Verify a signed challenge and create a session
|
|
1264
|
-
*
|
|
1316
|
+
*
|
|
1265
1317
|
* @param publicKey - The user's public key
|
|
1266
1318
|
* @param challenge - The challenge string from requestChallenge
|
|
1267
1319
|
* @param signature - Signature of the auth message
|
|
@@ -1287,14 +1339,19 @@ export class AuthApi {
|
|
|
1287
1339
|
requestOptions?: { retry?: boolean; timeout?: number },
|
|
1288
1340
|
options: { plantTokens?: boolean } = {},
|
|
1289
1341
|
): Promise<SessionLoginResponse> {
|
|
1290
|
-
const res = await this.ctx.request<SessionLoginResponse>(
|
|
1291
|
-
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1342
|
+
const res = await this.ctx.request<SessionLoginResponse>(
|
|
1343
|
+
'POST',
|
|
1344
|
+
'/auth/verify',
|
|
1345
|
+
{
|
|
1346
|
+
publicKey,
|
|
1347
|
+
challenge,
|
|
1348
|
+
signature,
|
|
1349
|
+
timestamp,
|
|
1350
|
+
deviceName,
|
|
1351
|
+
deviceFingerprint,
|
|
1352
|
+
},
|
|
1353
|
+
{ cache: false, skipAuth: true, ...requestOptions },
|
|
1354
|
+
);
|
|
1298
1355
|
|
|
1299
1356
|
// Plant the freshly-minted tokens, mirroring `auth.claimSession`.
|
|
1300
1357
|
// `/auth/verify` returns the first access token (and refresh token) in
|
|
@@ -1319,7 +1376,7 @@ export class AuthApi {
|
|
|
1319
1376
|
'GET',
|
|
1320
1377
|
`/auth/check-publickey/${encodeURIComponent(publicKey)}`,
|
|
1321
1378
|
undefined,
|
|
1322
|
-
{ cache: false, skipAuth: true }
|
|
1379
|
+
{ cache: false, skipAuth: true },
|
|
1323
1380
|
);
|
|
1324
1381
|
}
|
|
1325
1382
|
|
|
@@ -1349,11 +1406,16 @@ export class AuthApi {
|
|
|
1349
1406
|
*/
|
|
1350
1407
|
async claimSession(
|
|
1351
1408
|
sessionToken: string,
|
|
1352
|
-
options: {
|
|
1409
|
+
options: {
|
|
1410
|
+
deviceFingerprint?: string;
|
|
1411
|
+
plantTokens?: boolean;
|
|
1412
|
+
device?: DeviceProof | null;
|
|
1413
|
+
} = {},
|
|
1353
1414
|
): Promise<ClaimedSession> {
|
|
1354
1415
|
// The device this client holds, so an official app's claim joins it
|
|
1355
1416
|
// (ADR 0029 D2). `null` opts out explicitly.
|
|
1356
|
-
const device =
|
|
1417
|
+
const device =
|
|
1418
|
+
options.device === undefined ? await this.ctx.oxy.session.readDeviceProof() : options.device;
|
|
1357
1419
|
const res = await this.ctx.request<ClaimedSession>(
|
|
1358
1420
|
'POST',
|
|
1359
1421
|
'/auth/session/claim',
|
|
@@ -1363,7 +1425,7 @@ export class AuthApi {
|
|
|
1363
1425
|
...(device ? { device } : {}),
|
|
1364
1426
|
},
|
|
1365
1427
|
// Body-authenticated device-flow claim (no bearer) — skip the preflight.
|
|
1366
|
-
{ cache: false, retry: false, skipAuth: true }
|
|
1428
|
+
{ cache: false, retry: false, skipAuth: true },
|
|
1367
1429
|
);
|
|
1368
1430
|
|
|
1369
1431
|
if (options.plantTokens !== false) {
|
|
@@ -1402,7 +1464,7 @@ export class AuthApi {
|
|
|
1402
1464
|
deviceFingerprint?: string;
|
|
1403
1465
|
requestOptions?: { retry?: boolean; timeout?: number };
|
|
1404
1466
|
plantTokens?: boolean;
|
|
1405
|
-
} = {}
|
|
1467
|
+
} = {},
|
|
1406
1468
|
): Promise<SessionLoginResponse | null> {
|
|
1407
1469
|
if (isAndroid()) {
|
|
1408
1470
|
const bridge = await loadCommonsBridge();
|
|
@@ -1458,7 +1520,10 @@ export class AuthApi {
|
|
|
1458
1520
|
*/
|
|
1459
1521
|
async checkUsername(username: string): Promise<{ available: boolean; message: string }> {
|
|
1460
1522
|
// Public availability lookup (pre-session) — skip the bearer preflight.
|
|
1461
|
-
return this.ctx.request('GET', `/auth/check-username/${username}`, undefined, {
|
|
1523
|
+
return this.ctx.request('GET', `/auth/check-username/${username}`, undefined, {
|
|
1524
|
+
cache: false,
|
|
1525
|
+
skipAuth: true,
|
|
1526
|
+
});
|
|
1462
1527
|
}
|
|
1463
1528
|
|
|
1464
1529
|
/**
|
|
@@ -1466,7 +1531,9 @@ export class AuthApi {
|
|
|
1466
1531
|
* challenge → the session. Send the same device proof the first factor did
|
|
1467
1532
|
* (the default does).
|
|
1468
1533
|
*/
|
|
1469
|
-
async completeSecondFactor(
|
|
1534
|
+
async completeSecondFactor(
|
|
1535
|
+
request: { challengeId: string; code: string } & SignInDeviceOptions,
|
|
1536
|
+
): Promise<LoginResult> {
|
|
1470
1537
|
const { challengeId, code, ...options } = request;
|
|
1471
1538
|
const res = await this.ctx.request<unknown>(
|
|
1472
1539
|
'POST',
|
|
@@ -1477,7 +1544,9 @@ export class AuthApi {
|
|
|
1477
1544
|
return plantSession(this.ctx, res, 'auth/signin/second-factor');
|
|
1478
1545
|
}
|
|
1479
1546
|
|
|
1480
|
-
async signUp(
|
|
1547
|
+
async signUp(
|
|
1548
|
+
request: { username: string; email: string; emailTicket: string } & SignInDeviceOptions,
|
|
1549
|
+
): Promise<LoginResult> {
|
|
1481
1550
|
const { username, email, emailTicket, ...options } = request;
|
|
1482
1551
|
const res = await this.ctx.request<unknown>(
|
|
1483
1552
|
'POST',
|
|
@@ -1489,7 +1558,9 @@ export class AuthApi {
|
|
|
1489
1558
|
}
|
|
1490
1559
|
|
|
1491
1560
|
async methods(): Promise<SignInMethods> {
|
|
1492
|
-
const res = await this.ctx.request<unknown>('GET', '/users/me/sign-in-methods', undefined, {
|
|
1561
|
+
const res = await this.ctx.request<unknown>('GET', '/users/me/sign-in-methods', undefined, {
|
|
1562
|
+
cache: false,
|
|
1563
|
+
});
|
|
1493
1564
|
const parsed = safeParseContract(signInMethodsSchema, res);
|
|
1494
1565
|
if (!parsed) throw new Error('users/me/sign-in-methods returned an unexpected response shape');
|
|
1495
1566
|
return parsed;
|
|
@@ -1502,10 +1573,14 @@ export class AuthApi {
|
|
|
1502
1573
|
* names it.
|
|
1503
1574
|
*/
|
|
1504
1575
|
async requestReauthCode(action: ReauthAction): Promise<EmailVerificationStartResponse> {
|
|
1505
|
-
const res = await this.ctx.request<unknown>(
|
|
1576
|
+
const res = await this.ctx.request<unknown>(
|
|
1577
|
+
'POST',
|
|
1578
|
+
'/users/me/reauth/email',
|
|
1579
|
+
{ action },
|
|
1580
|
+
{ cache: false },
|
|
1581
|
+
);
|
|
1506
1582
|
const parsed = safeParseContract(emailVerificationStartResponseSchema, res);
|
|
1507
1583
|
if (!parsed) throw new Error('users/me/reauth/email returned an unexpected response shape');
|
|
1508
1584
|
return parsed;
|
|
1509
1585
|
}
|
|
1510
|
-
|
|
1511
1586
|
}
|