@oxyhq/core 12.9.0 → 12.10.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (106) hide show
  1. package/dist/cjs/.tsbuildinfo +1 -1
  2. package/dist/cjs/HttpService.js +22 -12
  3. package/dist/cjs/crypto/keyManager.js +89 -0
  4. package/dist/cjs/i18n/locales/ar-SA.json +4 -0
  5. package/dist/cjs/i18n/locales/ca-ES.json +4 -0
  6. package/dist/cjs/i18n/locales/de-DE.json +4 -0
  7. package/dist/cjs/i18n/locales/en-US.json +69 -3
  8. package/dist/cjs/i18n/locales/es-ES.json +68 -2
  9. package/dist/cjs/i18n/locales/fr-FR.json +4 -0
  10. package/dist/cjs/i18n/locales/it-IT.json +4 -0
  11. package/dist/cjs/i18n/locales/ja-JP.json +4 -0
  12. package/dist/cjs/i18n/locales/ko-KR.json +4 -0
  13. package/dist/cjs/i18n/locales/locales/ar-SA.json +4 -0
  14. package/dist/cjs/i18n/locales/locales/ca-ES.json +4 -0
  15. package/dist/cjs/i18n/locales/locales/de-DE.json +4 -0
  16. package/dist/cjs/i18n/locales/locales/en-US.json +69 -3
  17. package/dist/cjs/i18n/locales/locales/es-ES.json +68 -2
  18. package/dist/cjs/i18n/locales/locales/fr-FR.json +4 -0
  19. package/dist/cjs/i18n/locales/locales/it-IT.json +4 -0
  20. package/dist/cjs/i18n/locales/locales/ja-JP.json +4 -0
  21. package/dist/cjs/i18n/locales/locales/ko-KR.json +4 -0
  22. package/dist/cjs/i18n/locales/locales/pt-PT.json +4 -0
  23. package/dist/cjs/i18n/locales/locales/zh-CN.json +4 -0
  24. package/dist/cjs/i18n/locales/pt-PT.json +4 -0
  25. package/dist/cjs/i18n/locales/zh-CN.json +4 -0
  26. package/dist/cjs/index.js +7 -4
  27. package/dist/cjs/mixins/OxyServices.auth.js +51 -20
  28. package/dist/cjs/mixins/OxyServices.connectedApps.js +6 -1
  29. package/dist/cjs/mixins/OxyServices.deviceBoot.js +9 -2
  30. package/dist/cjs/mixins/OxyServices.identityBackup.js +11 -0
  31. package/dist/cjs/mixins/OxyServices.user.js +6 -0
  32. package/dist/cjs/session/accountDialogController.js +7 -5
  33. package/dist/cjs/utils/commonsApproval.js +31 -0
  34. package/dist/esm/.tsbuildinfo +1 -1
  35. package/dist/esm/HttpService.js +22 -12
  36. package/dist/esm/crypto/keyManager.js +89 -0
  37. package/dist/esm/i18n/locales/ar-SA.json +4 -0
  38. package/dist/esm/i18n/locales/ca-ES.json +4 -0
  39. package/dist/esm/i18n/locales/de-DE.json +4 -0
  40. package/dist/esm/i18n/locales/en-US.json +69 -3
  41. package/dist/esm/i18n/locales/es-ES.json +68 -2
  42. package/dist/esm/i18n/locales/fr-FR.json +4 -0
  43. package/dist/esm/i18n/locales/it-IT.json +4 -0
  44. package/dist/esm/i18n/locales/ja-JP.json +4 -0
  45. package/dist/esm/i18n/locales/ko-KR.json +4 -0
  46. package/dist/esm/i18n/locales/locales/ar-SA.json +4 -0
  47. package/dist/esm/i18n/locales/locales/ca-ES.json +4 -0
  48. package/dist/esm/i18n/locales/locales/de-DE.json +4 -0
  49. package/dist/esm/i18n/locales/locales/en-US.json +69 -3
  50. package/dist/esm/i18n/locales/locales/es-ES.json +68 -2
  51. package/dist/esm/i18n/locales/locales/fr-FR.json +4 -0
  52. package/dist/esm/i18n/locales/locales/it-IT.json +4 -0
  53. package/dist/esm/i18n/locales/locales/ja-JP.json +4 -0
  54. package/dist/esm/i18n/locales/locales/ko-KR.json +4 -0
  55. package/dist/esm/i18n/locales/locales/pt-PT.json +4 -0
  56. package/dist/esm/i18n/locales/locales/zh-CN.json +4 -0
  57. package/dist/esm/i18n/locales/pt-PT.json +4 -0
  58. package/dist/esm/i18n/locales/zh-CN.json +4 -0
  59. package/dist/esm/index.js +2 -1
  60. package/dist/esm/mixins/OxyServices.auth.js +48 -19
  61. package/dist/esm/mixins/OxyServices.connectedApps.js +6 -1
  62. package/dist/esm/mixins/OxyServices.deviceBoot.js +9 -2
  63. package/dist/esm/mixins/OxyServices.identityBackup.js +11 -0
  64. package/dist/esm/mixins/OxyServices.user.js +6 -0
  65. package/dist/esm/session/accountDialogController.js +7 -5
  66. package/dist/esm/utils/commonsApproval.js +27 -0
  67. package/dist/types/.tsbuildinfo +1 -1
  68. package/dist/types/HttpService.d.ts +14 -0
  69. package/dist/types/crypto/keyManager.d.ts +33 -0
  70. package/dist/types/index.d.ts +2 -1
  71. package/dist/types/mixins/OxyServices.auth.d.ts +4 -4
  72. package/dist/types/session/accountDialogController.d.ts +7 -2
  73. package/dist/types/utils/commonsApproval.d.ts +13 -0
  74. package/package.json +3 -3
  75. package/src/HttpService.ts +37 -14
  76. package/src/__tests__/httpServiceAuthSelfAwait.test.ts +108 -0
  77. package/src/__tests__/httpServiceQueueDeadlock.test.ts +128 -0
  78. package/src/crypto/__tests__/keyManager.recoveryMnemonic.test.ts +138 -0
  79. package/src/crypto/keyManager.ts +99 -0
  80. package/src/i18n/locales/ar-SA.json +4 -0
  81. package/src/i18n/locales/ca-ES.json +4 -0
  82. package/src/i18n/locales/de-DE.json +4 -0
  83. package/src/i18n/locales/en-US.json +69 -3
  84. package/src/i18n/locales/es-ES.json +68 -2
  85. package/src/i18n/locales/fr-FR.json +4 -0
  86. package/src/i18n/locales/it-IT.json +4 -0
  87. package/src/i18n/locales/ja-JP.json +4 -0
  88. package/src/i18n/locales/ko-KR.json +4 -0
  89. package/src/i18n/locales/pt-PT.json +4 -0
  90. package/src/i18n/locales/zh-CN.json +4 -0
  91. package/src/index.ts +7 -1
  92. package/src/mixins/OxyServices.auth.ts +48 -24
  93. package/src/mixins/OxyServices.connectedApps.ts +6 -1
  94. package/src/mixins/OxyServices.deviceBoot.ts +7 -2
  95. package/src/mixins/OxyServices.identityBackup.ts +13 -0
  96. package/src/mixins/OxyServices.user.ts +6 -0
  97. package/src/mixins/__tests__/OxyServices.deviceBoot.test.ts +4 -2
  98. package/src/mixins/__tests__/commonsSignIn.test.ts +4 -4
  99. package/src/mixins/__tests__/identityBackup.test.ts +57 -0
  100. package/src/mixins/__tests__/preSessionSkipAuth.test.ts +152 -0
  101. package/src/mixins/__tests__/privacyCacheInvalidation.test.ts +6 -0
  102. package/src/mixins/__tests__/webauthnAuth.test.ts +6 -6
  103. package/src/session/__tests__/accountDialogController.test.ts +3 -3
  104. package/src/session/accountDialogController.ts +7 -6
  105. package/src/utils/__tests__/commonsApproval.test.ts +60 -0
  106. package/src/utils/commonsApproval.ts +39 -0
