@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.
Files changed (285) hide show
  1. package/README.md +1 -1
  2. package/dist/cjs/HttpService.js +63 -19
  3. package/dist/cjs/api/accounts.js +10 -3
  4. package/dist/cjs/api/agency.js +3 -1
  5. package/dist/cjs/api/apps.js +15 -4
  6. package/dist/cjs/api/assets.js +49 -12
  7. package/dist/cjs/api/auth.js +37 -11
  8. package/dist/cjs/api/billing.js +24 -7
  9. package/dist/cjs/api/civic.js +14 -4
  10. package/dist/cjs/api/follows.js +9 -2
  11. package/dist/cjs/api/identity.js +31 -9
  12. package/dist/cjs/api/nodes.js +3 -1
  13. package/dist/cjs/api/privacy.js +8 -2
  14. package/dist/cjs/api/session.js +15 -4
  15. package/dist/cjs/api/store.js +15 -5
  16. package/dist/cjs/api/topics.js +10 -3
  17. package/dist/cjs/api/users.js +16 -4
  18. package/dist/cjs/boot/sessionColdBoot.js +40 -13
  19. package/dist/cjs/constants/version.js +6 -6
  20. package/dist/cjs/crypto/identityMarker.js +3 -1
  21. package/dist/cjs/crypto/identityProof.js +6 -1
  22. package/dist/cjs/crypto/keyManager.js +87 -32
  23. package/dist/cjs/crypto/recoveryPhrase.js +2 -2
  24. package/dist/cjs/crypto/signatureService.js +3 -4
  25. package/dist/cjs/i18n/index.js +16 -3
  26. package/dist/cjs/i18n/locales/ar-SA.js +366 -366
  27. package/dist/cjs/i18n/locales/ca-ES.js +366 -366
  28. package/dist/cjs/i18n/locales/de-DE.js +366 -366
  29. package/dist/cjs/i18n/locales/en-US.js +1994 -1994
  30. package/dist/cjs/i18n/locales/es-ES.js +1994 -1994
  31. package/dist/cjs/i18n/locales/fr-FR.js +366 -366
  32. package/dist/cjs/i18n/locales/it-IT.js +366 -366
  33. package/dist/cjs/i18n/locales/ja-JP.js +366 -366
  34. package/dist/cjs/i18n/locales/ko-KR.js +366 -366
  35. package/dist/cjs/i18n/locales/pt-PT.js +366 -366
  36. package/dist/cjs/i18n/locales/zh-CN.js +366 -366
  37. package/dist/cjs/inference/OxyInferenceClient.js +12 -18
  38. package/dist/cjs/models/interfaces.js +11 -11
  39. package/dist/cjs/server/OxyServer.js +86 -28
  40. package/dist/cjs/server/agentAccount.js +6 -2
  41. package/dist/cjs/server/aliaMachineCredential.js +39 -14
  42. package/dist/cjs/server/auth.js +5 -4
  43. package/dist/cjs/server/capabilityTicket.js +5 -5
  44. package/dist/cjs/server/index.js +2 -1
  45. package/dist/cjs/server/liveCapabilityTicket.js +4 -1
  46. package/dist/cjs/server/middleware.js +61 -42
  47. package/dist/cjs/server/namespaces.js +28 -7
  48. package/dist/cjs/server/requesterAssertion.js +36 -30
  49. package/dist/cjs/server/serviceTokenLifetime.js +7 -4
  50. package/dist/cjs/server/traffic.js +53 -14
  51. package/dist/cjs/server/trafficNodeHttp.js +33 -8
  52. package/dist/cjs/server/workloadIdentity.client.js +4 -0
  53. package/dist/cjs/server/workloadIdentity.js +28 -1
  54. package/dist/cjs/session/SessionClient.js +54 -17
  55. package/dist/cjs/session/accountDelegationAccess.js +4 -6
  56. package/dist/cjs/session/accountDialogController.js +1 -1
  57. package/dist/cjs/session/authStateStore.js +18 -9
  58. package/dist/cjs/session/identityPin.js +6 -2
  59. package/dist/cjs/session/refresh.js +81 -23
  60. package/dist/cjs/session/sharedDeviceCredential.js +28 -15
  61. package/dist/cjs/shared/utils/errorUtils.js +1 -1
  62. package/dist/cjs/shared/utils/networkUtils.js +1 -1
  63. package/dist/cjs/shared/utils/themeUtils.js +1 -1
  64. package/dist/cjs/utils/accountCacheSweep.js +3 -1
  65. package/dist/cjs/utils/accountUtils.js +1 -3
  66. package/dist/cjs/utils/asyncUtils.js +1 -1
  67. package/dist/cjs/utils/authHelpers.js +2 -1
  68. package/dist/cjs/utils/avatarUtils.js +4 -2
  69. package/dist/cjs/utils/cache.js +1 -1
  70. package/dist/cjs/utils/cacheKey.js +3 -1
  71. package/dist/cjs/utils/deviceManager.js +4 -4
  72. package/dist/cjs/utils/errorUtils.js +6 -4
  73. package/dist/cjs/utils/languageUtils.js +404 -57
  74. package/dist/cjs/utils/profileLinks.js +1 -3
  75. package/dist/cjs/utils/requestUtils.js +7 -1
  76. package/dist/cjs/utils/userIdentity.js +1 -1
  77. package/dist/cjs/utils/validationUtils.js +5 -6
  78. package/dist/esm/HttpService.js +64 -20
  79. package/dist/esm/api/accounts.js +11 -4
  80. package/dist/esm/api/agency.js +3 -1
  81. package/dist/esm/api/apps.js +15 -4
  82. package/dist/esm/api/assets.js +49 -12
  83. package/dist/esm/api/auth.js +37 -11
  84. package/dist/esm/api/billing.js +25 -8
  85. package/dist/esm/api/civic.js +14 -4
  86. package/dist/esm/api/follows.js +9 -2
  87. package/dist/esm/api/identity.js +31 -9
  88. package/dist/esm/api/nodes.js +3 -1
  89. package/dist/esm/api/privacy.js +8 -2
  90. package/dist/esm/api/session.js +15 -4
  91. package/dist/esm/api/store.js +15 -5
  92. package/dist/esm/api/topics.js +10 -3
  93. package/dist/esm/api/users.js +16 -4
  94. package/dist/esm/boot/sessionColdBoot.js +41 -14
  95. package/dist/esm/constants/version.js +6 -6
  96. package/dist/esm/crypto/identityMarker.js +3 -1
  97. package/dist/esm/crypto/identityProof.js +6 -1
  98. package/dist/esm/crypto/internal.js +1 -1
  99. package/dist/esm/crypto/keyManager.js +87 -32
  100. package/dist/esm/crypto/recoveryPhrase.js +2 -2
  101. package/dist/esm/crypto/signatureService.js +3 -4
  102. package/dist/esm/i18n/index.js +16 -3
  103. package/dist/esm/i18n/locales/ar-SA.js +366 -366
  104. package/dist/esm/i18n/locales/ca-ES.js +366 -366
  105. package/dist/esm/i18n/locales/de-DE.js +366 -366
  106. package/dist/esm/i18n/locales/en-US.js +1994 -1994
  107. package/dist/esm/i18n/locales/es-ES.js +1994 -1994
  108. package/dist/esm/i18n/locales/fr-FR.js +366 -366
  109. package/dist/esm/i18n/locales/it-IT.js +366 -366
  110. package/dist/esm/i18n/locales/ja-JP.js +366 -366
  111. package/dist/esm/i18n/locales/ko-KR.js +366 -366
  112. package/dist/esm/i18n/locales/pt-PT.js +366 -366
  113. package/dist/esm/i18n/locales/zh-CN.js +366 -366
  114. package/dist/esm/index.js +1 -1
  115. package/dist/esm/inference/OxyInferenceClient.js +13 -19
  116. package/dist/esm/models/interfaces.js +11 -11
  117. package/dist/esm/server/OxyServer.js +87 -29
  118. package/dist/esm/server/agentAccount.js +6 -2
  119. package/dist/esm/server/aliaMachineCredential.js +39 -14
  120. package/dist/esm/server/auth.js +6 -5
  121. package/dist/esm/server/capabilityTicket.js +6 -6
  122. package/dist/esm/server/index.js +5 -5
  123. package/dist/esm/server/liveCapabilityTicket.js +6 -3
  124. package/dist/esm/server/middleware.js +62 -43
  125. package/dist/esm/server/namespaces.js +31 -10
  126. package/dist/esm/server/requesterAssertion.js +36 -30
  127. package/dist/esm/server/serviceTokenLifetime.js +7 -4
  128. package/dist/esm/server/traffic.js +55 -16
  129. package/dist/esm/server/trafficNodeHttp.js +34 -9
  130. package/dist/esm/server/userInvalidation.js +1 -1
  131. package/dist/esm/server/workloadIdentity.client.js +3 -0
  132. package/dist/esm/server/workloadIdentity.js +27 -1
  133. package/dist/esm/session/SessionClient.js +54 -17
  134. package/dist/esm/session/accountDelegationAccess.js +5 -7
  135. package/dist/esm/session/accountDialogController.js +1 -1
  136. package/dist/esm/session/authStateStore.js +18 -9
  137. package/dist/esm/session/identityPin.js +6 -2
  138. package/dist/esm/session/refresh.js +82 -24
  139. package/dist/esm/session/sharedDeviceCredential.js +28 -15
  140. package/dist/esm/shared/utils/errorUtils.js +1 -1
  141. package/dist/esm/shared/utils/networkUtils.js +1 -1
  142. package/dist/esm/shared/utils/themeUtils.js +1 -1
  143. package/dist/esm/utils/accountCacheSweep.js +3 -1
  144. package/dist/esm/utils/accountUtils.js +1 -3
  145. package/dist/esm/utils/asyncUtils.js +1 -1
  146. package/dist/esm/utils/authHelpers.js +2 -1
  147. package/dist/esm/utils/avatarUtils.js +4 -2
  148. package/dist/esm/utils/cache.js +1 -1
  149. package/dist/esm/utils/cacheKey.js +3 -1
  150. package/dist/esm/utils/deviceManager.js +4 -4
  151. package/dist/esm/utils/errorUtils.js +6 -4
  152. package/dist/esm/utils/languageUtils.js +404 -57
  153. package/dist/esm/utils/profileLinks.js +1 -3
  154. package/dist/esm/utils/requestUtils.js +7 -1
  155. package/dist/esm/utils/userIdentity.js +1 -1
  156. package/dist/esm/utils/validationUtils.js +5 -6
  157. package/dist/types/HttpService.d.ts +1 -1
  158. package/dist/types/api/accounts.d.ts +1 -1
  159. package/dist/types/api/apps.d.ts +4 -4
  160. package/dist/types/api/assets.d.ts +2 -0
  161. package/dist/types/api/auth.d.ts +8 -3
  162. package/dist/types/crypto/internal.d.ts +1 -1
  163. package/dist/types/index.d.ts +4 -4
  164. package/dist/types/server/index.d.ts +6 -6
  165. package/dist/types/server/requesterAssertion.d.ts +2 -2
  166. package/dist/types/server/workloadIdentity.client.d.ts +5 -1
  167. package/dist/types/server/workloadIdentity.d.ts +26 -0
  168. package/dist/types/session/accountDelegationAccess.d.ts +1 -1
  169. package/dist/types/session/index.d.ts +1 -1
  170. package/dist/types/utils/userIdentity.d.ts +1 -1
  171. package/dist/types/utils/validationUtils.d.ts +4 -5
  172. package/package.json +2 -3
  173. package/src/HttpService.ts +183 -53
  174. package/src/OxyServices.errors.ts +7 -3
  175. package/src/OxyServices.ts +6 -2
  176. package/src/api/accounts.ts +76 -26
  177. package/src/api/agency.ts +24 -9
  178. package/src/api/appData.ts +12 -2
  179. package/src/api/apps.ts +81 -31
  180. package/src/api/assets.ts +122 -40
  181. package/src/api/auth.ts +154 -79
  182. package/src/api/billing.ts +112 -65
  183. package/src/api/civic.ts +61 -19
  184. package/src/api/contacts.ts +4 -1
  185. package/src/api/devices.ts +54 -21
  186. package/src/api/follows.ts +88 -31
  187. package/src/api/identity.ts +101 -33
  188. package/src/api/linkedAccounts.ts +26 -8
  189. package/src/api/nodes.ts +18 -6
  190. package/src/api/notifications.ts +26 -6
  191. package/src/api/privacy.ts +42 -8
  192. package/src/api/reputation.ts +18 -7
  193. package/src/api/session.ts +23 -5
  194. package/src/api/store.ts +81 -31
  195. package/src/api/topics.ts +18 -6
  196. package/src/api/users.ts +98 -35
  197. package/src/boot/sessionColdBoot.ts +60 -19
  198. package/src/civic/payloads.ts +1 -4
  199. package/src/client/context.ts +6 -1
  200. package/src/constants/version.ts +7 -6
  201. package/src/crypto/aead.ts +1 -5
  202. package/src/crypto/ecdh.ts +1 -4
  203. package/src/crypto/identityDerivations.ts +5 -1
  204. package/src/crypto/identityMarker.ts +3 -1
  205. package/src/crypto/identityProof.ts +6 -1
  206. package/src/crypto/index.ts +11 -11
  207. package/src/crypto/internal.ts +6 -1
  208. package/src/crypto/keyManager.ts +348 -98
  209. package/src/crypto/recoveryPhrase.ts +14 -9
  210. package/src/crypto/registrationPow.ts +1 -1
  211. package/src/crypto/signatureService.ts +14 -6
  212. package/src/i18n/accountCategoryLabels.ts +1 -4
  213. package/src/i18n/accountRoleLabels.ts +1 -4
  214. package/src/i18n/index.ts +25 -7
  215. package/src/i18n/locales/ar-SA.ts +375 -366
  216. package/src/i18n/locales/ca-ES.ts +382 -366
  217. package/src/i18n/locales/de-DE.ts +387 -366
  218. package/src/i18n/locales/en-US.ts +2034 -1994
  219. package/src/i18n/locales/es-ES.ts +2043 -1994
  220. package/src/i18n/locales/fr-FR.ts +387 -366
  221. package/src/i18n/locales/it-IT.ts +380 -366
  222. package/src/i18n/locales/ja-JP.ts +380 -366
  223. package/src/i18n/locales/ko-KR.ts +377 -366
  224. package/src/i18n/locales/pt-PT.ts +383 -366
  225. package/src/i18n/locales/zh-CN.ts +373 -366
  226. package/src/i18n/trustTierLabels.ts +1 -4
  227. package/src/index.ts +371 -349
  228. package/src/inference/OxyInferenceClient.ts +784 -780
  229. package/src/models/interfaces.ts +30 -27
  230. package/src/server/OxyServer.ts +227 -68
  231. package/src/server/agentAccount.ts +8 -2
  232. package/src/server/aliaMachineCredential.ts +57 -16
  233. package/src/server/auth.ts +9 -5
  234. package/src/server/capabilityTicket.ts +30 -21
  235. package/src/server/index.ts +29 -6
  236. package/src/server/liveCapabilityTicket.ts +31 -9
  237. package/src/server/middleware.ts +212 -121
  238. package/src/server/namespaces.ts +247 -94
  239. package/src/server/rateLimit.ts +2 -4
  240. package/src/server/requesterAssertion.ts +93 -54
  241. package/src/server/serviceTokenLifetime.ts +9 -4
  242. package/src/server/traffic.ts +117 -23
  243. package/src/server/trafficNodeHttp.ts +61 -14
  244. package/src/server/userInvalidation.ts +1 -4
  245. package/src/server/workloadIdentity.client.ts +12 -1
  246. package/src/server/workloadIdentity.ts +52 -5
  247. package/src/session/SessionClient.ts +170 -49
  248. package/src/session/accountDelegationAccess.ts +24 -31
  249. package/src/session/accountDialogController.ts +59 -14
  250. package/src/session/accountSwitchTargets.ts +10 -15
  251. package/src/session/authStateStore.ts +121 -81
  252. package/src/session/deviceDirectory.ts +1 -3
  253. package/src/session/identityPin.ts +10 -11
  254. package/src/session/identitySession.ts +3 -1
  255. package/src/session/index.ts +87 -82
  256. package/src/session/refresh.ts +138 -44
  257. package/src/session/sessionClientHost.ts +1 -3
  258. package/src/session/sharedDeviceCredential.ts +35 -14
  259. package/src/session/socketLoader.ts +9 -2
  260. package/src/shared/utils/errorUtils.ts +5 -2
  261. package/src/shared/utils/networkUtils.ts +5 -8
  262. package/src/shared/utils/themeUtils.ts +2 -6
  263. package/src/types/buffer.d.ts +66 -21
  264. package/src/types/expo-secure-store.d.ts +5 -1
  265. package/src/utils/accountCacheSweep.ts +4 -5
  266. package/src/utils/accountUtils.ts +107 -108
  267. package/src/utils/apiUtils.ts +3 -3
  268. package/src/utils/asyncUtils.ts +2 -2
  269. package/src/utils/authHelpers.ts +10 -5
  270. package/src/utils/avatarUtils.ts +11 -6
  271. package/src/utils/cache.ts +9 -10
  272. package/src/utils/cacheKey.ts +5 -1
  273. package/src/utils/coldBoot.ts +1 -3
  274. package/src/utils/commonsDelivery.ts +1 -4
  275. package/src/utils/deviceManager.ts +15 -14
  276. package/src/utils/errorUtils.ts +68 -86
  277. package/src/utils/languageUtils.ts +407 -58
  278. package/src/utils/oauthPkce.ts +1 -4
  279. package/src/utils/platform.ts +0 -1
  280. package/src/utils/profileLinks.ts +2 -5
  281. package/src/utils/requestUtils.ts +18 -14
  282. package/src/utils/sessionUtils.ts +34 -33
  283. package/src/utils/userHandle.ts +3 -1
  284. package/src/utils/userIdentity.ts +1 -1
  285. 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 () => (await import('../crypto/internal')).loadCommonsIdentityBridge();
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(ctx: OxyContext, options: SignInDeviceOptions = {}): Promise<Record<string, unknown>> {
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(request: EmailVerificationStartRequest): Promise<EmailVerificationStartResponse> {
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(verificationId: string, code: string): Promise<EmailVerificationConfirmResponse> {
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(identifier: string, options: { device?: DeviceProof | null } = {}): Promise<EmailSignInStartResponse> {
544
- const device = options.device === undefined ? await this.ctx.oxy.session.readDeviceProof() : options.device;
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(request: { identifier: string; password: string } & SignInDeviceOptions): Promise<SignInStepResult> {
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: { newPassword: string; reauth: ReauthProof; revokeOtherSessions?: boolean }): Promise<{ success: true }> {
631
- return this.ctx.request<{ success: true }>('PUT', '/users/me/password', request, { cache: false });
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, { cache: false });
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>('POST', '/users/me/totp/confirm', { code, reauth }, { cache: false });
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 }>('POST', '/users/me/totp/disable', { reauth }, { cache: false });
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>('POST', '/users/me/totp/backup-codes', { reauth }, { cache: false });
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) throw new Error('users/me/totp/backup-codes returned an unexpected response shape');
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(params: {
703
- code: string;
704
- clientId: string;
705
- redirectUri: string;
706
- codeVerifier: string;
707
- }, options: { plantTokens?: boolean } = {}): Promise<OAuthTokenExchangeResult> {
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
- 'POST',
717
- '/auth/oauth/token',
718
- form,
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
- 'GET',
778
- '/auth/oauth/userinfo',
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
- { cache: false, skipAuth: true });
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
- { cache: false, skipAuth: true });
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 identity with public key authentication
1212
- * Identity is purely cryptographic - username and profile data are optional
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 }>('POST', '/auth/register', {
1230
- publicKey,
1231
- signature,
1232
- timestamp,
1233
- powNonce,
1234
- }, { cache: false, skipAuth: true });
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>('POST', '/auth/challenge', {
1258
- publicKey,
1259
- }, { cache: false, skipAuth: true, ...requestOptions });
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>('POST', '/auth/verify', {
1291
- publicKey,
1292
- challenge,
1293
- signature,
1294
- timestamp,
1295
- deviceName,
1296
- deviceFingerprint,
1297
- }, { cache: false, skipAuth: true, ...requestOptions });
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: { deviceFingerprint?: string; plantTokens?: boolean; device?: DeviceProof | null } = {}
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 = options.device === undefined ? await this.ctx.oxy.session.readDeviceProof() : options.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, { cache: false, skipAuth: true });
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(request: { challengeId: string; code: string } & SignInDeviceOptions): Promise<LoginResult> {
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(request: { username: string; email: string; emailTicket: string } & SignInDeviceOptions): Promise<LoginResult> {
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, { cache: false });
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>('POST', '/users/me/reauth/email', { action }, { cache: false });
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
  }