@oxyhq/core 5.5.0 → 7.0.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 (196) hide show
  1. package/dist/cjs/.tsbuildinfo +1 -1
  2. package/dist/cjs/HttpService.js +7 -4
  3. package/dist/cjs/OxyServices.base.js +7 -102
  4. package/dist/cjs/boot/coldBootV2.js +350 -0
  5. package/dist/cjs/boot/deviceBootReturn.js +152 -0
  6. package/dist/cjs/crypto/keyManager.js +95 -0
  7. package/dist/cjs/i18n/locales/en-US.json +13 -1
  8. package/dist/cjs/i18n/locales/es-ES.json +13 -1
  9. package/dist/cjs/i18n/locales/locales/en-US.json +13 -1
  10. package/dist/cjs/i18n/locales/locales/es-ES.json +13 -1
  11. package/dist/cjs/index.js +54 -45
  12. package/dist/cjs/mixins/OxyServices.accounts.js +13 -26
  13. package/dist/cjs/mixins/OxyServices.auth.js +66 -201
  14. package/dist/cjs/mixins/OxyServices.deviceBoot.js +119 -0
  15. package/dist/cjs/mixins/index.js +8 -17
  16. package/dist/cjs/server/index.js +2 -2
  17. package/dist/cjs/session/SessionClient.js +40 -1
  18. package/dist/cjs/session/authStateStore.js +284 -0
  19. package/dist/cjs/session/refresh.js +264 -0
  20. package/dist/cjs/shared/utils/debugUtils.js +3 -3
  21. package/dist/cjs/utils/accountUtils.js +1 -55
  22. package/dist/cjs/utils/authWebUrl.js +10 -39
  23. package/dist/cjs/utils/coldBoot.js +10 -8
  24. package/dist/cjs/utils/platform.js +19 -0
  25. package/dist/cjs/utils/registrableApex.js +49 -0
  26. package/dist/cjs/utils/ssoBounce.js +15 -362
  27. package/dist/cjs/utils/validationUtils.js +57 -0
  28. package/dist/esm/.tsbuildinfo +1 -1
  29. package/dist/esm/HttpService.js +7 -4
  30. package/dist/esm/OxyServices.base.js +7 -102
  31. package/dist/esm/boot/coldBootV2.js +344 -0
  32. package/dist/esm/boot/deviceBootReturn.js +146 -0
  33. package/dist/esm/crypto/keyManager.js +95 -0
  34. package/dist/esm/i18n/locales/en-US.json +13 -1
  35. package/dist/esm/i18n/locales/es-ES.json +13 -1
  36. package/dist/esm/i18n/locales/locales/en-US.json +13 -1
  37. package/dist/esm/i18n/locales/locales/es-ES.json +13 -1
  38. package/dist/esm/index.js +34 -17
  39. package/dist/esm/mixins/OxyServices.accounts.js +13 -26
  40. package/dist/esm/mixins/OxyServices.auth.js +66 -201
  41. package/dist/esm/mixins/OxyServices.deviceBoot.js +116 -0
  42. package/dist/esm/mixins/index.js +8 -17
  43. package/dist/esm/server/index.js +1 -1
  44. package/dist/esm/session/SessionClient.js +40 -1
  45. package/dist/esm/session/authStateStore.js +278 -0
  46. package/dist/esm/session/refresh.js +257 -0
  47. package/dist/esm/shared/utils/debugUtils.js +3 -3
  48. package/dist/esm/utils/accountUtils.js +0 -53
  49. package/dist/esm/utils/authWebUrl.js +9 -37
  50. package/dist/esm/utils/coldBoot.js +10 -8
  51. package/dist/esm/utils/platform.js +18 -0
  52. package/dist/esm/utils/registrableApex.js +46 -0
  53. package/dist/esm/utils/ssoBounce.js +14 -345
  54. package/dist/esm/utils/validationUtils.js +56 -0
  55. package/dist/types/.tsbuildinfo +1 -1
  56. package/dist/types/HttpService.d.ts +14 -1
  57. package/dist/types/OxyServices.base.d.ts +0 -52
  58. package/dist/types/OxyServices.d.ts +0 -25
  59. package/dist/types/boot/coldBootV2.d.ts +76 -0
  60. package/dist/types/boot/deviceBootReturn.d.ts +83 -0
  61. package/dist/types/crypto/keyManager.d.ts +21 -0
  62. package/dist/types/index.d.ts +14 -21
  63. package/dist/types/mixins/OxyServices.accounts.d.ts +24 -29
  64. package/dist/types/mixins/OxyServices.analytics.d.ts +0 -2
  65. package/dist/types/mixins/OxyServices.appData.d.ts +0 -2
  66. package/dist/types/mixins/OxyServices.assets.d.ts +0 -2
  67. package/dist/types/mixins/OxyServices.auth.d.ts +35 -77
  68. package/dist/types/mixins/OxyServices.civic.d.ts +0 -2
  69. package/dist/types/mixins/OxyServices.connectedApps.d.ts +0 -2
  70. package/dist/types/mixins/OxyServices.contacts.d.ts +0 -2
  71. package/dist/types/mixins/OxyServices.deviceBoot.d.ts +110 -0
  72. package/dist/types/mixins/OxyServices.devices.d.ts +0 -2
  73. package/dist/types/mixins/OxyServices.features.d.ts +0 -2
  74. package/dist/types/mixins/OxyServices.identity.d.ts +0 -2
  75. package/dist/types/mixins/OxyServices.language.d.ts +0 -2
  76. package/dist/types/mixins/OxyServices.links.d.ts +0 -2
  77. package/dist/types/mixins/OxyServices.location.d.ts +0 -2
  78. package/dist/types/mixins/OxyServices.nodes.d.ts +0 -2
  79. package/dist/types/mixins/OxyServices.payment.d.ts +0 -2
  80. package/dist/types/mixins/OxyServices.privacy.d.ts +0 -2
  81. package/dist/types/mixins/OxyServices.reputation.d.ts +0 -2
  82. package/dist/types/mixins/OxyServices.security.d.ts +0 -2
  83. package/dist/types/mixins/OxyServices.topics.d.ts +0 -2
  84. package/dist/types/mixins/OxyServices.user.d.ts +0 -2
  85. package/dist/types/mixins/OxyServices.utility.d.ts +0 -2
  86. package/dist/types/mixins/index.d.ts +5 -9
  87. package/dist/types/models/interfaces.d.ts +0 -67
  88. package/dist/types/models/session.d.ts +4 -5
  89. package/dist/types/server/index.d.ts +1 -1
  90. package/dist/types/session/SessionClient.d.ts +26 -1
  91. package/dist/types/session/authStateStore.d.ts +119 -0
  92. package/dist/types/session/refresh.d.ts +93 -0
  93. package/dist/types/shared/utils/debugUtils.d.ts +3 -3
  94. package/dist/types/utils/accountUtils.d.ts +2 -17
  95. package/dist/types/utils/authWebUrl.d.ts +9 -35
  96. package/dist/types/utils/coldBoot.d.ts +17 -14
  97. package/dist/types/utils/platform.d.ts +14 -0
  98. package/dist/types/utils/registrableApex.d.ts +31 -0
  99. package/dist/types/utils/ssoBounce.d.ts +14 -280
  100. package/dist/types/utils/validationUtils.d.ts +15 -0
  101. package/package.json +2 -2
  102. package/src/HttpService.ts +20 -4
  103. package/src/OxyServices.base.ts +7 -112
  104. package/src/OxyServices.ts +0 -38
  105. package/src/boot/__tests__/coldBootV2.test.ts +317 -0
  106. package/src/boot/__tests__/deviceBootReturn.test.ts +158 -0
  107. package/src/boot/coldBootV2.ts +426 -0
  108. package/src/boot/deviceBootReturn.ts +195 -0
  109. package/src/crypto/__tests__/sharedDeviceToken.test.ts +24 -0
  110. package/src/crypto/keyManager.ts +101 -0
  111. package/src/i18n/locales/en-US.json +13 -1
  112. package/src/i18n/locales/es-ES.json +13 -1
  113. package/src/index.ts +75 -65
  114. package/src/mixins/OxyServices.accounts.ts +27 -39
  115. package/src/mixins/OxyServices.auth.ts +78 -253
  116. package/src/mixins/OxyServices.deviceBoot.ts +146 -0
  117. package/src/mixins/__tests__/OxyServices.deviceBoot.test.ts +107 -0
  118. package/src/mixins/__tests__/accounts.test.ts +17 -44
  119. package/src/mixins/__tests__/passwordSignIn.test.ts +91 -0
  120. package/src/mixins/index.ts +10 -23
  121. package/src/models/interfaces.ts +0 -79
  122. package/src/models/session.ts +4 -5
  123. package/src/server/index.ts +1 -1
  124. package/src/session/SessionClient.ts +53 -2
  125. package/src/session/__tests__/SessionClient.additive.test.ts +92 -0
  126. package/src/session/__tests__/SessionClient.rest.test.ts +25 -0
  127. package/src/session/__tests__/SessionClient.state.test.ts +18 -5
  128. package/src/session/__tests__/authStateStore.test.ts +209 -0
  129. package/src/session/__tests__/refresh.test.ts +256 -0
  130. package/src/session/authStateStore.ts +335 -0
  131. package/src/session/refresh.ts +334 -0
  132. package/src/shared/utils/debugUtils.ts +3 -3
  133. package/src/utils/__tests__/authWebUrl.test.ts +5 -40
  134. package/src/utils/__tests__/registrableApex.test.ts +62 -0
  135. package/src/utils/__tests__/validationUtils.test.ts +30 -0
  136. package/src/utils/accountUtils.ts +2 -65
  137. package/src/utils/authWebUrl.ts +9 -39
  138. package/src/utils/coldBoot.ts +17 -14
  139. package/src/utils/platform.ts +21 -0
  140. package/src/utils/registrableApex.ts +45 -0
  141. package/src/utils/ssoBounce.ts +14 -393
  142. package/src/utils/validationUtils.ts +62 -0
  143. package/dist/cjs/AuthManager.js +0 -1110
  144. package/dist/cjs/AuthManagerTypes.js +0 -13
  145. package/dist/cjs/CrossDomainAuth.js +0 -206
  146. package/dist/cjs/mixins/OxyServices.fedcm.js +0 -823
  147. package/dist/cjs/mixins/OxyServices.redirect.js +0 -95
  148. package/dist/cjs/mixins/OxyServices.silent.js +0 -204
  149. package/dist/cjs/mixins/OxyServices.sso.js +0 -208
  150. package/dist/cjs/utils/fapiAutoDetect.js +0 -99
  151. package/dist/cjs/utils/ssoEstablish.js +0 -110
  152. package/dist/cjs/utils/ssoReturn.js +0 -275
  153. package/dist/esm/AuthManager.js +0 -1105
  154. package/dist/esm/AuthManagerTypes.js +0 -12
  155. package/dist/esm/CrossDomainAuth.js +0 -201
  156. package/dist/esm/mixins/OxyServices.fedcm.js +0 -821
  157. package/dist/esm/mixins/OxyServices.redirect.js +0 -92
  158. package/dist/esm/mixins/OxyServices.silent.js +0 -202
  159. package/dist/esm/mixins/OxyServices.sso.js +0 -204
  160. package/dist/esm/utils/fapiAutoDetect.js +0 -95
  161. package/dist/esm/utils/ssoEstablish.js +0 -107
  162. package/dist/esm/utils/ssoReturn.js +0 -271
  163. package/dist/types/AuthManager.d.ts +0 -380
  164. package/dist/types/AuthManagerTypes.d.ts +0 -81
  165. package/dist/types/CrossDomainAuth.d.ts +0 -164
  166. package/dist/types/mixins/OxyServices.fedcm.d.ts +0 -331
  167. package/dist/types/mixins/OxyServices.redirect.d.ts +0 -92
  168. package/dist/types/mixins/OxyServices.silent.d.ts +0 -132
  169. package/dist/types/mixins/OxyServices.sso.d.ts +0 -138
  170. package/dist/types/utils/fapiAutoDetect.d.ts +0 -56
  171. package/dist/types/utils/ssoEstablish.d.ts +0 -85
  172. package/dist/types/utils/ssoReturn.d.ts +0 -156
  173. package/src/AuthManager.ts +0 -1269
  174. package/src/AuthManagerTypes.ts +0 -86
  175. package/src/CrossDomainAuth.ts +0 -243
  176. package/src/__tests__/authManager.cookiePath.test.ts +0 -390
  177. package/src/__tests__/authManager.security.test.ts +0 -377
  178. package/src/__tests__/crossDomainAuth.test.ts +0 -116
  179. package/src/__tests__/establishDeviceRefreshSlot.test.ts +0 -221
  180. package/src/mixins/OxyServices.fedcm.ts +0 -1026
  181. package/src/mixins/OxyServices.redirect.ts +0 -122
  182. package/src/mixins/OxyServices.silent.ts +0 -272
  183. package/src/mixins/OxyServices.sso.ts +0 -261
  184. package/src/mixins/__tests__/constructorAuthWebUrl.test.ts +0 -85
  185. package/src/mixins/__tests__/fedcm.test.ts +0 -667
  186. package/src/mixins/__tests__/sessionBaseUrl.test.ts +0 -61
  187. package/src/mixins/__tests__/silent.test.ts +0 -102
  188. package/src/mixins/__tests__/sso.test.ts +0 -228
  189. package/src/utils/__tests__/consumeSsoReturn.test.ts +0 -816
  190. package/src/utils/__tests__/fapiAutoDetect.test.ts +0 -183
  191. package/src/utils/__tests__/ssoBounce.test.ts +0 -219
  192. package/src/utils/__tests__/ssoEstablish.test.ts +0 -204
  193. package/src/utils/__tests__/ssoReturn.test.ts +0 -276
  194. package/src/utils/fapiAutoDetect.ts +0 -91
  195. package/src/utils/ssoEstablish.ts +0 -174
  196. package/src/utils/ssoReturn.ts +0 -389