@@ -290,6 +290,8 @@
290
290
  "saving": "Guardando…",
291
291
  "helper": "El círculo recortado es lo que aparecerá en tu perfil. Pellizca para acercar, arrastra para colocar.",
292
292
  "zoom": "{{value}}×",
293
+ "zoomIn": "Acercar",
294
+ "zoomOut": "Alejar",
293
295
  "a11yImage": "Vista previa del recorte. Pellizca para acercar y arrastra para reposicionar la imagen.",
294
296
  "a11yReset": "Restablecer el recorte a la posición predeterminada",
295
297
  "a11yResetAnnouncement": "Recorte restablecido"
@@ -310,6 +312,47 @@
310
312
  },
311
313
  "changeAvatar": "Cambiar avatar"
312
314
  },
315
+ "changeAvatar": {
316
+ "title": "Cambiar foto de perfil",
317
+ "sources": {
318
+ "upload": {
319
+ "title": "Subir desde el dispositivo",
320
+ "description": "Elige una foto de tu galería"
321
+ },
322
+ "camera": {
323
+ "title": "Hacer una foto",
324
+ "description": "Usa tu cámara"
325
+ },
326
+ "files": {
327
+ "title": "Mis archivos de Oxy",
328
+ "description": "Elige una imagen que ya has subido"
329
+ },
330
+ "remove": {
331
+ "title": "Eliminar la foto actual",
332
+ "description": "Vuelve a tus iniciales"
333
+ }
334
+ },
335
+ "remove": {
336
+ "confirmTitle": "¿Eliminar la foto de perfil?",
337
+ "confirmMessage": "Tu perfil mostrará tus iniciales. Puedes añadir una foto nueva cuando quieras.",
338
+ "confirmLabel": "Eliminar"
339
+ },
340
+ "permission": {
341
+ "libraryDenied": "Oxy necesita acceso a tus fotos para subir una imagen.",
342
+ "cameraDenied": "Oxy necesita acceso a tu cámara para hacer una foto.",
343
+ "openSettings": "Abrir ajustes"
344
+ },
345
+ "errors": {
346
+ "pickerUnavailable": "La selección de fotos no está disponible en este dispositivo.",
347
+ "cameraUnavailable": "La cámara no está disponible en este dispositivo.",
348
+ "pickFailed": "No se pudo abrir el selector de fotos.",
349
+ "cameraFailed": "No se pudo abrir la cámara.",
350
+ "loadImageFailed": "No se pudo cargar la imagen seleccionada."
351
+ },
352
+ "a11y": {
353
+ "currentPhoto": "Tu foto de perfil actual"
354
+ }
355
+ },
313
356
  "common": {
314
357
  "actions": {
315
358
  "back": "Atrás",
@@ -619,7 +662,8 @@
619
662
  "getCommons": "Descargar Commons",
620
663
  "commonsNotInstalled": "¿No tienes Commons? Descarga la app para iniciar sesión con tu Oxy ID.",
621
664
  "showQrAnyway": "Tengo Commons en otro dispositivo",
622
- "switchWhileSignedInAs": "Cambiar de cuenta, con la sesión iniciada como {{name}}"
665
+ "switchWhileSignedInAs": "Cambiar de cuenta, con la sesión iniciada como {{name}}",
666
+ "manageOnDevice": "Gestionar cuentas en este dispositivo"
623
667
  },
624
668
  "feedback": {
625
669
  "type": {
@@ -1442,6 +1486,11 @@
1442
1486
  "uploadPhotos": "Subir fotos",
1443
1487
  "uploadFiles": "Subir archivos",
1444
1488
  "clearSearch": "Limpiar búsqueda",
1489
+ "retry": "Reintentar",
1490
+ "loadError": {
1491
+ "title": "No se pudieron cargar tus archivos",
1492
+ "description": "Algo salió mal. Comprueba tu conexión e inténtalo de nuevo."
1493
+ },
1445
1494
  "choosePhoto": "Elegir foto",
1446
1495
  "done": "Listo",
1447
1496
  "doneWithCount": "Listo ({{count}})",
@@ -1615,6 +1664,8 @@
1615
1664
  "accountMenu": {
1616
1665
  "label": "Menú de cuenta",
1617
1666
  "manage": "Gestiona tu cuenta de Oxy",
1667
+ "greeting": "¡Hola, {{name}}!",
1668
+ "switchAccount": "Cambiar de cuenta",
1618
1669
  "viewProfile": "Ver perfil",
1619
1670
  "addAnother": "Añadir otra cuenta",
1620
1671
  "signOutAll": "Cerrar sesión en todas las cuentas",
@@ -1622,7 +1673,22 @@
1622
1673
  "openHint": "Abre el menú de cuenta",
1623
1674
  "openWithUser": "Menú de cuenta de {{name}}",
1624
1675
  "switching": "Cambiando de cuenta…",
1625
- "signOutAccount": "Cerrar sesión de {{name}}"
1676
+ "signOutAccount": "Cerrar sesión de {{name}}",
1677
+ "storage": {
1678
+ "title": "Almacenamiento de Oxy",
1679
+ "usage": "{{used}} de {{total}} en uso",
1680
+ "used": "Usado",
1681
+ "free": "Libre",
1682
+ "unavailable": "Detalles de uso no disponibles",
1683
+ "upgrade": "Mejorar plan",
1684
+ "manage": "Gestionar almacenamiento"
1685
+ },
1686
+ "data": "Tus datos en Oxy",
1687
+ "settings": "Ajustes de Oxy",
1688
+ "help": "Ayuda y comentarios",
1689
+ "signOut": "Cerrar sesión",
1690
+ "privacy": "Política de privacidad",
1691
+ "terms": "Términos del servicio"
1626
1692
  },
1627
1693
  "accounts": {
1628
1694
  "activeAccount": {
@@ -112,6 +112,10 @@
112
112
  }
113
113
  },
114
114
  "accountSwitcher": {
115
+ "sections": {
116
+ "yourAccounts": "Vos comptes"
117
+ },
118
+ "loading": "Chargement des comptes...",
115
119
  "qrHeadline": "Connectez-vous avec votre identité Oxy",
116
120
  "signInWithOxy": "Se connecter avec Oxy",
117
121
  "useIdentityOnDevice": "Pas de Commons ? Utilisez une clé d'accès sur cet appareil",
@@ -112,6 +112,10 @@
112
112
  }
113
113
  },
114
114
  "accountSwitcher": {
115
+ "sections": {
116
+ "yourAccounts": "I tuoi account"
117
+ },
118
+ "loading": "Caricamento account...",
115
119
  "qrHeadline": "Accedi con la tua identità Oxy",
116
120
  "signInWithOxy": "Accedi con Oxy",
117
121
  "useIdentityOnDevice": "Non hai Commons? Usa una passkey su questo dispositivo",
@@ -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": "내 계정"
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": "你的账户"
117
+ },
118
+ "loading": "正在加载账户...",
115
119
  "qrHeadline": "使用您的 Oxy 身份登录",
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": "你的账户"
117
+ },
118
+ "loading": "正在加载账户...",
115
119
  "qrHeadline": "使用您的 Oxy 身份登录",
116
120
  "signInWithOxy": "使用 Oxy 登录",
117
121
  "useIdentityOnDevice": "没有 Commons?改用此设备上的通行密钥",
package/dist/cjs/index.js CHANGED
@@ -18,10 +18,10 @@
18
18
  * If a symbol does not appear here, it is NOT part of the public API.
19
19
  */
20
20
  Object.defineProperty(exports, "__esModule", { value: true });
21
- exports.normalizeLocale = exports.getBaseLanguage = exports.FALLBACK_LOCALE = exports.SUPPORTED_LANGUAGES = exports.TopicSource = exports.TopicType = exports.SECURITY_EVENT_SEVERITY_MAP = exports.DeviceManager = exports.deriveSharedSecret = exports.AEAD_NONCE_LENGTH = exports.AEAD_KEY_LENGTH = exports.decryptAead = exports.encryptAead = exports.hkdfSha256 = exports.RecoveryPhraseService = exports.SignatureService = exports.updateIdentityMarker = exports.readIdentityMarker = exports.IdentityUnavailableError = exports.IdentityPersistError = exports.IdentityAlreadyExistsError = exports.KeyManager = exports.sessionsArraysEqual = exports.normalizeAndSortSessions = exports.mergeSessions = exports.authenticatedApiCall = exports.withAuthErrorHandling = exports.isAuthenticationError = exports.ensureValidToken = exports.AuthenticationFailedError = exports.SessionSyncRequiredError = exports.verifyPublicCardAttestation = exports.parseAttestPayload = exports.parseIdPayload = exports.buildUserDid = exports.ORGANIZATION_CATEGORIES = exports.normalizeProfileLinks = exports.getNormalizedUserHandle = exports.getCanonicalUserHandle = exports.normalizeUserIdentityOrNull = exports.normalizeUserIdentity = exports.getNormalizedUserId = exports.OxyAppDataIdentifierError = exports.ServiceCredentialMismatchError = exports.oxyClient = exports.OXY_CLOUD_URL = exports.OxyAuthenticationTimeoutError = exports.OxyAuthenticationError = exports.AssetUrlResolutionError = exports.OxyServices = void 0;
22
- exports.safeJsonParse = exports.buildPaginationParams = exports.buildUrl = exports.buildSearchParams = exports.translate = exports.withRetry = exports.delay = exports.shouldAllowRequest = exports.recordSuccess = exports.recordFailure = exports.calculateBackoffInterval = exports.createCircuitBreakerState = exports.DEFAULT_CIRCUIT_BREAKER_CONFIG = exports.isRetryableError = exports.isNetworkError = exports.isServerError = exports.isRateLimitError = exports.isNotFoundError = exports.isForbiddenError = exports.isUnauthorizedError = exports.isAlreadyRegisteredError = exports.getErrorMessage = exports.getErrorStatus = exports.HttpStatus = exports.getSystemColorScheme = exports.systemPrefersDarkMode = exports.getOppositeTheme = exports.normalizeColorScheme = exports.normalizeTheme = exports.getContrastTextColor = exports.isLightColor = exports.withOpacity = exports.rgbToHex = exports.hexToRgb = exports.lightenColor = exports.darkenColor = exports.isWebBrowser = exports.isAndroid = exports.isIOS = exports.isNative = exports.isWeb = exports.setPlatformOS = exports.getPlatformOS = exports.getPrimaryLanguage = exports.getUserLanguages = exports.isRTLLocale = exports.getNativeLanguageName = exports.getLanguageName = exports.getLanguageMetadata = exports.isSupportedLocale = void 0;
23
- exports.buildOAuthAuthorizeUrl = exports.runColdBoot = exports.isOxyRpOrigin = exports.CENTRAL_IDP_APEX = exports.registrableApex = exports.getAccountColor = exports.formatPublicKeyHandle = exports.getAccountFallbackHandle = exports.getAccountDisplayName = exports.createQuickAccount = exports.buildAccountsArray = exports.updateAvatarVisibility = exports.isDev = exports.consoleSink = exports.resetLoggerConfig = exports.getLoggerConfig = exports.configureLogger = exports.createLogger = exports.logger = exports.normalizeMultilineText = exports.normalizeInlineText = exports.validateAndSanitizeUserInput = exports.isValidObjectId = exports.sanitizeHTML = exports.sanitizeString = exports.isValidFileType = exports.isValidFileSize = exports.isValidDate = exports.isValidURL = exports.isValidUUID = exports.isValidObject = exports.isValidArray = exports.isRequiredBoolean = exports.isRequiredNumber = exports.isRequiredString = exports.DISPLAY_NAME_ORPHANED_MARK_SOURCE = exports.DISPLAY_NAME_DISALLOWED_SOURCE = exports.DISPLAY_NAME_ALLOWED_SCRIPTS = exports.isValidDisplayName = exports.isValidPassword = exports.isValidUsername = exports.isValidEmail = exports.PASSWORD_REGEX = exports.USERNAME_REGEX = exports.EMAIL_REGEX = exports.retryAsync = exports.validateRequiredFields = exports.handleHttpError = exports.createApiError = exports.ErrorCodes = void 0;
24
- exports.packageInfo = exports.runSessionColdBoot = exports.TOKEN_REFRESH_LEAD_MS = exports.startTokenRefreshScheduler = exports.installAuthRefreshHandler = exports.createAuthRefreshHandler = exports.refreshDeviceSecretArm = exports.refreshPersistedSession = exports.AUTH_STATE_STORAGE_KEY = exports.createMemoryAuthStateStore = exports.createNativeAuthStateStore = exports.createWebAuthStateStore = exports.createAccountDialogController = exports.AccountDialogController = exports.switchableAccountIds = exports.projectSwitchableAccounts = exports.accountIdsOf = exports.activeUserOf = exports.activeSessionIdOf = exports.deviceStateToClientSessions = exports.createSessionClient = exports.createSessionClientHost = exports.SessionClient = exports.redeemHubTicketOnHub = exports.syncHubAfterSignIn = exports.parseHubSyncReturnUrl = exports.normalizeOfficialReturnOrigin = exports.isAllowedDeviceJoinOrigin = exports.isOfficialWebOrigin = exports.isLoopbackOrigin = exports.isIdpHubOrigin = exports.buildHubSyncUrl = exports.buildIdpHubOrigin = exports.clearOAuthHandshake = exports.readOAuthHandshake = exports.persistOAuthHandshake = exports.normalizeOAuthRedirectUri = exports.OXY_CROSS_ORIGIN_RESTORE_ATTEMPTED_KEY = exports.OXY_SILENT_OAUTH_ATTEMPTED_KEY = exports.OXY_OAUTH_CODE_VERIFIER_STORAGE_KEY = exports.OXY_OAUTH_STATE_STORAGE_KEY = exports.OXY_AUTHORIZE_URL = exports.DEFAULT_OAUTH_SCOPE = exports.generatePkcePair = exports.generateOAuthState = exports.computeCodeChallenge = void 0;
21
+ exports.FALLBACK_LOCALE = exports.SUPPORTED_LANGUAGES = exports.TopicSource = exports.TopicType = exports.SECURITY_EVENT_SEVERITY_MAP = exports.DeviceManager = exports.deriveSharedSecret = exports.AEAD_NONCE_LENGTH = exports.AEAD_KEY_LENGTH = exports.decryptAead = exports.encryptAead = exports.hkdfSha256 = exports.RecoveryPhraseService = exports.SignatureService = exports.updateIdentityMarker = exports.readIdentityMarker = exports.IdentityUnavailableError = exports.IdentityPersistError = exports.IdentityAlreadyExistsError = exports.KeyManager = exports.sessionsArraysEqual = exports.normalizeAndSortSessions = exports.mergeSessions = exports.authenticatedApiCall = exports.withAuthErrorHandling = exports.isAuthenticationError = exports.ensureValidToken = exports.AuthenticationFailedError = exports.SessionSyncRequiredError = exports.verifyPublicCardAttestation = exports.parseAttestPayload = exports.parseIdPayload = exports.buildUserDid = exports.ORGANIZATION_CATEGORIES = exports.normalizeProfileLinks = exports.getNormalizedUserHandle = exports.getCanonicalUserHandle = exports.normalizeUserIdentityOrNull = exports.normalizeUserIdentity = exports.getNormalizedUserId = exports.OxyAppDataIdentifierError = exports.parseCommonsApprovalExpiresAt = exports.getCommonsApprovalBlockingReason = exports.ServiceCredentialMismatchError = exports.oxyClient = exports.OXY_CLOUD_URL = exports.OxyAuthenticationTimeoutError = exports.OxyAuthenticationError = exports.AssetUrlResolutionError = exports.OxyServices = void 0;
22
+ exports.buildUrl = exports.buildSearchParams = exports.translate = exports.withRetry = exports.delay = exports.shouldAllowRequest = exports.recordSuccess = exports.recordFailure = exports.calculateBackoffInterval = exports.createCircuitBreakerState = exports.DEFAULT_CIRCUIT_BREAKER_CONFIG = exports.isRetryableError = exports.isNetworkError = exports.isServerError = exports.isRateLimitError = exports.isNotFoundError = exports.isForbiddenError = exports.isUnauthorizedError = exports.isAlreadyRegisteredError = exports.getErrorMessage = exports.getErrorStatus = exports.HttpStatus = exports.getSystemColorScheme = exports.systemPrefersDarkMode = exports.getOppositeTheme = exports.normalizeColorScheme = exports.normalizeTheme = exports.getContrastTextColor = exports.isLightColor = exports.withOpacity = exports.rgbToHex = exports.hexToRgb = exports.lightenColor = exports.darkenColor = exports.isWebBrowser = exports.isAndroid = exports.isIOS = exports.isNative = exports.isWeb = exports.setPlatformOS = exports.getPlatformOS = exports.getPrimaryLanguage = exports.getUserLanguages = exports.isRTLLocale = exports.getNativeLanguageName = exports.getLanguageName = exports.getLanguageMetadata = exports.isSupportedLocale = exports.normalizeLocale = exports.getBaseLanguage = void 0;
23
+ exports.isOxyRpOrigin = exports.CENTRAL_IDP_APEX = exports.registrableApex = exports.getAccountColor = exports.formatPublicKeyHandle = exports.getAccountFallbackHandle = exports.getAccountDisplayName = exports.createQuickAccount = exports.buildAccountsArray = exports.updateAvatarVisibility = exports.isDev = exports.consoleSink = exports.resetLoggerConfig = exports.getLoggerConfig = exports.configureLogger = exports.createLogger = exports.logger = exports.normalizeMultilineText = exports.normalizeInlineText = exports.validateAndSanitizeUserInput = exports.isValidObjectId = exports.sanitizeHTML = exports.sanitizeString = exports.isValidFileType = exports.isValidFileSize = exports.isValidDate = exports.isValidURL = exports.isValidUUID = exports.isValidObject = exports.isValidArray = exports.isRequiredBoolean = exports.isRequiredNumber = exports.isRequiredString = exports.DISPLAY_NAME_ORPHANED_MARK_SOURCE = exports.DISPLAY_NAME_DISALLOWED_SOURCE = exports.DISPLAY_NAME_ALLOWED_SCRIPTS = exports.isValidDisplayName = exports.isValidPassword = exports.isValidUsername = exports.isValidEmail = exports.PASSWORD_REGEX = exports.USERNAME_REGEX = exports.EMAIL_REGEX = exports.retryAsync = exports.validateRequiredFields = exports.handleHttpError = exports.createApiError = exports.ErrorCodes = exports.safeJsonParse = exports.buildPaginationParams = void 0;
24
+ exports.packageInfo = exports.runSessionColdBoot = exports.TOKEN_REFRESH_LEAD_MS = exports.startTokenRefreshScheduler = exports.installAuthRefreshHandler = exports.createAuthRefreshHandler = exports.refreshDeviceSecretArm = exports.refreshPersistedSession = exports.AUTH_STATE_STORAGE_KEY = exports.createMemoryAuthStateStore = exports.createNativeAuthStateStore = exports.createWebAuthStateStore = exports.createAccountDialogController = exports.AccountDialogController = exports.switchableAccountIds = exports.projectSwitchableAccounts = exports.accountIdsOf = exports.activeUserOf = exports.activeSessionIdOf = exports.deviceStateToClientSessions = exports.createSessionClient = exports.createSessionClientHost = exports.SessionClient = exports.redeemHubTicketOnHub = exports.syncHubAfterSignIn = exports.parseHubSyncReturnUrl = exports.normalizeOfficialReturnOrigin = exports.isAllowedDeviceJoinOrigin = exports.isOfficialWebOrigin = exports.isLoopbackOrigin = exports.isIdpHubOrigin = exports.buildHubSyncUrl = exports.buildIdpHubOrigin = exports.clearOAuthHandshake = exports.readOAuthHandshake = exports.persistOAuthHandshake = exports.normalizeOAuthRedirectUri = exports.OXY_CROSS_ORIGIN_RESTORE_ATTEMPTED_KEY = exports.OXY_SILENT_OAUTH_ATTEMPTED_KEY = exports.OXY_OAUTH_CODE_VERIFIER_STORAGE_KEY = exports.OXY_OAUTH_STATE_STORAGE_KEY = exports.OXY_AUTHORIZE_URL = exports.DEFAULT_OAUTH_SCOPE = exports.generatePkcePair = exports.generateOAuthState = exports.computeCodeChallenge = exports.buildOAuthAuthorizeUrl = exports.runColdBoot = void 0;
25
25
  // Ensure crypto polyfills are loaded before anything else
26
26
  require("./crypto/polyfill");
27
27
  // ---------------------------------------------------------------------------
@@ -40,6 +40,9 @@ Object.defineProperty(exports, "oxyClient", { enumerable: true, get: function ()
40
40
  // ---------------------------------------------------------------------------
41
41
  var OxyServices_auth_1 = require("./mixins/OxyServices.auth");
42
42
  Object.defineProperty(exports, "ServiceCredentialMismatchError", { enumerable: true, get: function () { return OxyServices_auth_1.ServiceCredentialMismatchError; } });
43
+ var commonsApproval_1 = require("./utils/commonsApproval");
44
+ Object.defineProperty(exports, "getCommonsApprovalBlockingReason", { enumerable: true, get: function () { return commonsApproval_1.getCommonsApprovalBlockingReason; } });
45
+ Object.defineProperty(exports, "parseCommonsApprovalExpiresAt", { enumerable: true, get: function () { return commonsApproval_1.parseCommonsApprovalExpiresAt; } });
43
46
  var OxyServices_appData_1 = require("./mixins/OxyServices.appData");
44
47
  Object.defineProperty(exports, "OxyAppDataIdentifierError", { enumerable: true, get: function () { return OxyServices_appData_1.OxyAppDataIdentifierError; } });
45
48
  // ---------------------------------------------------------------------------
@@ -1,8 +1,11 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.ServiceCredentialMismatchError = void 0;
3
+ exports.ServiceCredentialMismatchError = exports.parseCommonsApprovalExpiresAt = exports.getCommonsApprovalBlockingReason = void 0;
4
4
  exports.OxyServicesAuthMixin = OxyServicesAuthMixin;
5
5
  const contracts_1 = require("@oxyhq/contracts");
6
+ var commonsApproval_1 = require("../utils/commonsApproval");
7
+ Object.defineProperty(exports, "getCommonsApprovalBlockingReason", { enumerable: true, get: function () { return commonsApproval_1.getCommonsApprovalBlockingReason; } });
8
+ Object.defineProperty(exports, "parseCommonsApprovalExpiresAt", { enumerable: true, get: function () { return commonsApproval_1.parseCommonsApprovalExpiresAt; } });
6
9
  const OxyServices_errors_1 = require("../OxyServices.errors");
7
10
  const keyManager_1 = require("../crypto/keyManager");
8
11
  const signatureService_1 = require("../crypto/signatureService");
@@ -186,7 +189,7 @@ function OxyServicesAuthMixin(Base) {
186
189
  * @internal
187
190
  */
188
191
  async _doFetchServiceToken(key, secret, cacheKey, secretBuf) {
189
- const response = await this.makeRequest('POST', '/auth/service-token', { apiKey: key, apiSecret: secret }, { cache: false, retry: false });
192
+ const response = await this.makeRequest('POST', '/auth/service-token', { apiKey: key, apiSecret: secret }, { cache: false, retry: false, skipAuth: true });
190
193
  const expiresAt = Date.now() + response.expiresIn * 1000;
191
194
  // Update the entry in-place so any caller that already grabbed a reference
192
195
  // (via `_serviceTokenCache.get(...)`) sees the fresh state.
@@ -283,7 +286,7 @@ function OxyServicesAuthMixin(Base) {
283
286
  publicKey,
284
287
  signature,
285
288
  timestamp,
286
- }, { cache: false });
289
+ }, { cache: false, skipAuth: true });
287
290
  if (!res || (typeof res === 'object' && Object.keys(res).length === 0)) {
288
291
  throw new OxyServices_errors_1.OxyAuthenticationError('Registration failed', 'REGISTER_FAILED', 400);
289
292
  }
@@ -307,7 +310,7 @@ function OxyServicesAuthMixin(Base) {
307
310
  try {
308
311
  return await this.makeRequest('POST', '/auth/challenge', {
309
312
  publicKey,
310
- }, { cache: false, ...requestOptions });
313
+ }, { cache: false, skipAuth: true, ...requestOptions });
311
314
  }
312
315
  catch (error) {
313
316
  throw this.handleError(error);
@@ -336,7 +339,7 @@ function OxyServicesAuthMixin(Base) {
336
339
  timestamp,
337
340
  deviceName,
338
341
  deviceFingerprint,
339
- }, { cache: false, ...requestOptions });
342
+ }, { cache: false, skipAuth: true, ...requestOptions });
340
343
  // Plant the freshly-minted tokens, mirroring `claimSessionByToken`.