@@ -57,6 +57,11 @@ const STORAGE_KEYS = {
57
57
  SHARED_PUBLIC_KEY: 'oxy_shared_identity_public_key',
58
58
  SHARED_SESSION_TOKEN: 'oxy_shared_session_token',
59
59
  SHARED_SESSION_ID: 'oxy_shared_session_id',
60
+ // Opaque device-attribution token, shared across all Oxy apps on one device
61
+ // so they all resolve to a SINGLE server-side DeviceSession (device-first
62
+ // session model). Add-only: it never carries session state, only attributes
63
+ // a newly-credentialed session to the shared device set.
64
+ SHARED_DEVICE_TOKEN: 'oxy_shared_device_token',
60
65
  };
61
66
  /**
62
67
  * iOS Keychain Access Group for sharing identities across Oxy apps
@@ -544,6 +549,96 @@ class KeyManager {
544
549
  return false;
545
550
  }
546
551
  }
552
+ /**
553
+ * Store the opaque device-attribution token in the SHARED keychain so every
554
+ * Oxy app on this device reads the SAME token and therefore resolves to one
555
+ * server-side DeviceSession.
556
+ *
557
+ * Mirrors the shared-session storage options exactly (iOS keychain access
558
+ * group `group.so.oxy.shared`; Android shared secure store). Native-only —
559
+ * a no-op on web (the shared keychain does not exist there; web persists its
560
+ * deviceToken in the per-origin {@link AuthStateStore} instead).
561
+ */
562
+ static async setSharedDeviceToken(deviceToken) {
563
+ if (isWebPlatform()) {
564
+ return; // Not supported on web
565
+ }
566
+ try {
567
+ const store = await initSecureStore();
568
+ if ((0, platform_1.isIOS)()) {
569
+ const opts = {
570
+ keychainAccessible: store.WHEN_UNLOCKED,
571
+ keychainAccessGroup: IOS_KEYCHAIN_GROUP,
572
+ };
573
+ await store.setItemAsync(STORAGE_KEYS.SHARED_DEVICE_TOKEN, deviceToken, opts);
574
+ }
575
+ else if ((0, platform_1.isAndroid)()) {
576
+ await store.setItemAsync(STORAGE_KEYS.SHARED_DEVICE_TOKEN, deviceToken);
577
+ }
578
+ if ((0, debugUtils_1.isDev)()) {
579
+ loggerUtils_1.logger.debug('Shared device token stored successfully', { component: 'KeyManager' });
580
+ }
581
+ }
582
+ catch (error) {
583
+ if ((0, debugUtils_1.isDev)()) {
584
+ loggerUtils_1.logger.error('Failed to store shared device token', error, { component: 'KeyManager' });
585
+ }
586
+ throw error;
587
+ }
588
+ }
589
+ /**
590
+ * Read the shared device-attribution token, or `null` when none is set (or
591
+ * on web). Mirrors {@link getSharedSession}'s keychain-access-group read.
592
+ */
593
+ static async getSharedDeviceToken() {
594
+ if (isWebPlatform()) {
595
+ return null;
596
+ }
597
+ try {
598
+ const store = await initSecureStore();
599
+ if ((0, platform_1.isIOS)()) {
600
+ const opts = { keychainAccessGroup: IOS_KEYCHAIN_GROUP };
601
+ return await store.getItemAsync(STORAGE_KEYS.SHARED_DEVICE_TOKEN, opts);
602
+ }
603
+ if ((0, platform_1.isAndroid)()) {
604
+ return await store.getItemAsync(STORAGE_KEYS.SHARED_DEVICE_TOKEN);
605
+ }
606
+ return null;
607
+ }
608
+ catch (error) {
609
+ if ((0, debugUtils_1.isDev)()) {
610
+ loggerUtils_1.logger.warn('Failed to get shared device token', { component: 'KeyManager' }, error);
611
+ }
612
+ return null;
613
+ }
614
+ }
615
+ /**
616
+ * Delete the shared device-attribution token (device signout-all). Best-effort:
617
+ * a keychain failure is logged, not thrown, so it cannot block a sign-out.
618
+ */
619
+ static async clearSharedDeviceToken() {
620
+ if (isWebPlatform()) {
621
+ return;
622
+ }
623
+ try {
624
+ const store = await initSecureStore();
625
+ if ((0, platform_1.isIOS)()) {
626
+ const opts = { keychainAccessGroup: IOS_KEYCHAIN_GROUP };
627
+ await store.deleteItemAsync(STORAGE_KEYS.SHARED_DEVICE_TOKEN, opts);
628
+ }
629
+ else if ((0, platform_1.isAndroid)()) {
630
+ await store.deleteItemAsync(STORAGE_KEYS.SHARED_DEVICE_TOKEN);
631
+ }
632
+ if ((0, debugUtils_1.isDev)()) {
633
+ loggerUtils_1.logger.debug('Shared device token cleared successfully', { component: 'KeyManager' });
634
+ }
635
+ }
636
+ catch (error) {
637
+ if ((0, debugUtils_1.isDev)()) {
638
+ loggerUtils_1.logger.error('Failed to clear shared device token', error, { component: 'KeyManager' });
639
+ }
640
+ }
641
+ }
547
642
  // ==================== END SHARED IDENTITY METHODS ====================
548
643
  /**
549
644
  * Atomically persist a key pair to secure storage with verification + backup.
@@ -2,6 +2,13 @@
2
2
  "signin": {
3
3
  "title": "Sign In",
4
4
  "subtitle": "Sign in to continue your journey",
5
+ "chooser": {
6
+ "title": "Choose an account",
7
+ "subtitle": "Continue as an account below, or use another.",
8
+ "signedIn": "Signed in",
9
+ "useAnother": "Use another account",
10
+ "continueAs": "Continue as {{name}}"
11
+ },
5
12
  "addAccountTitle": "Add Another Account",
6
13
  "addAccountSubtitle": "Sign in with another account",
7
14
  "username": {
@@ -602,6 +609,7 @@
602
609
  "editProfile": {
603
610
  "title": "Edit Profile",
604
611
  "subtitle": "Manage your profile and preferences",
612
+ "notSet": "Not set",
605
613
  "sections": {
606
614
  "profilePicture": "Profile Picture",
607
615
  "basicInfo": "Basic Information",
@@ -610,6 +618,9 @@
610
618
  "security": "Security"
611
619
  },
612
620
  "items": {
621
+ "avatar": {
622
+ "subtitle": "Update your profile photo"
623
+ },
613
624
  "displayName": {
614
625
  "title": "Display Name",
615
626
  "subtitle": "This is how your name will appear to others",
@@ -617,7 +628,8 @@
617
628
  "firstName": "First Name",
618
629
  "firstNamePlaceholder": "Enter first name",
619
630
  "lastName": "Last Name",
620
- "lastNamePlaceholder": "Enter last name (optional)"
631
+ "lastNamePlaceholder": "Enter last name (optional)",
632
+ "invalidChars": "Use letters and spaces only"
621
633
  },
622
634
  "username": {
623
635
  "title": "Username",
@@ -2,6 +2,13 @@
2
2
  "signin": {
3
3
  "title": "Iniciar sesión",
4
4
  "subtitle": "Inicia sesión para continuar",
5
+ "chooser": {
6
+ "title": "Elige una cuenta",
7
+ "subtitle": "Continúa con una de tus cuentas o usa otra.",
8
+ "signedIn": "Sesión activa",
9
+ "useAnother": "Usar otra cuenta",
10
+ "continueAs": "Continuar como {{name}}"
11
+ },
5
12
  "addAccountTitle": "Agregar otra cuenta",
6
13
  "addAccountSubtitle": "Inicia sesión con otra cuenta",
7
14
  "username": {
@@ -152,6 +159,7 @@
152
159
  "editProfile": {
153
160
  "title": "Editar perfil",
154
161
  "subtitle": "Gestiona tu perfil y preferencias",
162
+ "notSet": "Sin definir",
155
163
  "sections": {
156
164
  "profilePicture": "Foto de perfil",
157
165
  "basicInfo": "Información básica",
@@ -160,6 +168,9 @@
160
168
  "security": "Seguridad"
161
169
  },
162
170
  "items": {
171
+ "avatar": {
172
+ "subtitle": "Actualiza tu foto de perfil"
173
+ },
163
174
  "displayName": {
164
175
  "title": "Nombre para mostrar",
165
176
  "subtitle": "Así aparecerá tu nombre para los demás",
@@ -167,7 +178,8 @@
167
178
  "firstName": "Nombre",
168
179
  "firstNamePlaceholder": "Introduce tu nombre",
169
180
  "lastName": "Apellido",
170
- "lastNamePlaceholder": "Introduce tu apellido (opcional)"
181
+ "lastNamePlaceholder": "Introduce tu apellido (opcional)",
182
+ "invalidChars": "Usa solo letras y espacios"
171
183
  },
172
184
  "username": {
173
185
  "title": "Usuario",
@@ -2,6 +2,13 @@
2
2
  "signin": {
3
3
  "title": "Sign In",
4
4
  "subtitle": "Sign in to continue your journey",
5
+ "chooser": {
6
+ "title": "Choose an account",
7
+ "subtitle": "Continue as an account below, or use another.",
8
+ "signedIn": "Signed in",
9
+ "useAnother": "Use another account",
10
+ "continueAs": "Continue as {{name}}"
11
+ },
5
12
  "addAccountTitle": "Add Another Account",
6
13
  "addAccountSubtitle": "Sign in with another account",
7
14
  "username": {
@@ -602,6 +609,7 @@
602
609
  "editProfile": {
603
610
  "title": "Edit Profile",
604
611
  "subtitle": "Manage your profile and preferences",
612
+ "notSet": "Not set",
605
613
  "sections": {
606
614
  "profilePicture": "Profile Picture",
607
615
  "basicInfo": "Basic Information",
@@ -610,6 +618,9 @@
610
618
  "security": "Security"
611
619
  },
612
620
  "items": {
621
+ "avatar": {
622
+ "subtitle": "Update your profile photo"
623
+ },
613
624
  "displayName": {
614
625
  "title": "Display Name",
615
626
  "subtitle": "This is how your name will appear to others",
@@ -617,7 +628,8 @@
617
628
  "firstName": "First Name",
618
629
  "firstNamePlaceholder": "Enter first name",
619
630
  "lastName": "Last Name",
620
- "lastNamePlaceholder": "Enter last name (optional)"
631
+ "lastNamePlaceholder": "Enter last name (optional)",
632
+ "invalidChars": "Use letters and spaces only"
621
633
  },
622
634
  "username": {
623
635
  "title": "Username",
@@ -2,6 +2,13 @@
2
2
  "signin": {
3
3
  "title": "Iniciar sesión",
4
4
  "subtitle": "Inicia sesión para continuar",
5
+ "chooser": {
6
+ "title": "Elige una cuenta",
7
+ "subtitle": "Continúa con una de tus cuentas o usa otra.",
8
+ "signedIn": "Sesión activa",
9
+ "useAnother": "Usar otra cuenta",
10
+ "continueAs": "Continuar como {{name}}"
11
+ },
5
12
  "addAccountTitle": "Agregar otra cuenta",
6
13
  "addAccountSubtitle": "Inicia sesión con otra cuenta",
7
14
  "username": {
@@ -152,6 +159,7 @@
152
159
  "editProfile": {
153
160
  "title": "Editar perfil",
154
161
  "subtitle": "Gestiona tu perfil y preferencias",
162
+ "notSet": "Sin definir",
155
163
  "sections": {
156
164
  "profilePicture": "Foto de perfil",
157
165
  "basicInfo": "Información básica",
@@ -160,6 +168,9 @@
160
168
  "security": "Seguridad"
161
169
  },
162
170
  "items": {
171
+ "avatar": {
172
+ "subtitle": "Actualiza tu foto de perfil"
173
+ },
163
174
  "displayName": {
164
175
  "title": "Nombre para mostrar",
165
176
  "subtitle": "Así aparecerá tu nombre para los demás",
@@ -167,7 +178,8 @@
167
178
  "firstName": "Nombre",
168
179
  "firstNamePlaceholder": "Introduce tu nombre",
169
180
  "lastName": "Apellido",
170
- "lastNamePlaceholder": "Introduce tu apellido (opcional)"
181
+ "lastNamePlaceholder": "Introduce tu apellido (opcional)",
182
+ "invalidChars": "Usa solo letras y espacios"
171
183
  },
172
184
  "username": {
173
185
  "title": "Usuario",
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.isIOS = exports.isNative = exports.isWeb = exports.setPlatformOS = exports.getPlatformOS = exports.isRTLLocale = exports.normalizeLanguageCode = exports.getNativeLanguageName = exports.getLanguageName = exports.getLanguageMetadata = exports.SUPPORTED_LANGUAGES = exports.TopicSource = exports.TopicType = exports.SECURITY_EVENT_SEVERITY_MAP = exports.DeviceManager = exports.RecoveryPhraseService = exports.SignatureService = 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.normalizeProfileLinks = exports.getNormalizedUserHandle = exports.getCanonicalUserHandle = exports.normalizeUserIdentityOrNull = exports.normalizeUserIdentity = exports.getNormalizedUserId = exports.OxyAppDataIdentifierError = exports.ServiceCredentialMismatchError = exports.createCrossDomainAuth = exports.CrossDomainAuth = exports.createAuthManager = exports.AuthManager = exports.oxyClient = exports.OXY_CLOUD_URL = exports.OxyAuthenticationTimeoutError = exports.OxyAuthenticationError = exports.OxyServices = void 0;
22
- exports.PASSWORD_REGEX = exports.USERNAME_REGEX = exports.EMAIL_REGEX = exports.retryAsync = exports.validateRequiredFields = exports.handleHttpError = exports.createApiError = exports.ErrorCodes = exports.safeJsonParse = exports.buildPaginationParams = exports.buildUrl = exports.buildSearchParams = exports.translate = exports.createDebugLogger = exports.debugError = exports.debugWarn = exports.debugLog = exports.isDev = 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.isAndroid = void 0;
23
- exports.ssoAttemptedKey = exports.ssoNoSessionKey = exports.ssoDestKey = exports.ssoGuardKey = exports.ssoStateKey = exports.SSO_GUARD_TTL_MS = exports.SSO_CALLBACK_PATH = exports.establishIdpSessionAfterClaim = exports.generateSsoState = exports.consumeSsoReturn = exports.parseSsoReturnFragment = exports.resolveCentralAuthUrl = exports.CENTRAL_IDP_APEX = exports.CENTRAL_AUTH_URL = exports.registrableApex = exports.autoDetectAuthWebUrl = exports.getAccountColor = exports.mergeAccountsFromRefreshAll = exports.formatPublicKeyHandle = exports.getAccountFallbackHandle = exports.getAccountDisplayName = exports.createQuickAccount = exports.buildAccountsArray = exports.updateAvatarVisibility = exports.logPerformance = exports.logPayment = exports.logDevice = exports.logUser = exports.logSession = exports.logApi = exports.logAuth = exports.LogLevel = exports.logger = 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.isValidPassword = exports.isValidUsername = exports.isValidEmail = void 0;
24
- exports.packageInfo = exports.accountIdsOf = exports.activeUserOf = exports.activeSessionIdOf = exports.deviceStateToClientSessions = exports.createSessionClient = exports.createSessionClientHost = exports.SessionClient = exports.runColdBoot = exports.allowSsoBounce = exports.silentRestoreSuppressed = exports.guardActive = exports.isCentralIdPOrigin = exports.buildSsoBounceUrl = exports.getSsoCallbackBootstrapScript = exports.ssoNavigate = exports.ssoCallbackBootstrapKey = exports.ssoOutcomeKey = exports.ssoSignedOutKey = exports.ssoPriorSessionKey = void 0;
21
+ exports.lightenColor = exports.darkenColor = exports.isWebBrowser = exports.isAndroid = exports.isIOS = exports.isNative = exports.isWeb = exports.setPlatformOS = exports.getPlatformOS = exports.isRTLLocale = exports.normalizeLanguageCode = exports.getNativeLanguageName = exports.getLanguageName = exports.getLanguageMetadata = exports.SUPPORTED_LANGUAGES = exports.TopicSource = exports.TopicType = exports.SECURITY_EVENT_SEVERITY_MAP = exports.DeviceManager = exports.RecoveryPhraseService = exports.SignatureService = 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.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.OxyServices = void 0;
22
+ 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 = exports.buildUrl = exports.buildSearchParams = exports.translate = exports.createDebugLogger = exports.debugError = exports.debugWarn = exports.debugLog = exports.isDev = 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 = void 0;
23
+ exports.installAuthRefreshHandler = exports.createAuthRefreshHandler = exports.refreshPersistedSession = exports.DEVICE_TOKEN_STORAGE_KEY = exports.AUTH_STATE_STORAGE_KEY = exports.createMemoryAuthStateStore = exports.createNativeAuthStateStore = exports.createWebAuthStateStore = exports.accountIdsOf = exports.activeUserOf = exports.activeSessionIdOf = exports.deviceStateToClientSessions = exports.createSessionClient = exports.createSessionClientHost = exports.SessionClient = exports.runColdBoot = exports.SSO_CALLBACK_PATH = exports.CENTRAL_IDP_APEX = exports.registrableApex = exports.getAccountColor = exports.formatPublicKeyHandle = exports.getAccountFallbackHandle = exports.getAccountDisplayName = exports.createQuickAccount = exports.buildAccountsArray = exports.updateAvatarVisibility = exports.logPerformance = exports.logPayment = exports.logDevice = exports.logUser = exports.logSession = exports.logApi = exports.logAuth = exports.LogLevel = exports.logger = 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.isValidDisplayName = void 0;
24
+ exports.packageInfo = exports.BOOT_STATE_SESSION_KEY = exports.BOOT_FRAGMENT_PARAM = exports.hashHasBootFragment = exports.parseDeviceBootFragment = exports.consumeDeviceBootReturn = exports.BOOT_ATTEMPTED_KEY = exports.isSameApex = exports.createBrowserColdBootDom = exports.runSessionColdBoot = exports.TOKEN_REFRESH_LEAD_MS = exports.startTokenRefreshScheduler = void 0;
25
25
  // Ensure crypto polyfills are loaded before anything else
26
26
  require("./crypto/polyfill");
27
27
  // ---------------------------------------------------------------------------
@@ -37,12 +37,6 @@ Object.defineProperty(exports, "oxyClient", { enumerable: true, get: function ()
37
37
  // ---------------------------------------------------------------------------
38
38
  // Authentication
39
39
  // ---------------------------------------------------------------------------
40
- var AuthManager_1 = require("./AuthManager");
41
- Object.defineProperty(exports, "AuthManager", { enumerable: true, get: function () { return AuthManager_1.AuthManager; } });
42
- Object.defineProperty(exports, "createAuthManager", { enumerable: true, get: function () { return AuthManager_1.createAuthManager; } });
43
- var CrossDomainAuth_1 = require("./CrossDomainAuth");
44
- Object.defineProperty(exports, "CrossDomainAuth", { enumerable: true, get: function () { return CrossDomainAuth_1.CrossDomainAuth; } });
45
- Object.defineProperty(exports, "createCrossDomainAuth", { enumerable: true, get: function () { return CrossDomainAuth_1.createCrossDomainAuth; } });
46
40
  var OxyServices_auth_1 = require("./mixins/OxyServices.auth");
47
41
  Object.defineProperty(exports, "ServiceCredentialMismatchError", { enumerable: true, get: function () { return OxyServices_auth_1.ServiceCredentialMismatchError; } });
48
42
  var OxyServices_appData_1 = require("./mixins/OxyServices.appData");
@@ -138,6 +132,7 @@ Object.defineProperty(exports, "isWeb", { enumerable: true, get: function () { r
138
132
  Object.defineProperty(exports, "isNative", { enumerable: true, get: function () { return platform_1.isNative; } });
139
133
  Object.defineProperty(exports, "isIOS", { enumerable: true, get: function () { return platform_1.isIOS; } });
140
134
  Object.defineProperty(exports, "isAndroid", { enumerable: true, get: function () { return platform_1.isAndroid; } });
135
+ Object.defineProperty(exports, "isWebBrowser", { enumerable: true, get: function () { return platform_1.isWebBrowser; } });
141
136
  // ---------------------------------------------------------------------------
142
137
  // Colour / theme utilities
143
138
  // ---------------------------------------------------------------------------
@@ -215,6 +210,7 @@ Object.defineProperty(exports, "PASSWORD_REGEX", { enumerable: true, get: functi
215
210
  Object.defineProperty(exports, "isValidEmail", { enumerable: true, get: function () { return validationUtils_1.isValidEmail; } });
216
211
  Object.defineProperty(exports, "isValidUsername", { enumerable: true, get: function () { return validationUtils_1.isValidUsername; } });
217
212
  Object.defineProperty(exports, "isValidPassword", { enumerable: true, get: function () { return validationUtils_1.isValidPassword; } });
213
+ Object.defineProperty(exports, "isValidDisplayName", { enumerable: true, get: function () { return validationUtils_1.isValidDisplayName; } });
218
214
  Object.defineProperty(exports, "isRequiredString", { enumerable: true, get: function () { return validationUtils_1.isRequiredString; } });
219
215
  Object.defineProperty(exports, "isRequiredNumber", { enumerable: true, get: function () { return validationUtils_1.isRequiredNumber; } });
220
216
  Object.defineProperty(exports, "isRequiredBoolean", { enumerable: true, get: function () { return validationUtils_1.isRequiredBoolean; } });
@@ -256,47 +252,27 @@ Object.defineProperty(exports, "createQuickAccount", { enumerable: true, get: fu
256
252
  Object.defineProperty(exports, "getAccountDisplayName", { enumerable: true, get: function () { return accountUtils_1.getAccountDisplayName; } });
257
253
  Object.defineProperty(exports, "getAccountFallbackHandle", { enumerable: true, get: function () { return accountUtils_1.getAccountFallbackHandle; } });
258
254
  Object.defineProperty(exports, "formatPublicKeyHandle", { enumerable: true, get: function () { return accountUtils_1.formatPublicKeyHandle; } });
259
- Object.defineProperty(exports, "mergeAccountsFromRefreshAll", { enumerable: true, get: function () { return accountUtils_1.mergeAccountsFromRefreshAll; } });
260
255
  Object.defineProperty(exports, "getAccountColor", { enumerable: true, get: function () { return accountUtils_1.getAccountColor; } });
261
256
  // ---------------------------------------------------------------------------
262
- // Cross-domain SSO infrastructure
263
- // ---------------------------------------------------------------------------
264
- var fapiAutoDetect_1 = require("./utils/fapiAutoDetect");
265
- Object.defineProperty(exports, "autoDetectAuthWebUrl", { enumerable: true, get: function () { return fapiAutoDetect_1.autoDetectAuthWebUrl; } });
266
- Object.defineProperty(exports, "registrableApex", { enumerable: true, get: function () { return fapiAutoDetect_1.registrableApex; } });
267
- // Central cross-domain SSO (opaque single-use code bounce via auth.oxy.so)
257
+ // Registrable-domain + central-IdP-apex helpers.
258
+ //
259
+ // The client SSO-bounce / silent-iframe / FedCM machinery was removed in the
260
+ // device-first cutover (wave 2, ecosystem-wide bump complete). `registrableApex`
261
+ // (eTLD+1) and `CENTRAL_IDP_APEX` are still genuinely used: `registrableApex`
262
+ // via the `@oxyhq/core/server` re-export consumed by
263
+ // `packages/api/src/utils/sameSite.ts` for same-site origin checks, and
264
+ // `CENTRAL_IDP_APEX` by `server/cors.ts`'s `createOxyCors` (auto-allows
265
+ // `*.oxy.so`). `SSO_CALLBACK_PATH` has no remaining importer outside this
266
+ // module as of wave 2 — kept exported for now rather than removed here (an
267
+ // export deletion is a logic change, out of scope for a comment sweep); flag
268
+ // for a follow-up dead-export cleanup pass.
269
+ // ---------------------------------------------------------------------------
270
+ var registrableApex_1 = require("./utils/registrableApex");
271
+ Object.defineProperty(exports, "registrableApex", { enumerable: true, get: function () { return registrableApex_1.registrableApex; } });
268
272
  var authWebUrl_1 = require("./utils/authWebUrl");
269
- Object.defineProperty(exports, "CENTRAL_AUTH_URL", { enumerable: true, get: function () { return authWebUrl_1.CENTRAL_AUTH_URL; } });
270
273
  Object.defineProperty(exports, "CENTRAL_IDP_APEX", { enumerable: true, get: function () { return authWebUrl_1.CENTRAL_IDP_APEX; } });
271
- Object.defineProperty(exports, "resolveCentralAuthUrl", { enumerable: true, get: function () { return authWebUrl_1.resolveCentralAuthUrl; } });
272
- var ssoReturn_1 = require("./utils/ssoReturn");
273
- Object.defineProperty(exports, "parseSsoReturnFragment", { enumerable: true, get: function () { return ssoReturn_1.parseSsoReturnFragment; } });
274
- Object.defineProperty(exports, "consumeSsoReturn", { enumerable: true, get: function () { return ssoReturn_1.consumeSsoReturn; } });
275
- var OxyServices_sso_1 = require("./mixins/OxyServices.sso");
276
- Object.defineProperty(exports, "generateSsoState", { enumerable: true, get: function () { return OxyServices_sso_1.generateSsoState; } });
277
- // Post-claim durable-session establish hop (web device-flow / QR sign-in).
278
- var ssoEstablish_1 = require("./utils/ssoEstablish");
279
- Object.defineProperty(exports, "establishIdpSessionAfterClaim", { enumerable: true, get: function () { return ssoEstablish_1.establishIdpSessionAfterClaim; } });
280
- // SSO bounce — per-origin sessionStorage keys, bounce URL builder, predicates
281
274
  var ssoBounce_1 = require("./utils/ssoBounce");
282
275
  Object.defineProperty(exports, "SSO_CALLBACK_PATH", { enumerable: true, get: function () { return ssoBounce_1.SSO_CALLBACK_PATH; } });
283
- Object.defineProperty(exports, "SSO_GUARD_TTL_MS", { enumerable: true, get: function () { return ssoBounce_1.SSO_GUARD_TTL_MS; } });
284
- Object.defineProperty(exports, "ssoStateKey", { enumerable: true, get: function () { return ssoBounce_1.ssoStateKey; } });
285
- Object.defineProperty(exports, "ssoGuardKey", { enumerable: true, get: function () { return ssoBounce_1.ssoGuardKey; } });
286
- Object.defineProperty(exports, "ssoDestKey", { enumerable: true, get: function () { return ssoBounce_1.ssoDestKey; } });
287
- Object.defineProperty(exports, "ssoNoSessionKey", { enumerable: true, get: function () { return ssoBounce_1.ssoNoSessionKey; } });
288
- Object.defineProperty(exports, "ssoAttemptedKey", { enumerable: true, get: function () { return ssoBounce_1.ssoAttemptedKey; } });
289
- Object.defineProperty(exports, "ssoPriorSessionKey", { enumerable: true, get: function () { return ssoBounce_1.ssoPriorSessionKey; } });
290
- Object.defineProperty(exports, "ssoSignedOutKey", { enumerable: true, get: function () { return ssoBounce_1.ssoSignedOutKey; } });
291
- Object.defineProperty(exports, "ssoOutcomeKey", { enumerable: true, get: function () { return ssoBounce_1.ssoOutcomeKey; } });
292
- Object.defineProperty(exports, "ssoCallbackBootstrapKey", { enumerable: true, get: function () { return ssoBounce_1.ssoCallbackBootstrapKey; } });
293
- Object.defineProperty(exports, "ssoNavigate", { enumerable: true, get: function () { return ssoBounce_1.ssoNavigate; } });
294
- Object.defineProperty(exports, "getSsoCallbackBootstrapScript", { enumerable: true, get: function () { return ssoBounce_1.getSsoCallbackBootstrapScript; } });
295
- Object.defineProperty(exports, "buildSsoBounceUrl", { enumerable: true, get: function () { return ssoBounce_1.buildSsoBounceUrl; } });
296
- Object.defineProperty(exports, "isCentralIdPOrigin", { enumerable: true, get: function () { return ssoBounce_1.isCentralIdPOrigin; } });
297
- Object.defineProperty(exports, "guardActive", { enumerable: true, get: function () { return ssoBounce_1.guardActive; } });
298
- Object.defineProperty(exports, "silentRestoreSuppressed", { enumerable: true, get: function () { return ssoBounce_1.silentRestoreSuppressed; } });
299
- Object.defineProperty(exports, "allowSsoBounce", { enumerable: true, get: function () { return ssoBounce_1.allowSsoBounce; } });
300
276
  var coldBoot_1 = require("./utils/coldBoot");
301
277
  Object.defineProperty(exports, "runColdBoot", { enumerable: true, get: function () { return coldBoot_1.runColdBoot; } });
302
278
  // ---------------------------------------------------------------------------
@@ -318,6 +294,39 @@ Object.defineProperty(exports, "deviceStateToClientSessions", { enumerable: true
318
294
  Object.defineProperty(exports, "activeSessionIdOf", { enumerable: true, get: function () { return projectSessionState_1.activeSessionIdOf; } });
319
295
  Object.defineProperty(exports, "activeUserOf", { enumerable: true, get: function () { return projectSessionState_1.activeUserOf; } });
320
296
  Object.defineProperty(exports, "accountIdsOf", { enumerable: true, get: function () { return projectSessionState_1.accountIdsOf; } });
297
+ // ---------------------------------------------------------------------------
298
+ // Device-first session machinery (auth centralization, wave 1) — additive.
299
+ // Persisted auth-state store, the unified refresh handler + scheduler, the
300
+ // cold-boot v2 runner, and the device-boot return-fragment consumer. Built ON
301
+ // the existing `runColdBoot` primitive + `SessionClient`; the legacy
302
+ // FedCM/SSO/CrossDomainAuth surface is untouched (cutover happens in F4).
303
+ // ---------------------------------------------------------------------------
304
+ var authStateStore_1 = require("./session/authStateStore");
305
+ Object.defineProperty(exports, "createWebAuthStateStore", { enumerable: true, get: function () { return authStateStore_1.createWebAuthStateStore; } });
306
+ Object.defineProperty(exports, "createNativeAuthStateStore", { enumerable: true, get: function () { return authStateStore_1.createNativeAuthStateStore; } });
307
+ Object.defineProperty(exports, "createMemoryAuthStateStore", { enumerable: true, get: function () { return authStateStore_1.createMemoryAuthStateStore; } });
308
+ Object.defineProperty(exports, "AUTH_STATE_STORAGE_KEY", { enumerable: true, get: function () { return authStateStore_1.AUTH_STATE_STORAGE_KEY; } });
309
+ Object.defineProperty(exports, "DEVICE_TOKEN_STORAGE_KEY", { enumerable: true, get: function () { return authStateStore_1.DEVICE_TOKEN_STORAGE_KEY; } });
310
+ var refresh_1 = require("./session/refresh");
311
+ Object.defineProperty(exports, "refreshPersistedSession", { enumerable: true, get: function () { return refresh_1.refreshPersistedSession; } });
312
+ Object.defineProperty(exports, "createAuthRefreshHandler", { enumerable: true, get: function () { return refresh_1.createAuthRefreshHandler; } });
313
+ Object.defineProperty(exports, "installAuthRefreshHandler", { enumerable: true, get: function () { return refresh_1.installAuthRefreshHandler; } });
314
+ Object.defineProperty(exports, "startTokenRefreshScheduler", { enumerable: true, get: function () { return refresh_1.startTokenRefreshScheduler; } });
315
+ Object.defineProperty(exports, "TOKEN_REFRESH_LEAD_MS", { enumerable: true, get: function () { return refresh_1.TOKEN_REFRESH_LEAD_MS; } });
316
+ var coldBootV2_1 = require("./boot/coldBootV2");
317
+ Object.defineProperty(exports, "runSessionColdBoot", { enumerable: true, get: function () { return coldBootV2_1.runSessionColdBoot; } });
318
+ Object.defineProperty(exports, "createBrowserColdBootDom", { enumerable: true, get: function () { return coldBootV2_1.createBrowserColdBootDom; } });
319
+ Object.defineProperty(exports, "isSameApex", { enumerable: true, get: function () { return coldBootV2_1.isSameApex; } });
320
+ Object.defineProperty(exports, "BOOT_ATTEMPTED_KEY", { enumerable: true, get: function () { return coldBootV2_1.BOOT_ATTEMPTED_KEY; } });
321
+ var deviceBootReturn_1 = require("./boot/deviceBootReturn");
322
+ Object.defineProperty(exports, "consumeDeviceBootReturn", { enumerable: true, get: function () { return deviceBootReturn_1.consumeDeviceBootReturn; } });
323
+ Object.defineProperty(exports, "parseDeviceBootFragment", { enumerable: true, get: function () { return deviceBootReturn_1.parseDeviceBootFragment; } });
324
+ Object.defineProperty(exports, "hashHasBootFragment", { enumerable: true, get: function () { return deviceBootReturn_1.hashHasBootFragment; } });
325
+ Object.defineProperty(exports, "BOOT_FRAGMENT_PARAM", { enumerable: true, get: function () { return deviceBootReturn_1.BOOT_FRAGMENT_PARAM; } });
326
+ Object.defineProperty(exports, "BOOT_STATE_SESSION_KEY", { enumerable: true, get: function () { return deviceBootReturn_1.BOOT_STATE_SESSION_KEY; } });
327
+ // The web-session result contract (`WebSessionResult`) is owned by
328
+ // `@oxyhq/contracts` — import it directly from there; `@oxyhq/core` does not
329
+ // re-export contract types.
321
330
  // API response contracts (request/response Zod schemas + inferred types) live in
322
331
  // `@oxyhq/contracts` — the single source of truth shared by the backend and every
323
332
  // client SDK. Import them directly from `@oxyhq/contracts`; `@oxyhq/core` does NOT
@@ -52,24 +52,18 @@ function OxyServicesAccountsMixin(Base) {
52
52
  * target, directly or inherited — else 403; 404 if missing/archived; 403 if
53
53
  * the target is a personal account), then mints a REAL session for the
54
54
  * target account and returns it in the canonical login / `claimSessionByToken`
55
- * shape (`{ sessionId, deviceId, expiresAt, accessToken, user, authuser }`).
55
+ * shape (`{ sessionId, deviceId, expiresAt, accessToken, user }`).
56
56
  *
57
57
  * Unlike the removed `X-Acting-As` delegation header, the returned session
58
58
  * IS the new identity: this plants `accessToken` as the active token —
59
59
  * exactly like `claimSessionByToken` / `verifyChallenge` — so every
60
60
  * subsequent request authenticates as the target account.
61
61
  *
62
- * Joining the device multi-account set (so the switch survives a reload and
63
- * propagates cross-domain via `/auth/refresh-all`) requires a SECOND call, to
64
- * `POST /auth/session`, made here after the token is planted. The switch route
65
- * lives at `/accounts/*`, OUTSIDE the `oxy_rt_<authuser>` cookie's `Path=/auth`
66
- * scope, so the server never sees the device's existing slots from it and
67
- * would clobber slot 0 (destroying the operator's own session). `/auth/session`
68
- * runs where those cookies ARE visible, so the server allocates a NEW slot that
69
- * coexists with the operator's and returns its `authuser`. This step is
70
- * web-only (native multi-account uses stored sessions, not cookies) and
71
- * best-effort — a failure leaves the in-session switch intact; the switched
72
- * account simply won't survive a reload until the cookie is next established.
62
+ * A single call is all that's needed: the server registers the switched
63
+ * session into the operator's `DeviceSession` set directly, inheriting the
64
+ * operator's central `deviceId` so the switch survives a reload and syncs
65
+ * cross-domain via the same device-first session model as a normal login —
66
+ * there is no separate client-side cookie/slot step to make it stick.
73
67
  *
74
68
  * After planting, the SDK's identity-scoped GET cache is fully cleared so
75
69
  * every cached read re-fetches as the new account. (The consuming
@@ -79,29 +73,22 @@ function OxyServicesAccountsMixin(Base) {
79
73
  * same-user silent refreshes, so the sweep here is explicit.)
80
74
  *
81
75
  * @param accountId - The target account's Mongo `_id`.
82
- * @returns The minted session (planted) plus the device `authuser` slot.
76
+ * @returns The minted session, already planted as the active session.
83
77
  */