341
344
  // `/auth/verify` returns the first access token (and refresh token) in
342
345
  // its body, so installing it here means callers get an authenticated
@@ -359,7 +362,7 @@ function OxyServicesAuthMixin(Base) {
359
362
  */
360
363
  async checkPublicKeyRegistered(publicKey) {
361
364
  try {
362
- return await this.makeRequest('GET', `/auth/check-publickey/${encodeURIComponent(publicKey)}`, undefined, { cache: false });
365
+ return await this.makeRequest('GET', `/auth/check-publickey/${encodeURIComponent(publicKey)}`, undefined, { cache: false, skipAuth: true });
363
366
  }
364
367
  catch (error) {
365
368
  throw this.handleError(error);
@@ -370,7 +373,12 @@ function OxyServicesAuthMixin(Base) {
370
373
  */
371
374
  async getUserByPublicKey(publicKey) {
372
375
  try {
373
- const user = await this.makeRequest('GET', `/auth/user/${encodeURIComponent(publicKey)}`, undefined, { cache: true, cacheTTL: 2 * 60 * 1000 });
376
+ const user = await this.makeRequest('GET', `/auth/user/${encodeURIComponent(publicKey)}`, undefined, {
377
+ cache: true,
378
+ cacheTTL: 2 * 60 * 1000,
379
+ // Public lookup by public key (pre-session) — skip the bearer preflight.
380
+ skipAuth: true,
381
+ });
374
382
  return (0, userIdentity_1.normalizeUserIdentity)(user);
375
383
  }
376
384
  catch (error) {
@@ -441,7 +449,9 @@ function OxyServicesAuthMixin(Base) {
441
449
  const res = await this.makeRequest('POST', '/auth/session/claim', {
442
450
  sessionToken,
443
451
  ...(options.deviceFingerprint ? { deviceFingerprint: options.deviceFingerprint } : {}),
444
- }, { cache: false, retry: false });
452
+ },
453
+ // Body-authenticated device-flow claim (no bearer) — skip the preflight.
454
+ { cache: false, retry: false, skipAuth: true });
445
455
  this.setTokens(res.accessToken);
446
456
  return res;
447
457
  }
@@ -525,7 +535,11 @@ function OxyServicesAuthMixin(Base) {
525
535
  // QR. Reuses the platform-safe random generator.
526
536
  const sessionToken = await signatureService_1.SignatureService.generateChallenge();
527
537
  const expiresAt = Date.now() + COMMONS_SIGN_IN_EXPIRY_MS;
528
- const res = await this.makeRequest('POST', '/auth/session/create', { sessionToken, expiresAt, clientId: params.clientId }, { cache: false });
538
+ const res = await this.makeRequest('POST', '/auth/session/create', { sessionToken, expiresAt, clientId: params.clientId },
539
+ // Public/pre-session (no bearer): skip the preflight so a stale
540
+ // near-expiry token cannot re-enter refreshAccessToken while the
541
+ // refresh handler is already in flight (self-await hang).
542
+ { cache: false, skipAuth: true });
529
543
  return {
530
544
  sessionToken,
531
545
  authorizeCode: res.authorizeCode,
@@ -549,7 +563,11 @@ function OxyServicesAuthMixin(Base) {
549
563
  */
550
564
  async pollCommonsSignIn(sessionToken) {
551
565
  try {
552
- return await this.makeRequest('GET', `/auth/session/status/${encodeURIComponent(sessionToken)}`, undefined, { cache: false, retry: false });
566
+ return await this.makeRequest('GET', `/auth/session/status/${encodeURIComponent(sessionToken)}`, undefined,
567
+ // Public/pre-session (no bearer): a preflight here is wrong per se and,
568
+ // if ever reached while a refresh is pending, would re-enter
569
+ // refreshAccessToken and await the very promise it runs inside.
570
+ { cache: false, retry: false, skipAuth: true });
553
571
  }
554
572
  catch (error) {
555
573
  throw this.handleError(error);
@@ -567,7 +585,10 @@ function OxyServicesAuthMixin(Base) {
567
585
  */
568
586
  async getCommonsApprovalInfo(authorizeCode) {
569
587
  try {
570
- const raw = await this.makeRequest('GET', `/auth/session/approve-info/${encodeURIComponent(authorizeCode)}`, undefined, { cache: false });
588
+ const raw = await this.makeRequest('GET', `/auth/session/approve-info/${encodeURIComponent(authorizeCode)}`, undefined,
589
+ // Public (no auth required) — skip the bearer preflight (avoids the
590
+ // pre-session self-await class).
591
+ { cache: false, skipAuth: true });
571
592
  return {
572
593
  application: raw.application,
573
594
  scopes: raw.scopes,
@@ -614,7 +635,9 @@ function OxyServicesAuthMixin(Base) {
614
635
  timestamp: signed.timestamp,
615
636
  ...(params.deviceName ? { deviceName: params.deviceName } : {}),
616
637
  ...(params.deviceFingerprint ? { deviceFingerprint: params.deviceFingerprint } : {}),
617
- }, { cache: false });
638
+ },
639
+ // Key-signed, cookieless (no bearer) — skip the preflight.
640
+ { cache: false, skipAuth: true });
618
641
  }
619
642
  catch (error) {
620
643
  throw this.handleError(error);
@@ -628,7 +651,9 @@ function OxyServicesAuthMixin(Base) {
628
651
  */
629
652
  async denyCommonsSignIn(authorizeCode) {
630
653
  try {
631
- return await this.makeRequest('POST', `/auth/session/deny/${encodeURIComponent(authorizeCode)}`, undefined, { cache: false });
654
+ return await this.makeRequest('POST', `/auth/session/deny/${encodeURIComponent(authorizeCode)}`, undefined,
655
+ // Public (no auth required) — skip the bearer preflight.
656
+ { cache: false, skipAuth: true });
632
657
  }
633
658
  catch (error) {
634
659
  throw this.handleError(error);
@@ -739,7 +764,8 @@ function OxyServicesAuthMixin(Base) {
739
764
  */
740
765
  async checkUsernameAvailability(username) {
741
766
  try {
742
- return await this.makeRequest('GET', `/auth/check-username/${username}`, undefined, { cache: false });
767
+ // Public availability lookup (pre-session) skip the bearer preflight.
768
+ return await this.makeRequest('GET', `/auth/check-username/${username}`, undefined, { cache: false, skipAuth: true });
743
769
  }
744
770
  catch (error) {
745
771
  throw this.handleError(error);
@@ -750,7 +776,8 @@ function OxyServicesAuthMixin(Base) {
750
776
  */
751
777
  async checkEmailAvailability(email) {
752
778
  try {
753
- return await this.makeRequest('GET', `/auth/check-email/${email}`, undefined, { cache: false });
779
+ // Public availability lookup (pre-session) skip the bearer preflight.
780
+ return await this.makeRequest('GET', `/auth/check-email/${email}`, undefined, { cache: false, skipAuth: true });
754
781
  }
755
782
  catch (error) {
756
783
  throw this.handleError(error);
@@ -769,7 +796,7 @@ function OxyServicesAuthMixin(Base) {
769
796
  */
770
797
  async webauthnRegisterOptions(username) {
771
798
  try {
772
- return await this.makeRequest('POST', '/auth/webauthn/register/options', { ...(username !== undefined ? { username } : {}) }, { cache: false });
799
+ return await this.makeRequest('POST', '/auth/webauthn/register/options', { ...(username !== undefined ? { username } : {}) }, { cache: false, ...(username !== undefined ? { skipAuth: true } : {}) });
773
800
  }
774
801
  catch (error) {
775
802
  throw this.handleError(error);
@@ -790,7 +817,7 @@ function OxyServicesAuthMixin(Base) {
790
817
  */
791
818
  async webauthnRegisterVerify(response, envelope = {}) {
792
819
  try {
793
- const res = await this.makeRequest('POST', '/auth/webauthn/register/verify', { response, ...envelope }, { cache: false });
820
+ const res = await this.makeRequest('POST', '/auth/webauthn/register/verify', { response, ...envelope }, { cache: false, ...(envelope.username !== undefined ? { skipAuth: true } : {}) });
794
821
  if (res && typeof res === 'object') {
795
822
  const record = res;
796
823
  // Signup branch: mints a session (LoginSessionResult, carries
@@ -828,7 +855,9 @@ function OxyServicesAuthMixin(Base) {
828
855
  */
829
856
  async webauthnLoginOptions(username) {
830
857
  try {
831
- return await this.makeRequest('POST', '/auth/webauthn/login/options', { ...(username !== undefined ? { username } : {}) }, { cache: false });
858
+ return await this.makeRequest('POST', '/auth/webauthn/login/options', { ...(username !== undefined ? { username } : {}) },
859
+ // Pre-session login ceremony — skip the bearer preflight.
860
+ { cache: false, skipAuth: true });
832
861
  }
833
862
  catch (error) {
834
863
  throw this.handleError(error);
@@ -844,7 +873,9 @@ function OxyServicesAuthMixin(Base) {
844
873
  */
845
874
  async webauthnLoginVerify(response, envelope = {}) {
846
875
  try {
847
- const res = await this.makeRequest('POST', '/auth/webauthn/login/verify', { response, ...envelope }, { cache: false });
876
+ const res = await this.makeRequest('POST', '/auth/webauthn/login/verify', { response, ...envelope },
877
+ // Pre-session login ceremony — skip the bearer preflight.
878
+ { cache: false, skipAuth: true });
848
879
  const parsed = (0, contracts_1.safeParseContract)(contracts_1.loginResultSchema, res);
849
880
  if (!parsed) {
850
881
  throw new Error('auth/webauthn/login/verify returned an unexpected response shape');
@@ -871,7 +902,7 @@ function OxyServicesAuthMixin(Base) {
871
902
  clientId: params.clientId,
872
903
  redirectUri: params.redirectUri,
873
904
  codeVerifier: params.codeVerifier,
874
- }, { cache: false });
905
+ }, { cache: false, skipAuth: true });
875
906
  const payload = res.data ??
876
907
  res;
877
908
  if (!payload || typeof payload !== 'object') {
@@ -19,7 +19,12 @@ function OxyServicesConnectedAppsMixin(Base) {
19
19
  */
20
20
  async getPublicApplication(clientId) {
21
21
  try {
22
- const res = await this.makeRequest('GET', `/auth/oauth/client/${encodeURIComponent(clientId)}`, undefined, { cache: true, cacheTTL: mixinHelpers_1.CACHE_TIMES.MEDIUM });
22
+ const res = await this.makeRequest('GET', `/auth/oauth/client/${encodeURIComponent(clientId)}`, undefined, {
23
+ cache: true,
24
+ cacheTTL: mixinHelpers_1.CACHE_TIMES.MEDIUM,
25
+ // Public client metadata (pre-session consent UI) — skip the bearer preflight.
26
+ skipAuth: true,
27
+ });
23
28
  return res.application;
24
29
  }
25
30
  catch (error) {
@@ -44,7 +44,11 @@ function OxyServicesDeviceBootMixin(Base) {
44
44
  */
45
45
  async mintFromDeviceSecret(deviceId, deviceSecret) {
46
46
  try {
47
- const res = await this.makeRequest('POST', '/session/device/token', { deviceId, deviceSecret }, { cache: false, skipAuth: true, retry: false });
47
+ const res = await this.makeRequest('POST', '/session/device/token', { deviceId, deviceSecret },
48
+ // `bypassQueue`: this mint is the control-plane call the auth lane
49
+ // depends on — it must run even when every RequestQueue slot is parked
50
+ // awaiting it, or the whole client deadlocks. See RequestOptions.bypassQueue.
51
+ { cache: false, skipAuth: true, retry: false, bypassQueue: true });
48
52
  const parsed = (0, contracts_1.safeParseContract)(contracts_1.deviceTokenMintResponseSchema, res);
49
53
  if (!parsed) {
50
54
  throw new Error('session/device/token returned an unexpected response shape');
@@ -72,7 +76,10 @@ function OxyServicesDeviceBootMixin(Base) {
72
76
  /** Redeem a hub sync ticket for a fresh device secret (public). */
73
77
  async redeemHubTicket(ticket, returnOrigin) {
74
78
  try {
75
- const res = await this.makeRequest('POST', '/session/device/redeem-ticket', { ticket, returnOrigin }, { cache: false, skipAuth: true });
79
+ const res = await this.makeRequest('POST', '/session/device/redeem-ticket', { ticket, returnOrigin },
80
+ // Public device-hub sync mint (bearer-less). Same control-plane class as
81
+ // the device-secret mint — bypassQueue so it never waits for a slot.
82
+ { cache: false, skipAuth: true, bypassQueue: true });
76
83
  const parsed = (0, contracts_1.safeParseContract)(contracts_1.deviceHubTicketRedeemResponseSchema, res);
77
84
  if (!parsed) {
78
85
  throw new Error('session/device/redeem-ticket returned an unexpected response shape');
@@ -141,6 +141,17 @@ function OxyServicesIdentityBackupMixin(Base) {
141
141
  const aad = buildBackupAad(envelope.version, envelope.publicKeyHint);
142
142
  const plaintext = (0, aead_1.decryptAead)(backupKey, fromHex(envelope.nonce), fromHex(envelope.ciphertext), aad);
143
143
  const payload = JSON.parse(new TextDecoder().decode(plaintext));
144
+ if (!payload.privateKey || !payload.publicKey) {
145
+ throw new Error('Backup payload is missing key material');
146
+ }
147
+ const derivedFromPhrase = await recoveryPhrase_1.RecoveryPhraseService.derivePublicKeyFromPhrase(phrase);
148
+ const derivedFromPrivate = keyManager_1.KeyManager.derivePublicKey(payload.privateKey);
149
+ const phrasePk = derivedFromPhrase.toLowerCase();
150
+ const payloadPk = payload.publicKey.toLowerCase();
151
+ const privatePk = derivedFromPrivate.toLowerCase();
152
+ if (phrasePk !== payloadPk || privatePk !== payloadPk) {
153
+ throw new Error('Backup payload does not match the recovery phrase');
154
+ }
144
155
  // Persist the recovered key. Native-only; refuses to clobber a different
145
156
  // identity unless overwrite — the IdentityAlreadyExistsError propagates.
146
157
  return await keyManager_1.KeyManager.importKeyPair(payload.privateKey, {
@@ -59,6 +59,8 @@ function OxyServicesUserMixin(Base) {
59
59
  return await this.makeRequest('GET', `/auth/lookup/${encodeURIComponent(username)}`, undefined, {
60
60
  cache: true,
61
61
  cacheTTL: 60 * 1000, // 1 minute cache
62
+ // Public login-flow lookup (pre-session) — skip the bearer preflight.
63
+ skipAuth: true,
62
64
  });
63
65
  }
64
66
  /**
@@ -423,6 +425,10 @@ function OxyServicesUserMixin(Base) {
423
425
  const result = await this.makeRequest('PATCH', `/privacy/${id}/privacy`, settings, {
424
426
  cache: false,
425
427
  });
428
+ this.clearCacheByPrefix('GET:/session/user/');
429
+ this.clearCacheByPrefix('GET:/users/me');
430
+ this.clearCacheByPrefix('GET:/profiles/username/');
431
+ this.clearCacheEntry(`GET:/users/${id}`);
426
432
  this.clearCacheEntry(`GET:/privacy/${id}/privacy`);
427
433
  return result;
428
434
  }
@@ -36,6 +36,13 @@
36
36
  * password, social login, and 2FA were removed ecosystem-wide. Account
37
37
  * creation (`signup` view) is the same two identity backends: a passkey
38
38
  * ceremony on web, or a Commons-created identity.
39
+ *
40
+ * The controller owns NO surface PRESENTATION: whether the account dialog is
41
+ * mounted, visible, or dismissed is the job of the shared surface stack
42
+ * (`@oxyhq/services` presents the `AccountDialog` surface into `@oxyhq/bloom`'s
43
+ * stack). This is a headless state machine only — it exposes `setView` /
44
+ * `add` / `startSignup` (the view axis) and `cancelSignIn` (device-flow
45
+ * teardown), never an `open` / `close` / `visible`.
39
46
  */
40
47
  Object.defineProperty(exports, "__esModule", { value: true });
41
48
  exports.AccountDialogController = void 0;
@@ -252,11 +259,6 @@ class AccountDialogController {
252
259
  this.view = view;
253
260
  this.emit();
254
261
  }
255
- /** Return to the account list and cancel any in-flight sign-in flow. */
256
- close() {
257
- this.cancelSignIn();
258
- this.setView('accounts');
259
- }
260
262
  /** Switch to the "add account" view (the sign-in entry chooser). */
261
263
  add() {
262
264
  this.setView('add');
@@ -0,0 +1,31 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getCommonsApprovalBlockingReason = getCommonsApprovalBlockingReason;
4
+ exports.parseCommonsApprovalExpiresAt = parseCommonsApprovalExpiresAt;
5
+ /**
6
+ * Returns a user-facing blocking reason when an approval payload must not be
7
+ * shown as actionable, or `null` when the request is still pending and valid.
8
+ */
9
+ function getCommonsApprovalBlockingReason(info) {
10
+ if (!info.application?.id) {
11
+ return 'The requesting application could not be resolved.';
12
+ }
13
+ if (info.status !== 'pending') {
14
+ return 'This sign-in request is invalid, already used, or expired.';
15
+ }
16
+ const expiresAtMs = parseCommonsApprovalExpiresAt(info.expiresAt);
17
+ if (expiresAtMs !== null && expiresAtMs < Date.now()) {
18
+ return 'This sign-in request has expired. Ask for a new QR code.';
19
+ }
20
+ return null;
21
+ }
22
+ /** Normalize API `expiresAt` (number or ISO string) to epoch ms. */
23
+ function parseCommonsApprovalExpiresAt(expiresAt) {
24
+ if (typeof expiresAt === 'number' && Number.isFinite(expiresAt))
25
+ return expiresAt;
26
+ if (typeof expiresAt === 'string') {
27
+ const ms = Date.parse(expiresAt);
28
+ return Number.isFinite(ms) ? ms : null;
29
+ }
30
+ return null;
31
+ }