84
78
  async switchToAccount(accountId) {
85
79
  try {
86
80
  const res = await this.makeRequest('POST', `/accounts/${encodeURIComponent(accountId)}/switch`, undefined, { cache: false });
87
81
  // Plant the freshly minted session as the ACTIVE session, mirroring
88
82
  // `claimSessionByToken` / `verifyChallenge`: the response body carries
89
- // the first access token. The device refresh cookie is established below.
83
+ // the first access token.
90
84
  if (res?.accessToken) {
91
85
  this.setTokens(res.accessToken);
92
86
  }
93
- // Register the switched session in the device's multi-account set by
94
- // establishing its first-party refresh cookie. This MUST be a separate
95
- // call to `POST /auth/session` (the shared `establishDeviceRefreshSlot`
96
- // primitive): the switch route is at `/accounts/*`, outside the
97
- // `oxy_rt_<authuser>` cookie's `Path=/auth` scope, so it can never read
98
- // the device's existing slots and would overwrite slot 0 (destroying the
99
- // operator's own session). `/auth/session` runs where the cookies ARE
100
- // visible, so the server allocates a NEW slot that coexists with the
101
- // operator's and returns its `authuser`. Web-only; best-effort (the helper
102
- // re-plants the rotated access token and returns `null` on native/failure).
103
- const establishedAuthuser = await this.establishDeviceRefreshSlot();
104
- const authuser = establishedAuthuser ?? res.authuser;
87
+ // The switch route now registers the switched session in the device's
88
+ // server-side DeviceSession set directly (device-first), so there is no
89
+ // client-side refresh-cookie slot to establish the `authuser` comes
90
+ // from the switch response (optional-chained to match `res?.accessToken`).
91
+ const authuser = res?.authuser;
105
92
  // Identity changed → drop the entire GET response cache so no entry
106
93
  // personalised for the previous identity is reused. Cache keys are
107
94
  // identity-scoped, so a different identity could not READ the old