@oxy.so/core 1.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 (673) hide show
  1. package/LICENSE +202 -0
  2. package/NOTICE +16 -0
  3. package/README.md +221 -0
  4. package/dist/cjs/.tsbuildinfo +1 -0
  5. package/dist/cjs/HttpService.js +1270 -0
  6. package/dist/cjs/OxyServices.base.js +390 -0
  7. package/dist/cjs/OxyServices.errors.js +95 -0
  8. package/dist/cjs/OxyServices.js +72 -0
  9. package/dist/cjs/boot/sessionColdBoot.js +395 -0
  10. package/dist/cjs/constants/version.js +16 -0
  11. package/dist/cjs/crypto/aead.js +79 -0
  12. package/dist/cjs/crypto/ecdh.js +35 -0
  13. package/dist/cjs/crypto/identityMarker.js +255 -0
  14. package/dist/cjs/crypto/kdf.js +39 -0
  15. package/dist/cjs/crypto/keyManager.js +2234 -0
  16. package/dist/cjs/crypto/polyfill.js +131 -0
  17. package/dist/cjs/crypto/recoveryPhrase.js +242 -0
  18. package/dist/cjs/crypto/signatureService.js +273 -0
  19. package/dist/cjs/i18n/accountCategoryLabels.js +44 -0
  20. package/dist/cjs/i18n/accountRoleLabels.js +27 -0
  21. package/dist/cjs/i18n/index.js +90 -0
  22. package/dist/cjs/i18n/locales/ar-SA.json +282 -0
  23. package/dist/cjs/i18n/locales/ca-ES.json +282 -0
  24. package/dist/cjs/i18n/locales/de-DE.json +282 -0
  25. package/dist/cjs/i18n/locales/en-US.json +2161 -0
  26. package/dist/cjs/i18n/locales/es-ES.json +2161 -0
  27. package/dist/cjs/i18n/locales/fr-FR.json +282 -0
  28. package/dist/cjs/i18n/locales/it-IT.json +282 -0
  29. package/dist/cjs/i18n/locales/ja-JP.json +282 -0
  30. package/dist/cjs/i18n/locales/ko-KR.json +282 -0
  31. package/dist/cjs/i18n/locales/locales/ar-SA.json +282 -0
  32. package/dist/cjs/i18n/locales/locales/ca-ES.json +282 -0
  33. package/dist/cjs/i18n/locales/locales/de-DE.json +282 -0
  34. package/dist/cjs/i18n/locales/locales/en-US.json +2161 -0
  35. package/dist/cjs/i18n/locales/locales/es-ES.json +2161 -0
  36. package/dist/cjs/i18n/locales/locales/fr-FR.json +282 -0
  37. package/dist/cjs/i18n/locales/locales/it-IT.json +282 -0
  38. package/dist/cjs/i18n/locales/locales/ja-JP.json +282 -0
  39. package/dist/cjs/i18n/locales/locales/ko-KR.json +282 -0
  40. package/dist/cjs/i18n/locales/locales/pt-PT.json +282 -0
  41. package/dist/cjs/i18n/locales/locales/zh-CN.json +282 -0
  42. package/dist/cjs/i18n/locales/pt-PT.json +282 -0
  43. package/dist/cjs/i18n/locales/zh-CN.json +282 -0
  44. package/dist/cjs/i18n/reputationCategoryLabels.js +20 -0
  45. package/dist/cjs/i18n/trustTierLabels.js +19 -0
  46. package/dist/cjs/index.js +498 -0
  47. package/dist/cjs/inference/OxyInferenceClient.js +544 -0
  48. package/dist/cjs/logger/index.js +149 -0
  49. package/dist/cjs/mixins/OxyServices.accounts.js +555 -0
  50. package/dist/cjs/mixins/OxyServices.analytics.js +49 -0
  51. package/dist/cjs/mixins/OxyServices.appData.js +108 -0
  52. package/dist/cjs/mixins/OxyServices.assets.js +764 -0
  53. package/dist/cjs/mixins/OxyServices.auth.js +1254 -0
  54. package/dist/cjs/mixins/OxyServices.chains.js +73 -0
  55. package/dist/cjs/mixins/OxyServices.civic.js +611 -0
  56. package/dist/cjs/mixins/OxyServices.connectedApps.js +78 -0
  57. package/dist/cjs/mixins/OxyServices.contacts.js +50 -0
  58. package/dist/cjs/mixins/OxyServices.deviceBoot.js +191 -0
  59. package/dist/cjs/mixins/OxyServices.deviceTransfer.js +314 -0
  60. package/dist/cjs/mixins/OxyServices.devices.js +116 -0
  61. package/dist/cjs/mixins/OxyServices.features.js +335 -0
  62. package/dist/cjs/mixins/OxyServices.followGraph.js +221 -0
  63. package/dist/cjs/mixins/OxyServices.identity.js +461 -0
  64. package/dist/cjs/mixins/OxyServices.identityBackup.js +172 -0
  65. package/dist/cjs/mixins/OxyServices.inference.js +59 -0
  66. package/dist/cjs/mixins/OxyServices.language.js +125 -0
  67. package/dist/cjs/mixins/OxyServices.links.js +72 -0
  68. package/dist/cjs/mixins/OxyServices.location.js +43 -0
  69. package/dist/cjs/mixins/OxyServices.nodes.js +175 -0
  70. package/dist/cjs/mixins/OxyServices.notifications.js +63 -0
  71. package/dist/cjs/mixins/OxyServices.payment.js +158 -0
  72. package/dist/cjs/mixins/OxyServices.privacy.js +199 -0
  73. package/dist/cjs/mixins/OxyServices.reputation.js +289 -0
  74. package/dist/cjs/mixins/OxyServices.security.js +89 -0
  75. package/dist/cjs/mixins/OxyServices.store.js +266 -0
  76. package/dist/cjs/mixins/OxyServices.topics.js +137 -0
  77. package/dist/cjs/mixins/OxyServices.user.js +902 -0
  78. package/dist/cjs/mixins/OxyServices.utility.js +1098 -0
  79. package/dist/cjs/mixins/index.js +135 -0
  80. package/dist/cjs/mixins/mixinHelpers.js +53 -0
  81. package/dist/cjs/models/Topic.js +16 -0
  82. package/dist/cjs/models/interfaces.js +20 -0
  83. package/dist/cjs/models/session.js +2 -0
  84. package/dist/cjs/server/auth.js +167 -0
  85. package/dist/cjs/server/capabilityTicket.js +192 -0
  86. package/dist/cjs/server/cors.js +225 -0
  87. package/dist/cjs/server/index.js +97 -0
  88. package/dist/cjs/server/rateLimit.js +207 -0
  89. package/dist/cjs/server/safeFetch.js +458 -0
  90. package/dist/cjs/server/securityHeaders.js +377 -0
  91. package/dist/cjs/server/userInvalidation.js +156 -0
  92. package/dist/cjs/server/verifySecret.js +50 -0
  93. package/dist/cjs/session/SessionClient.js +865 -0
  94. package/dist/cjs/session/accountDelegationAccess.js +48 -0
  95. package/dist/cjs/session/accountDialogController.js +1131 -0
  96. package/dist/cjs/session/accountSwitchTargets.js +81 -0
  97. package/dist/cjs/session/authStateStore.js +404 -0
  98. package/dist/cjs/session/createSessionClient.js +32 -0
  99. package/dist/cjs/session/deviceDirectory.js +143 -0
  100. package/dist/cjs/session/deviceSwitcherRows.js +76 -0
  101. package/dist/cjs/session/identityPin.js +256 -0
  102. package/dist/cjs/session/identitySession.js +135 -0
  103. package/dist/cjs/session/projectSessionState.js +121 -0
  104. package/dist/cjs/session/refresh.js +398 -0
  105. package/dist/cjs/session/sessionClientHost.js +34 -0
  106. package/dist/cjs/session/sharedDeviceCredential.js +247 -0
  107. package/dist/cjs/session/socketLoader.js +55 -0
  108. package/dist/cjs/shared/utils/colorUtils.js +153 -0
  109. package/dist/cjs/shared/utils/errorUtils.js +183 -0
  110. package/dist/cjs/shared/utils/index.js +49 -0
  111. package/dist/cjs/shared/utils/networkUtils.js +183 -0
  112. package/dist/cjs/shared/utils/themeUtils.js +106 -0
  113. package/dist/cjs/utils/accountCacheSweep.js +80 -0
  114. package/dist/cjs/utils/accountUtils.js +140 -0
  115. package/dist/cjs/utils/activityId.js +6 -0
  116. package/dist/cjs/utils/apiUtils.js +91 -0
  117. package/dist/cjs/utils/asyncUtils.js +222 -0
  118. package/dist/cjs/utils/authHelpers.js +120 -0
  119. package/dist/cjs/utils/authWebUrl.js +19 -0
  120. package/dist/cjs/utils/avatarUtils.js +29 -0
  121. package/dist/cjs/utils/cache.js +235 -0
  122. package/dist/cjs/utils/cacheKey.js +85 -0
  123. package/dist/cjs/utils/coldBoot.js +122 -0
  124. package/dist/cjs/utils/commonsApproval.js +31 -0
  125. package/dist/cjs/utils/commonsDelivery.js +59 -0
  126. package/dist/cjs/utils/deviceManager.js +174 -0
  127. package/dist/cjs/utils/displayNamePolicyRanges.generated.js +60 -0
  128. package/dist/cjs/utils/edgeRegion.js +6 -0
  129. package/dist/cjs/utils/errorUtils.js +243 -0
  130. package/dist/cjs/utils/identityCacheSweep.js +97 -0
  131. package/dist/cjs/utils/languageUtils.js +224 -0
  132. package/dist/cjs/utils/oauthPkce.js +311 -0
  133. package/dist/cjs/utils/officialOrigins.js +64 -0
  134. package/dist/cjs/utils/oxyServiceEnvironment.js +19 -0
  135. package/dist/cjs/utils/platform.js +119 -0
  136. package/dist/cjs/utils/profileLinks.js +63 -0
  137. package/dist/cjs/utils/redactUrl.js +29 -0
  138. package/dist/cjs/utils/registrableApex.js +45 -0
  139. package/dist/cjs/utils/requestUtils.js +209 -0
  140. package/dist/cjs/utils/sessionUtils.js +181 -0
  141. package/dist/cjs/utils/textNormalization.js +158 -0
  142. package/dist/cjs/utils/userHandle.js +37 -0
  143. package/dist/cjs/utils/userIdentity.js +50 -0
  144. package/dist/cjs/utils/validationUtils.js +370 -0
  145. package/dist/cjs/utils/webauthnOrigin.js +51 -0
  146. package/dist/esm/.tsbuildinfo +1 -0
  147. package/dist/esm/HttpService.js +1266 -0
  148. package/dist/esm/OxyServices.base.js +386 -0
  149. package/dist/esm/OxyServices.errors.js +88 -0
  150. package/dist/esm/OxyServices.js +66 -0
  151. package/dist/esm/boot/sessionColdBoot.js +392 -0
  152. package/dist/esm/constants/version.js +13 -0
  153. package/dist/esm/crypto/aead.js +74 -0
  154. package/dist/esm/crypto/ecdh.js +32 -0
  155. package/dist/esm/crypto/identityMarker.js +248 -0
  156. package/dist/esm/crypto/kdf.js +36 -0
  157. package/dist/esm/crypto/keyManager.js +2227 -0
  158. package/dist/esm/crypto/polyfill.js +129 -0
  159. package/dist/esm/crypto/recoveryPhrase.js +238 -0
  160. package/dist/esm/crypto/signatureService.js +269 -0
  161. package/dist/esm/i18n/accountCategoryLabels.js +37 -0
  162. package/dist/esm/i18n/accountRoleLabels.js +20 -0
  163. package/dist/esm/i18n/index.js +83 -0
  164. package/dist/esm/i18n/locales/ar-SA.json +282 -0
  165. package/dist/esm/i18n/locales/ca-ES.json +282 -0
  166. package/dist/esm/i18n/locales/de-DE.json +282 -0
  167. package/dist/esm/i18n/locales/en-US.json +2161 -0
  168. package/dist/esm/i18n/locales/es-ES.json +2161 -0
  169. package/dist/esm/i18n/locales/fr-FR.json +282 -0
  170. package/dist/esm/i18n/locales/it-IT.json +282 -0
  171. package/dist/esm/i18n/locales/ja-JP.json +282 -0
  172. package/dist/esm/i18n/locales/ko-KR.json +282 -0
  173. package/dist/esm/i18n/locales/locales/ar-SA.json +282 -0
  174. package/dist/esm/i18n/locales/locales/ca-ES.json +282 -0
  175. package/dist/esm/i18n/locales/locales/de-DE.json +282 -0
  176. package/dist/esm/i18n/locales/locales/en-US.json +2161 -0
  177. package/dist/esm/i18n/locales/locales/es-ES.json +2161 -0
  178. package/dist/esm/i18n/locales/locales/fr-FR.json +282 -0
  179. package/dist/esm/i18n/locales/locales/it-IT.json +282 -0
  180. package/dist/esm/i18n/locales/locales/ja-JP.json +282 -0
  181. package/dist/esm/i18n/locales/locales/ko-KR.json +282 -0
  182. package/dist/esm/i18n/locales/locales/pt-PT.json +282 -0
  183. package/dist/esm/i18n/locales/locales/zh-CN.json +282 -0
  184. package/dist/esm/i18n/locales/pt-PT.json +282 -0
  185. package/dist/esm/i18n/locales/zh-CN.json +282 -0
  186. package/dist/esm/i18n/reputationCategoryLabels.js +13 -0
  187. package/dist/esm/i18n/trustTierLabels.js +12 -0
  188. package/dist/esm/index.js +254 -0
  189. package/dist/esm/inference/OxyInferenceClient.js +538 -0
  190. package/dist/esm/logger/index.js +140 -0
  191. package/dist/esm/mixins/OxyServices.accounts.js +543 -0
  192. package/dist/esm/mixins/OxyServices.analytics.js +46 -0
  193. package/dist/esm/mixins/OxyServices.appData.js +103 -0
  194. package/dist/esm/mixins/OxyServices.assets.js +761 -0
  195. package/dist/esm/mixins/OxyServices.auth.js +1247 -0
  196. package/dist/esm/mixins/OxyServices.chains.js +70 -0
  197. package/dist/esm/mixins/OxyServices.civic.js +605 -0
  198. package/dist/esm/mixins/OxyServices.connectedApps.js +75 -0
  199. package/dist/esm/mixins/OxyServices.contacts.js +47 -0
  200. package/dist/esm/mixins/OxyServices.deviceBoot.js +186 -0
  201. package/dist/esm/mixins/OxyServices.deviceTransfer.js +311 -0
  202. package/dist/esm/mixins/OxyServices.devices.js +113 -0
  203. package/dist/esm/mixins/OxyServices.features.js +332 -0
  204. package/dist/esm/mixins/OxyServices.followGraph.js +218 -0
  205. package/dist/esm/mixins/OxyServices.identity.js +457 -0
  206. package/dist/esm/mixins/OxyServices.identityBackup.js +169 -0
  207. package/dist/esm/mixins/OxyServices.inference.js +56 -0
  208. package/dist/esm/mixins/OxyServices.language.js +122 -0
  209. package/dist/esm/mixins/OxyServices.links.js +69 -0
  210. package/dist/esm/mixins/OxyServices.location.js +40 -0
  211. package/dist/esm/mixins/OxyServices.nodes.js +172 -0
  212. package/dist/esm/mixins/OxyServices.notifications.js +60 -0
  213. package/dist/esm/mixins/OxyServices.payment.js +155 -0
  214. package/dist/esm/mixins/OxyServices.privacy.js +196 -0
  215. package/dist/esm/mixins/OxyServices.reputation.js +286 -0
  216. package/dist/esm/mixins/OxyServices.security.js +86 -0
  217. package/dist/esm/mixins/OxyServices.store.js +263 -0
  218. package/dist/esm/mixins/OxyServices.topics.js +134 -0
  219. package/dist/esm/mixins/OxyServices.user.js +899 -0
  220. package/dist/esm/mixins/OxyServices.utility.js +1095 -0
  221. package/dist/esm/mixins/index.js +132 -0
  222. package/dist/esm/mixins/mixinHelpers.js +48 -0
  223. package/dist/esm/models/Topic.js +13 -0
  224. package/dist/esm/models/interfaces.js +17 -0
  225. package/dist/esm/models/session.js +1 -0
  226. package/dist/esm/server/auth.js +154 -0
  227. package/dist/esm/server/capabilityTicket.js +183 -0
  228. package/dist/esm/server/cors.js +220 -0
  229. package/dist/esm/server/index.js +47 -0
  230. package/dist/esm/server/rateLimit.js +201 -0
  231. package/dist/esm/server/safeFetch.js +447 -0
  232. package/dist/esm/server/securityHeaders.js +364 -0
  233. package/dist/esm/server/userInvalidation.js +152 -0
  234. package/dist/esm/server/verifySecret.js +47 -0
  235. package/dist/esm/session/SessionClient.js +861 -0
  236. package/dist/esm/session/accountDelegationAccess.js +45 -0
  237. package/dist/esm/session/accountDialogController.js +1126 -0
  238. package/dist/esm/session/accountSwitchTargets.js +77 -0
  239. package/dist/esm/session/authStateStore.js +398 -0
  240. package/dist/esm/session/createSessionClient.js +29 -0
  241. package/dist/esm/session/deviceDirectory.js +135 -0
  242. package/dist/esm/session/deviceSwitcherRows.js +72 -0
  243. package/dist/esm/session/identityPin.js +249 -0
  244. package/dist/esm/session/identitySession.js +131 -0
  245. package/dist/esm/session/projectSessionState.js +114 -0
  246. package/dist/esm/session/refresh.js +390 -0
  247. package/dist/esm/session/sessionClientHost.js +31 -0
  248. package/dist/esm/session/sharedDeviceCredential.js +239 -0
  249. package/dist/esm/session/socketLoader.js +19 -0
  250. package/dist/esm/shared/utils/colorUtils.js +143 -0
  251. package/dist/esm/shared/utils/errorUtils.js +170 -0
  252. package/dist/esm/shared/utils/index.js +15 -0
  253. package/dist/esm/shared/utils/networkUtils.js +173 -0
  254. package/dist/esm/shared/utils/themeUtils.js +98 -0
  255. package/dist/esm/utils/accountCacheSweep.js +75 -0
  256. package/dist/esm/utils/accountUtils.js +131 -0
  257. package/dist/esm/utils/activityId.js +2 -0
  258. package/dist/esm/utils/apiUtils.js +84 -0
  259. package/dist/esm/utils/asyncUtils.js +207 -0
  260. package/dist/esm/utils/authHelpers.js +111 -0
  261. package/dist/esm/utils/authWebUrl.js +16 -0
  262. package/dist/esm/utils/avatarUtils.js +26 -0
  263. package/dist/esm/utils/cache.js +227 -0
  264. package/dist/esm/utils/cacheKey.js +80 -0
  265. package/dist/esm/utils/coldBoot.js +119 -0
  266. package/dist/esm/utils/commonsApproval.js +27 -0
  267. package/dist/esm/utils/commonsDelivery.js +54 -0
  268. package/dist/esm/utils/deviceManager.js +170 -0
  269. package/dist/esm/utils/displayNamePolicyRanges.generated.js +57 -0
  270. package/dist/esm/utils/edgeRegion.js +2 -0
  271. package/dist/esm/utils/errorUtils.js +232 -0
  272. package/dist/esm/utils/identityCacheSweep.js +92 -0
  273. package/dist/esm/utils/languageUtils.js +212 -0
  274. package/dist/esm/utils/oauthPkce.js +297 -0
  275. package/dist/esm/utils/officialOrigins.js +59 -0
  276. package/dist/esm/utils/oxyServiceEnvironment.js +16 -0
  277. package/dist/esm/utils/platform.js +110 -0
  278. package/dist/esm/utils/profileLinks.js +60 -0
  279. package/dist/esm/utils/redactUrl.js +26 -0
  280. package/dist/esm/utils/registrableApex.js +42 -0
  281. package/dist/esm/utils/requestUtils.js +203 -0
  282. package/dist/esm/utils/sessionUtils.js +171 -0
  283. package/dist/esm/utils/textNormalization.js +154 -0
  284. package/dist/esm/utils/userHandle.js +33 -0
  285. package/dist/esm/utils/userIdentity.js +45 -0
  286. package/dist/esm/utils/validationUtils.js +350 -0
  287. package/dist/esm/utils/webauthnOrigin.js +48 -0
  288. package/dist/types/.tsbuildinfo +1 -0
  289. package/dist/types/HttpService.d.ts +413 -0
  290. package/dist/types/OxyServices.base.d.ts +187 -0
  291. package/dist/types/OxyServices.d.ts +139 -0
  292. package/dist/types/OxyServices.errors.d.ts +84 -0
  293. package/dist/types/boot/sessionColdBoot.d.ts +140 -0
  294. package/dist/types/constants/version.d.ts +13 -0
  295. package/dist/types/crypto/aead.d.ts +56 -0
  296. package/dist/types/crypto/ecdh.d.ts +29 -0
  297. package/dist/types/crypto/identityMarker.d.ts +94 -0
  298. package/dist/types/crypto/kdf.d.ts +25 -0
  299. package/dist/types/crypto/keyManager.d.ts +582 -0
  300. package/dist/types/crypto/polyfill.d.ts +25 -0
  301. package/dist/types/crypto/recoveryPhrase.d.ts +173 -0
  302. package/dist/types/crypto/signatureService.d.ts +136 -0
  303. package/dist/types/i18n/accountCategoryLabels.d.ts +34 -0
  304. package/dist/types/i18n/accountRoleLabels.d.ts +10 -0
  305. package/dist/types/i18n/index.d.ts +3 -0
  306. package/dist/types/i18n/reputationCategoryLabels.d.ts +10 -0
  307. package/dist/types/i18n/trustTierLabels.d.ts +9 -0
  308. package/dist/types/index.d.ts +145 -0
  309. package/dist/types/inference/OxyInferenceClient.d.ts +342 -0
  310. package/dist/types/logger/index.d.ts +104 -0
  311. package/dist/types/mixins/OxyServices.accounts.d.ts +868 -0
  312. package/dist/types/mixins/OxyServices.analytics.d.ts +72 -0
  313. package/dist/types/mixins/OxyServices.appData.d.ts +108 -0
  314. package/dist/types/mixins/OxyServices.assets.d.ts +329 -0
  315. package/dist/types/mixins/OxyServices.auth.d.ts +908 -0
  316. package/dist/types/mixins/OxyServices.chains.d.ts +156 -0
  317. package/dist/types/mixins/OxyServices.civic.d.ts +510 -0
  318. package/dist/types/mixins/OxyServices.connectedApps.d.ts +169 -0
  319. package/dist/types/mixins/OxyServices.contacts.d.ts +100 -0
  320. package/dist/types/mixins/OxyServices.deviceBoot.d.ts +185 -0
  321. package/dist/types/mixins/OxyServices.deviceTransfer.d.ts +149 -0
  322. package/dist/types/mixins/OxyServices.devices.d.ts +103 -0
  323. package/dist/types/mixins/OxyServices.features.d.ts +250 -0
  324. package/dist/types/mixins/OxyServices.followGraph.d.ts +223 -0
  325. package/dist/types/mixins/OxyServices.identity.d.ts +351 -0
  326. package/dist/types/mixins/OxyServices.identityBackup.d.ts +129 -0
  327. package/dist/types/mixins/OxyServices.inference.d.ts +95 -0
  328. package/dist/types/mixins/OxyServices.language.d.ts +87 -0
  329. package/dist/types/mixins/OxyServices.links.d.ts +104 -0
  330. package/dist/types/mixins/OxyServices.location.d.ts +70 -0
  331. package/dist/types/mixins/OxyServices.nodes.d.ts +198 -0
  332. package/dist/types/mixins/OxyServices.notifications.d.ts +143 -0
  333. package/dist/types/mixins/OxyServices.payment.d.ts +117 -0
  334. package/dist/types/mixins/OxyServices.privacy.d.ts +146 -0
  335. package/dist/types/mixins/OxyServices.reputation.d.ts +202 -0
  336. package/dist/types/mixins/OxyServices.security.d.ts +84 -0
  337. package/dist/types/mixins/OxyServices.store.d.ts +334 -0
  338. package/dist/types/mixins/OxyServices.topics.d.ts +110 -0
  339. package/dist/types/mixins/OxyServices.user.d.ts +558 -0
  340. package/dist/types/mixins/OxyServices.utility.d.ts +393 -0
  341. package/dist/types/mixins/index.d.ts +87 -0
  342. package/dist/types/mixins/mixinHelpers.d.ts +31 -0
  343. package/dist/types/models/Topic.d.ts +42 -0
  344. package/dist/types/models/interfaces.d.ts +675 -0
  345. package/dist/types/models/session.d.ts +51 -0
  346. package/dist/types/server/auth.d.ts +130 -0
  347. package/dist/types/server/capabilityTicket.d.ts +41 -0
  348. package/dist/types/server/cors.d.ts +98 -0
  349. package/dist/types/server/index.d.ts +35 -0
  350. package/dist/types/server/rateLimit.d.ts +40 -0
  351. package/dist/types/server/safeFetch.d.ts +137 -0
  352. package/dist/types/server/securityHeaders.d.ts +221 -0
  353. package/dist/types/server/userInvalidation.d.ts +114 -0
  354. package/dist/types/server/verifySecret.d.ts +29 -0
  355. package/dist/types/session/SessionClient.d.ts +418 -0
  356. package/dist/types/session/accountDelegationAccess.d.ts +40 -0
  357. package/dist/types/session/accountDialogController.d.ts +648 -0
  358. package/dist/types/session/accountSwitchTargets.d.ts +70 -0
  359. package/dist/types/session/authStateStore.d.ts +153 -0
  360. package/dist/types/session/createSessionClient.d.ts +30 -0
  361. package/dist/types/session/deviceDirectory.d.ts +182 -0
  362. package/dist/types/session/deviceSwitcherRows.d.ts +92 -0
  363. package/dist/types/session/identityPin.d.ts +87 -0
  364. package/dist/types/session/identitySession.d.ts +105 -0
  365. package/dist/types/session/projectSessionState.d.ts +74 -0
  366. package/dist/types/session/refresh.d.ts +179 -0
  367. package/dist/types/session/sessionClientHost.d.ts +18 -0
  368. package/dist/types/session/sharedDeviceCredential.d.ts +202 -0
  369. package/dist/types/session/socketLoader.d.ts +11 -0
  370. package/dist/types/shared/utils/colorUtils.d.ts +104 -0
  371. package/dist/types/shared/utils/errorUtils.d.ts +97 -0
  372. package/dist/types/shared/utils/index.d.ts +13 -0
  373. package/dist/types/shared/utils/networkUtils.d.ts +139 -0
  374. package/dist/types/shared/utils/themeUtils.d.ts +90 -0
  375. package/dist/types/utils/accountCacheSweep.d.ts +75 -0
  376. package/dist/types/utils/accountUtils.d.ts +100 -0
  377. package/dist/types/utils/activityId.d.ts +2 -0
  378. package/dist/types/utils/apiUtils.d.ts +95 -0
  379. package/dist/types/utils/asyncUtils.d.ts +62 -0
  380. package/dist/types/utils/authHelpers.d.ts +58 -0
  381. package/dist/types/utils/authWebUrl.d.ts +16 -0
  382. package/dist/types/utils/avatarUtils.d.ts +16 -0
  383. package/dist/types/utils/cache.d.ts +130 -0
  384. package/dist/types/utils/cacheKey.d.ts +66 -0
  385. package/dist/types/utils/coldBoot.d.ts +131 -0
  386. package/dist/types/utils/commonsApproval.d.ts +13 -0
  387. package/dist/types/utils/commonsDelivery.d.ts +105 -0
  388. package/dist/types/utils/deviceManager.d.ts +65 -0
  389. package/dist/types/utils/displayNamePolicyRanges.generated.d.ts +57 -0
  390. package/dist/types/utils/edgeRegion.d.ts +2 -0
  391. package/dist/types/utils/errorUtils.d.ts +125 -0
  392. package/dist/types/utils/identityCacheSweep.d.ts +80 -0
  393. package/dist/types/utils/languageUtils.d.ts +100 -0
  394. package/dist/types/utils/oauthPkce.d.ts +157 -0
  395. package/dist/types/utils/officialOrigins.d.ts +13 -0
  396. package/dist/types/utils/oxyServiceEnvironment.d.ts +17 -0
  397. package/dist/types/utils/platform.d.ts +49 -0
  398. package/dist/types/utils/profileLinks.d.ts +44 -0
  399. package/dist/types/utils/redactUrl.d.ts +17 -0
  400. package/dist/types/utils/registrableApex.d.ts +27 -0
  401. package/dist/types/utils/requestUtils.d.ts +123 -0
  402. package/dist/types/utils/sessionUtils.d.ts +54 -0
  403. package/dist/types/utils/textNormalization.d.ts +103 -0
  404. package/dist/types/utils/userHandle.d.ts +26 -0
  405. package/dist/types/utils/userIdentity.d.ts +21 -0
  406. package/dist/types/utils/validationUtils.d.ts +268 -0
  407. package/dist/types/utils/webauthnOrigin.d.ts +32 -0
  408. package/package.json +168 -0
  409. package/src/HttpService.ts +1553 -0
  410. package/src/OxyServices.base.ts +478 -0
  411. package/src/OxyServices.errors.ts +122 -0
  412. package/src/OxyServices.ts +172 -0
  413. package/src/__tests__/authSocket.test.ts +96 -0
  414. package/src/__tests__/httpServiceActivityId.test.ts +49 -0
  415. package/src/__tests__/httpServiceAuthSelfAwait.test.ts +108 -0
  416. package/src/__tests__/httpServiceCache.test.ts +318 -0
  417. package/src/__tests__/httpServiceCsrf.test.ts +235 -0
  418. package/src/__tests__/httpServiceFormEncoded.test.ts +142 -0
  419. package/src/__tests__/httpServiceQueueDeadlock.test.ts +128 -0
  420. package/src/__tests__/httpServiceUnwrapEnvelope.test.ts +115 -0
  421. package/src/__tests__/inSessionRefresh.test.ts +260 -0
  422. package/src/__tests__/linkedClient.test.ts +370 -0
  423. package/src/__tests__/parseHttpErrorBody.test.ts +116 -0
  424. package/src/__tests__/serverValueImportsDeclared.test.ts +120 -0
  425. package/src/__tests__/userIdentity.test.ts +143 -0
  426. package/src/boot/__tests__/sessionColdBoot.identity.test.ts +393 -0
  427. package/src/boot/__tests__/sessionColdBoot.sharedDevice.test.ts +325 -0
  428. package/src/boot/__tests__/sessionColdBoot.test.ts +570 -0
  429. package/src/boot/sessionColdBoot.ts +529 -0
  430. package/src/constants/version.ts +15 -0
  431. package/src/crypto/__tests__/backupMaterial.test.ts +86 -0
  432. package/src/crypto/__tests__/cryptoPrimitives.test.ts +226 -0
  433. package/src/crypto/__tests__/identityMocks.ts +125 -0
  434. package/src/crypto/__tests__/keyManager.atomicity.test.ts +272 -0
  435. package/src/crypto/__tests__/keyManager.cacheSafety.test.ts +175 -0
  436. package/src/crypto/__tests__/keyManager.identityStatus.test.ts +217 -0
  437. package/src/crypto/__tests__/keyManager.recoveryLadder.test.ts +179 -0
  438. package/src/crypto/__tests__/keyManager.recoveryMnemonic.test.ts +138 -0
  439. package/src/crypto/__tests__/keyManager.storageMigration.test.ts +227 -0
  440. package/src/crypto/__tests__/keyManager.test.ts +329 -0
  441. package/src/crypto/__tests__/polyfill.test.ts +109 -0
  442. package/src/crypto/__tests__/recoveryPhrase.test.ts +61 -0
  443. package/src/crypto/__tests__/scopedSeed.test.ts +126 -0
  444. package/src/crypto/__tests__/signChallengeShared.test.ts +63 -0
  445. package/src/crypto/__tests__/signedRecord.test.ts +230 -0
  446. package/src/crypto/aead.ts +97 -0
  447. package/src/crypto/ecdh.ts +37 -0
  448. package/src/crypto/identityMarker.ts +291 -0
  449. package/src/crypto/kdf.ts +43 -0
  450. package/src/crypto/keyManager.ts +2607 -0
  451. package/src/crypto/polyfill.ts +143 -0
  452. package/src/crypto/recoveryPhrase.ts +337 -0
  453. package/src/crypto/signatureService.ts +350 -0
  454. package/src/i18n/__tests__/accountCategoryLabels.test.ts +62 -0
  455. package/src/i18n/__tests__/accountRoleLabels.test.ts +54 -0
  456. package/src/i18n/__tests__/reputationCategoryLabels.test.ts +56 -0
  457. package/src/i18n/__tests__/trustTierLabels.test.ts +47 -0
  458. package/src/i18n/accountCategoryLabels.ts +44 -0
  459. package/src/i18n/accountRoleLabels.ts +26 -0
  460. package/src/i18n/index.ts +88 -0
  461. package/src/i18n/locales/ar-SA.json +282 -0
  462. package/src/i18n/locales/ca-ES.json +282 -0
  463. package/src/i18n/locales/de-DE.json +282 -0
  464. package/src/i18n/locales/en-US.json +2161 -0
  465. package/src/i18n/locales/es-ES.json +2161 -0
  466. package/src/i18n/locales/fr-FR.json +282 -0
  467. package/src/i18n/locales/it-IT.json +282 -0
  468. package/src/i18n/locales/ja-JP.json +282 -0
  469. package/src/i18n/locales/ko-KR.json +282 -0
  470. package/src/i18n/locales/pt-PT.json +282 -0
  471. package/src/i18n/locales/zh-CN.json +282 -0
  472. package/src/i18n/reputationCategoryLabels.ts +20 -0
  473. package/src/i18n/trustTierLabels.ts +18 -0
  474. package/src/index.ts +881 -0
  475. package/src/inference/OxyInferenceClient.ts +888 -0
  476. package/src/inference/__tests__/OxyInferenceClient.test.ts +834 -0
  477. package/src/logger/__tests__/logger.test.ts +207 -0
  478. package/src/logger/index.ts +217 -0
  479. package/src/mixins/OxyServices.accounts.ts +1330 -0
  480. package/src/mixins/OxyServices.analytics.ts +53 -0
  481. package/src/mixins/OxyServices.appData.ts +158 -0
  482. package/src/mixins/OxyServices.assets.ts +861 -0
  483. package/src/mixins/OxyServices.auth.ts +1858 -0
  484. package/src/mixins/OxyServices.chains.ts +134 -0
  485. package/src/mixins/OxyServices.civic.ts +945 -0
  486. package/src/mixins/OxyServices.connectedApps.ts +174 -0
  487. package/src/mixins/OxyServices.contacts.ts +73 -0
  488. package/src/mixins/OxyServices.deviceBoot.ts +210 -0
  489. package/src/mixins/OxyServices.deviceTransfer.ts +393 -0
  490. package/src/mixins/OxyServices.devices.ts +120 -0
  491. package/src/mixins/OxyServices.features.ts +454 -0
  492. package/src/mixins/OxyServices.followGraph.ts +293 -0
  493. package/src/mixins/OxyServices.identity.ts +705 -0
  494. package/src/mixins/OxyServices.identityBackup.ts +250 -0
  495. package/src/mixins/OxyServices.inference.ts +57 -0
  496. package/src/mixins/OxyServices.language.ts +144 -0
  497. package/src/mixins/OxyServices.links.ts +107 -0
  498. package/src/mixins/OxyServices.location.ts +46 -0
  499. package/src/mixins/OxyServices.nodes.ts +337 -0
  500. package/src/mixins/OxyServices.notifications.ts +142 -0
  501. package/src/mixins/OxyServices.payment.ts +163 -0
  502. package/src/mixins/OxyServices.privacy.ts +219 -0
  503. package/src/mixins/OxyServices.reputation.ts +436 -0
  504. package/src/mixins/OxyServices.security.ts +110 -0
  505. package/src/mixins/OxyServices.store.ts +585 -0
  506. package/src/mixins/OxyServices.topics.ts +169 -0
  507. package/src/mixins/OxyServices.user.ts +1137 -0
  508. package/src/mixins/OxyServices.utility.ts +1370 -0
  509. package/src/mixins/__tests__/OxyServices.civic.test.ts +1095 -0
  510. package/src/mixins/__tests__/OxyServices.deviceBoot.test.ts +124 -0
  511. package/src/mixins/__tests__/OxyServices.deviceTransfer.test.ts +271 -0
  512. package/src/mixins/__tests__/OxyServices.identity.test.ts +376 -0
  513. package/src/mixins/__tests__/OxyServices.links.test.ts +154 -0
  514. package/src/mixins/__tests__/OxyServices.nodes.test.ts +341 -0
  515. package/src/mixins/__tests__/OxyServices.rotateKey.test.ts +276 -0
  516. package/src/mixins/__tests__/OxyServices.serviceAssetMetadata.test.ts +192 -0
  517. package/src/mixins/__tests__/OxyServices.serviceAssetMetadataBySha.test.ts +135 -0
  518. package/src/mixins/__tests__/accounts.test.ts +727 -0
  519. package/src/mixins/__tests__/appData.test.ts +203 -0
  520. package/src/mixins/__tests__/assetCredentials.test.ts +47 -0
  521. package/src/mixins/__tests__/assetUpload.test.ts +191 -0
  522. package/src/mixins/__tests__/backgroundCredential.httpIntegration.test.ts +135 -0
  523. package/src/mixins/__tests__/chains.test.ts +113 -0
  524. package/src/mixins/__tests__/commonsSignIn.test.ts +1144 -0
  525. package/src/mixins/__tests__/connectedApps.test.ts +123 -0
  526. package/src/mixins/__tests__/deviceTokenMintPinned.test.ts +113 -0
  527. package/src/mixins/__tests__/discoveryErrorHandling.test.ts +266 -0
  528. package/src/mixins/__tests__/followCacheInvalidation.test.ts +173 -0
  529. package/src/mixins/__tests__/followGraph.test.ts +147 -0
  530. package/src/mixins/__tests__/followGraphPagination.test.ts +271 -0
  531. package/src/mixins/__tests__/getFileDownloadUrl.test.ts +346 -0
  532. package/src/mixins/__tests__/getFollowStatuses.test.ts +95 -0
  533. package/src/mixins/__tests__/getUsersByIds.test.ts +149 -0
  534. package/src/mixins/__tests__/identityBackup.test.ts +315 -0
  535. package/src/mixins/__tests__/identityWriteCacheInvalidation.test.ts +407 -0
  536. package/src/mixins/__tests__/inferenceFactory.test.ts +58 -0
  537. package/src/mixins/__tests__/onTokensChanged.test.ts +129 -0
  538. package/src/mixins/__tests__/preSessionSkipAuth.test.ts +284 -0
  539. package/src/mixins/__tests__/privacyCacheInvalidation.test.ts +155 -0
  540. package/src/mixins/__tests__/reputation.test.ts +522 -0
  541. package/src/mixins/__tests__/serviceAuth.test.ts +832 -0
  542. package/src/mixins/__tests__/serviceTokenJwks.test.ts +208 -0
  543. package/src/mixins/__tests__/store.test.ts +304 -0
  544. package/src/mixins/__tests__/topics.test.ts +156 -0
  545. package/src/mixins/__tests__/userReadCacheBypass.test.ts +129 -0
  546. package/src/mixins/__tests__/userTokenAuth.test.ts +746 -0
  547. package/src/mixins/__tests__/verifyChallenge.test.ts +130 -0
  548. package/src/mixins/__tests__/verifyServiceActingAs.test.ts +167 -0
  549. package/src/mixins/__tests__/webauthnAuth.test.ts +205 -0
  550. package/src/mixins/index.ts +201 -0
  551. package/src/mixins/mixinHelpers.ts +69 -0
  552. package/src/models/Topic.ts +46 -0
  553. package/src/models/interfaces.ts +786 -0
  554. package/src/models/session.ts +55 -0
  555. package/src/server/__tests__/auth.test.ts +78 -0
  556. package/src/server/__tests__/capabilityTicket.test.ts +111 -0
  557. package/src/server/__tests__/cors.socket.test.ts +225 -0
  558. package/src/server/__tests__/cors.test.ts +158 -0
  559. package/src/server/__tests__/rateLimit.test.ts +257 -0
  560. package/src/server/__tests__/safeFetch.test.ts +232 -0
  561. package/src/server/__tests__/securityHeaders.test.ts +348 -0
  562. package/src/server/__tests__/serviceTokenAttribution.test.ts +396 -0
  563. package/src/server/__tests__/userInvalidation.test.ts +203 -0
  564. package/src/server/__tests__/verifySecret.test.ts +40 -0
  565. package/src/server/auth.ts +271 -0
  566. package/src/server/capabilityTicket.ts +258 -0
  567. package/src/server/cors.ts +277 -0
  568. package/src/server/index.ts +136 -0
  569. package/src/server/rateLimit.ts +313 -0
  570. package/src/server/safeFetch.ts +586 -0
  571. package/src/server/securityHeaders.ts +467 -0
  572. package/src/server/userInvalidation.ts +199 -0
  573. package/src/server/verifySecret.ts +52 -0
  574. package/src/session/SessionClient.ts +1001 -0
  575. package/src/session/__tests__/SessionClient.additive.test.ts +153 -0
  576. package/src/session/__tests__/SessionClient.broadcastChannel.test.ts +114 -0
  577. package/src/session/__tests__/SessionClient.diagnostics.test.ts +91 -0
  578. package/src/session/__tests__/SessionClient.directory.test.ts +688 -0
  579. package/src/session/__tests__/SessionClient.httpIntegration.test.ts +65 -0
  580. package/src/session/__tests__/SessionClient.identityPin.test.ts +175 -0
  581. package/src/session/__tests__/SessionClient.rest.test.ts +119 -0
  582. package/src/session/__tests__/SessionClient.serverEvents.test.ts +72 -0
  583. package/src/session/__tests__/SessionClient.socket.test.ts +202 -0
  584. package/src/session/__tests__/SessionClient.socketFactory.test.ts +81 -0
  585. package/src/session/__tests__/SessionClient.state.test.ts +78 -0
  586. package/src/session/__tests__/SessionClient.switchTokenOrder.test.ts +170 -0
  587. package/src/session/__tests__/accountDelegationAccess.test.ts +104 -0
  588. package/src/session/__tests__/accountDialogController.test.ts +1969 -0
  589. package/src/session/__tests__/accountDialogShape.test.ts +118 -0
  590. package/src/session/__tests__/accountSwitchTargets.test.ts +137 -0
  591. package/src/session/__tests__/authStateStore.test.ts +451 -0
  592. package/src/session/__tests__/deviceDirectory.test.ts +422 -0
  593. package/src/session/__tests__/deviceSwitcherRows.test.ts +223 -0
  594. package/src/session/__tests__/identityPin.test.ts +131 -0
  595. package/src/session/__tests__/identitySession.test.ts +194 -0
  596. package/src/session/__tests__/projectSessionState.test.ts +105 -0
  597. package/src/session/__tests__/refresh.identityPin.test.ts +307 -0
  598. package/src/session/__tests__/refresh.test.ts +443 -0
  599. package/src/session/__tests__/sessionIntegration.test.ts +209 -0
  600. package/src/session/__tests__/sharedDeviceCredential.test.ts +300 -0
  601. package/src/session/accountDelegationAccess.ts +72 -0
  602. package/src/session/accountDialogController.ts +1494 -0
  603. package/src/session/accountSwitchTargets.ts +93 -0
  604. package/src/session/authStateStore.ts +502 -0
  605. package/src/session/createSessionClient.ts +39 -0
  606. package/src/session/deviceDirectory.ts +269 -0
  607. package/src/session/deviceSwitcherRows.ts +145 -0
  608. package/src/session/identityPin.ts +310 -0
  609. package/src/session/identitySession.ts +206 -0
  610. package/src/session/projectSessionState.ts +137 -0
  611. package/src/session/refresh.ts +517 -0
  612. package/src/session/sessionClientHost.ts +39 -0
  613. package/src/session/sharedDeviceCredential.ts +349 -0
  614. package/src/session/socketLoader.ts +30 -0
  615. package/src/shared/utils/colorUtils.ts +155 -0
  616. package/src/shared/utils/errorUtils.ts +181 -0
  617. package/src/shared/utils/index.ts +59 -0
  618. package/src/shared/utils/networkUtils.ts +248 -0
  619. package/src/shared/utils/themeUtils.ts +115 -0
  620. package/src/types/buffer.d.ts +97 -0
  621. package/src/types/expo-crypto.d.ts +16 -0
  622. package/src/types/expo-secure-store.d.ts +17 -0
  623. package/src/utils/__tests__/accountUtils.test.ts +151 -0
  624. package/src/utils/__tests__/activityId.test.ts +45 -0
  625. package/src/utils/__tests__/asyncUtils.test.ts +187 -0
  626. package/src/utils/__tests__/authWebUrl.test.ts +15 -0
  627. package/src/utils/__tests__/cacheKey.test.ts +0 -0
  628. package/src/utils/__tests__/coldBoot.test.ts +496 -0
  629. package/src/utils/__tests__/commonsApproval.test.ts +60 -0
  630. package/src/utils/__tests__/identityCacheSweep.test.ts +151 -0
  631. package/src/utils/__tests__/languageUtils.test.ts +219 -0
  632. package/src/utils/__tests__/oauthPkce.test.ts +272 -0
  633. package/src/utils/__tests__/officialOrigins.test.ts +31 -0
  634. package/src/utils/__tests__/oxyServiceEnvironment.test.ts +7 -0
  635. package/src/utils/__tests__/profileLinks.test.ts +180 -0
  636. package/src/utils/__tests__/redactUrl.test.ts +33 -0
  637. package/src/utils/__tests__/registrableApex.test.ts +62 -0
  638. package/src/utils/__tests__/textNormalization.test.ts +205 -0
  639. package/src/utils/__tests__/validationUtils.test.ts +703 -0
  640. package/src/utils/__tests__/webauthnOrigin.test.ts +83 -0
  641. package/src/utils/accountCacheSweep.ts +93 -0
  642. package/src/utils/accountUtils.ts +194 -0
  643. package/src/utils/activityId.ts +2 -0
  644. package/src/utils/apiUtils.ts +137 -0
  645. package/src/utils/asyncUtils.ts +280 -0
  646. package/src/utils/authHelpers.ts +148 -0
  647. package/src/utils/authWebUrl.ts +17 -0
  648. package/src/utils/avatarUtils.ts +39 -0
  649. package/src/utils/cache.ts +273 -0
  650. package/src/utils/cacheKey.ts +93 -0
  651. package/src/utils/coldBoot.ts +218 -0
  652. package/src/utils/commonsApproval.ts +39 -0
  653. package/src/utils/commonsDelivery.ts +132 -0
  654. package/src/utils/deviceManager.ts +203 -0
  655. package/src/utils/displayNamePolicyRanges.generated.ts +69 -0
  656. package/src/utils/edgeRegion.ts +2 -0
  657. package/src/utils/errorUtils.ts +352 -0
  658. package/src/utils/identityCacheSweep.ts +104 -0
  659. package/src/utils/languageUtils.ts +256 -0
  660. package/src/utils/oauthPkce.ts +392 -0
  661. package/src/utils/officialOrigins.ts +62 -0
  662. package/src/utils/oxyServiceEnvironment.ts +17 -0
  663. package/src/utils/platform.ts +139 -0
  664. package/src/utils/profileLinks.ts +91 -0
  665. package/src/utils/redactUrl.ts +28 -0
  666. package/src/utils/registrableApex.ts +41 -0
  667. package/src/utils/requestUtils.ts +237 -0
  668. package/src/utils/sessionUtils.ts +206 -0
  669. package/src/utils/textNormalization.ts +162 -0
  670. package/src/utils/userHandle.ts +49 -0
  671. package/src/utils/userIdentity.ts +60 -0
  672. package/src/utils/validationUtils.ts +390 -0
  673. package/src/utils/webauthnOrigin.ts +52 -0
@@ -0,0 +1,398 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.TOKEN_REFRESH_LEAD_MS = void 0;
4
+ exports.refreshDeviceSecretArm = refreshDeviceSecretArm;
5
+ exports.refreshPersistedSession = refreshPersistedSession;
6
+ exports.createAuthRefreshHandler = createAuthRefreshHandler;
7
+ exports.installAuthRefreshHandler = installAuthRefreshHandler;
8
+ exports.startTokenRefreshScheduler = startTokenRefreshScheduler;
9
+ const identitySession_1 = require("./identitySession");
10
+ const platform_1 = require("../utils/platform");
11
+ const errorUtils_1 = require("../utils/errorUtils");
12
+ const logger_1 = require("../logger");
13
+ /**
14
+ * Lead time (ms) before access-token expiry at which the proactive scheduler
15
+ * re-mints. Mirrors `HttpService`'s per-request `TOKEN_REFRESH_LEAD_SECONDS`
16
+ * (60s) so the scheduled re-mint and the request-time preflight use the same
17
+ * window — the scheduler just fires it during idle/background.
18
+ */
19
+ exports.TOKEN_REFRESH_LEAD_MS = 60000;
20
+ /**
21
+ * Max `setTimeout` delay (2^31 − 1 ms, ~24.8 days). A larger delay overflows
22
+ * the int32 timer field and fires IMMEDIATELY — with a long-TTL token that
23
+ * turns the reschedule-on-finish loop into a tight busy refresh. Clamp to it.
24
+ */
25
+ const MAX_TIMEOUT_DELAY_MS = 2147483647;
26
+ /**
27
+ * Floor (ms) on ANY scheduled delay. An already-expired / in-lead-window token
28
+ * computes a non-positive `exp − now − lead`; without this floor that becomes
29
+ * `setTimeout(…, 0)`, and a FAILING re-mint (offline / server error) would
30
+ * re-arm at 0 in the finally block → a tight 100%-CPU busy loop. The floor
31
+ * guarantees every re-arm yields the event loop.
32
+ */
33
+ const MIN_SCHEDULE_DELAY_MS = 1000;
34
+ /**
35
+ * Backoff schedule (ms) applied when a scheduled re-mint FAILS: first retry
36
+ * after {@link MIN_FAILURE_BACKOFF_MS}, doubling up to {@link MAX_FAILURE_BACKOFF_MS}.
37
+ * Reset to 0 on any success or token change. This is what converts the former
38
+ * zero-delay failure loop into a bounded, backing-off retry.
39
+ */
40
+ const MIN_FAILURE_BACKOFF_MS = 5000;
41
+ const MAX_FAILURE_BACKOFF_MS = 5 * 60000;
42
+ /**
43
+ * Arm 1 — the device-secret mint, run under the owning client's PROCESS-WIDE
44
+ * single-flight (`httpService.runSingleFlightDeviceSecretMint`).
45
+ *
46
+ * Concurrent lanes (cold boot, the proactive scheduler, a request-time preflight,
47
+ * a 401 retry, the socket token transport, or a tab-focus reconcile) must not
48
+ * each persist a different view of the mint response. Routing EVERY lane through
49
+ * this one single-flight makes concurrent callers await the SAME in-flight mint
50
+ * and all receive its result, so the durable store converges on one credential.
51
+ *
52
+ * On success it persists `nextDeviceSecret` (read-back-verified) BEFORE planting
53
+ * the access token; a failed durable persist yields `persist-failed` WITHOUT
54
+ * planting. This function performs NO store mutation on failure — the caller
55
+ * applies the drop/clear policy (which differs web vs native) from the returned
56
+ * status.
57
+ *
58
+ * `pin` makes the mint IDENTITY-BOUND: the request carries the pinned
59
+ * `accountId` (so the server mints that account's token without touching
60
+ * `activeAccountId`), and the persisted `sessionId`/`userId` are resolved from
61
+ * the PINNED account entry — never from `state.activeAccountId`, whose drift is
62
+ * exactly what the pin exists to stop.
63
+ */
64
+ async function refreshDeviceSecretArm(deps) {
65
+ const { oxy, store } = deps;
66
+ const pin = deps.pin ?? null;
67
+ return oxy.httpService.runSingleFlightDeviceSecretMint(async () => {
68
+ const persisted = await store.load();
69
+ if (!persisted?.deviceId || !persisted?.deviceSecret) {
70
+ return { status: 'no-secret' };
71
+ }
72
+ let mint;
73
+ try {
74
+ // Unpinned callers pass NO third argument at all, so the account-mode call
75
+ // shape (and therefore the request body) is untouched by this feature.
76
+ mint = pin
77
+ ? await oxy.mintFromDeviceSecret(persisted.deviceId, persisted.deviceSecret, {
78
+ accountId: pin.accountId,
79
+ })
80
+ : await oxy.mintFromDeviceSecret(persisted.deviceId, persisted.deviceSecret);
81
+ }
82
+ catch (error) {
83
+ if ((0, errorUtils_1.extractErrorStatus)(error) === 401) {
84
+ // Structural read (not `instanceof Error`): the thrown value can be a
85
+ // plain ApiError-shaped object or come from another realm.
86
+ const message = error?.message;
87
+ const body = typeof message === 'string' ? message : '';
88
+ // ONLY the server's explicit `invalid_device_secret` proves the presented
89
+ // secret is bad and may clear the durable device credential. `no_active_session`
90
+ // is an authoritative signed-out. ANY OTHER 401 — a middleware/CSRF/proxy 401,
91
+ // an ALB/starting-instance 401, a CORS error page, etc., all common during a
92
+ // deploy/restart window — is NOT proof the secret diverged: treat it as
93
+ // transient and KEEP the credential so a later attempt self-heals. Wiping the
94
+ // credential on an ambiguous 401 is what logged users out on every deploy,
95
+ // ecosystem-wide.
96
+ if (body.includes('invalid_device_secret'))
97
+ return { status: 'invalid-secret' };
98
+ if (body.includes('no_active_session'))
99
+ return { status: 'no-session' };
100
+ // A pinned mint whose account left the device set. The secret is intact —
101
+ // never classify this as a bad secret, or the caller would drop a healthy
102
+ // credential over a stale identity binding.
103
+ if (body.includes('account_not_on_device'))
104
+ return { status: 'account-not-on-device' };
105
+ return { status: 'transient' };
106
+ }
107
+ return { status: 'transient' };
108
+ }
109
+ // The account this session is BOUND to: the pinned one when identity-bound
110
+ // (the server already minted for it), else the device's active account.
111
+ const boundAccountId = pin ? pin.accountId : mint.state.activeAccountId;
112
+ const bound = mint.state.accounts.find((a) => a.accountId === boundAccountId);
113
+ const next = {
114
+ ...persisted,
115
+ deviceId: mint.state.deviceId,
116
+ deviceSecret: mint.nextDeviceSecret,
117
+ accessToken: mint.accessToken,
118
+ expiresAt: mint.expiresAt,
119
+ ...(bound ? { sessionId: bound.sessionId, userId: bound.accountId } : {}),
120
+ };
121
+ // Persist nextDeviceSecret (read-back-verified) BEFORE planting the token.
122
+ // A failed durable persist must NOT plant.
123
+ const persistedOk = await store.save(next);
124
+ if (!persistedOk) {
125
+ return { status: 'persist-failed' };
126
+ }
127
+ oxy.setTokens(mint.accessToken);
128
+ return {
129
+ status: 'ok',
130
+ token: mint.accessToken,
131
+ sessionId: next.sessionId,
132
+ userId: next.userId,
133
+ state: mint.state,
134
+ };
135
+ });
136
+ }
137
+ /**
138
+ * Re-mint the persisted session and return the fresh access token, or `null`
139
+ * when no arm could produce one.
140
+ *
141
+ * Arm 1 (`POST /session/device/token`, via {@link refreshDeviceSecretArm}): mint
142
+ * from the persisted `deviceId` + `deviceSecret`. On a 401 the secret is diverged
143
+ * or the device has no live session: drop the secret so the mint lane stops (or
144
+ * clear the store on web, where there is no fallback), then fall to arm 2 on
145
+ * native. A transient error — or a durable-persist failure — leaves the store and
146
+ * returns `null` WITHOUT falling to shared-key (those are not bad-secret signals).
147
+ *
148
+ * Arm 2 (native shared-keychain): when the secret is absent or was just rejected,
149
+ * re-mint via `signInWithSharedIdentity` (which plants tokens). On success the
150
+ * recovered `{deviceId, deviceSecret, …}` is PERSISTED so the fast device-secret
151
+ * lane is repopulated (mirrors the cold boot's `shared-key-signin` step) — an
152
+ * in-session shared-key recovery must not leave the fast-lane credential empty.
153
+ *
154
+ * IDENTITY-BOUND clients (`deps.identity`) run a different arm 2: the
155
+ * shared-keychain lane is DISABLED (its cross-app slot may hold a different
156
+ * identity) and replaced by {@link establishIdentitySession}, which re-signs a
157
+ * challenge with the PRIMARY local key and rewrites the pin. Arm 1 is pinned.
158
+ */
159
+ async function refreshPersistedSession(deps) {
160
+ const { oxy, store } = deps;
161
+ const identity = deps.identity ?? null;
162
+ // The shared keychain is never an identity-bound client's recovery path.
163
+ const allowSharedKeyFallback = identity ? false : (deps.allowSharedKeyFallback ?? (0, platform_1.isNative)());
164
+ // Resolved per call: a re-established identity session can move the pin, and a
165
+ // replaced/removed local key clears it (in which case arm 1 must NOT mint —
166
+ // an unpinned mint would adopt whatever account the device switched to).
167
+ const pin = identity ? await (0, identitySession_1.resolveIdentityPin)(identity) : null;
168
+ if (identity && !pin) {
169
+ return recoverIdentitySession(oxy, store, identity);
170
+ }
171
+ const arm1 = await refreshDeviceSecretArm({ oxy, store, pin });
172
+ switch (arm1.status) {
173
+ case 'ok':
174
+ return arm1.token;
175
+ case 'transient':
176
+ logger_1.logger.debug('Persisted deviceSecret mint failed (transient) — keeping store', { component: 'refresh', method: 'refreshPersistedSession' });
177
+ return null;
178
+ case 'persist-failed':
179
+ // The server rotated the secret but it did not durably persist. Do NOT fall
180
+ // to shared-key and do NOT plant — a later attempt re-mints (the process
181
+ // mirror still holds the rotated secret the server accepts) and can persist
182
+ // once storage recovers. Never advertise a session on an unsaved secret.
183
+ logger_1.logger.error('Device-secret mint rotated the secret but it could not be durably persisted — refusing to plant (a later attempt re-mints)', undefined, { component: 'refresh', method: 'refreshPersistedSession' });
184
+ return null;
185
+ case 'invalid-secret':
186
+ case 'no-session': {
187
+ // 401: secret diverged or no live session. When a key-based arm 2 can still
188
+ // recover (native shared key, or an identity-bound client's own primary
189
+ // key) drop ONLY the secret and keep the deviceId; otherwise (web) the
190
+ // session is over — clear the store.
191
+ const persisted = await store.load();
192
+ if (allowSharedKeyFallback || identity) {
193
+ if (persisted) {
194
+ await store.save({ ...persisted, deviceSecret: undefined });
195
+ }
196
+ }
197
+ else {
198
+ await store.clear();
199
+ }
200
+ break;
201
+ }
202
+ case 'account-not-on-device':
203
+ // The pinned account left this device's session set. The secret is healthy —
204
+ // leave the store untouched and let the identity arm re-establish.
205
+ logger_1.logger.debug('Pinned device-secret mint rejected: the pinned account is no longer on this device — re-establishing from the identity key', { component: 'refresh', method: 'refreshPersistedSession' });
206
+ break;
207
+ case 'no-secret':
208
+ break;
209
+ }
210
+ if (identity) {
211
+ return recoverIdentitySession(oxy, store, identity);
212
+ }
213
+ if (allowSharedKeyFallback) {
214
+ try {
215
+ const session = await oxy.signInWithSharedIdentity();
216
+ if (session?.accessToken) {
217
+ // Repopulate the fast device-secret lane from the shared-key re-mint.
218
+ if (session.deviceId && session.deviceSecret) {
219
+ await store.save({
220
+ sessionId: session.sessionId,
221
+ userId: session.user.id,
222
+ deviceId: session.deviceId,
223
+ deviceSecret: session.deviceSecret,
224
+ accessToken: session.accessToken,
225
+ expiresAt: session.expiresAt,
226
+ });
227
+ }
228
+ return session.accessToken;
229
+ }
230
+ }
231
+ catch (error) {
232
+ logger_1.logger.debug('Shared-key re-mint fallback failed', { component: 'refresh', method: 'refreshPersistedSession' }, error);
233
+ }
234
+ }
235
+ return null;
236
+ }
237
+ /**
238
+ * Arm 2 for an IDENTITY-BOUND client: re-establish the session from the PRIMARY
239
+ * local key and rewrite the pin (`establishIdentitySession` plants the token and
240
+ * persists the device credential itself).
241
+ *
242
+ * Returns `null` — never throws — when there is no local identity, the verify
243
+ * yielded no token, or the exchange failed: the caller treats that as "could not
244
+ * refresh", exactly like the shared-key arm. A locked keychain therefore ends
245
+ * signed out rather than falling back to the device's active account.
246
+ */
247
+ async function recoverIdentitySession(oxy, store, binding) {
248
+ try {
249
+ const established = await (0, identitySession_1.establishIdentitySession)({ oxy, store, binding });
250
+ return established?.session.accessToken ?? null;
251
+ }
252
+ catch (error) {
253
+ logger_1.logger.debug('Identity-key re-sign-in failed', { component: 'refresh', method: 'recoverIdentitySession' }, error);
254
+ return null;
255
+ }
256
+ }
257
+ /**
258
+ * Build the reactive `AuthRefreshHandler` (arm 1 + arm 2). Install it via
259
+ * {@link installAuthRefreshHandler} or directly on
260
+ * `oxy.httpService.setAuthRefreshHandler`. `HttpService` owns single-flight
261
+ * dedup + cooldown, so the timer, the request-time preflight, and a 401 all
262
+ * collapse to one network attempt.
263
+ */
264
+ function createAuthRefreshHandler(deps) {
265
+ return async (_reason) => {
266
+ return refreshPersistedSession(deps);
267
+ };
268
+ }
269
+ /**
270
+ * Install the unified refresh handler on the owner client's `HttpService`.
271
+ * Returns a disposer that removes it.
272
+ */
273
+ function installAuthRefreshHandler(deps) {
274
+ deps.oxy.httpService.setAuthRefreshHandler(createAuthRefreshHandler(deps));
275
+ return () => {
276
+ deps.oxy.httpService.setAuthRefreshHandler(null);
277
+ };
278
+ }
279
+ /**
280
+ * Start the proactive re-mint scheduler against `oxy`.
281
+ *
282
+ * Schedules a single timer to fire {@link TOKEN_REFRESH_LEAD_MS} before the
283
+ * current access token's `exp`, calling
284
+ * `oxy.httpService.refreshAccessToken('preflight')` (which runs the installed
285
+ * handler; deduped + cooldown-guarded). After every attempt it reschedules
286
+ * from the possibly-rotated token. It also reschedules whenever the token
287
+ * changes (a sign-out that clears the token cancels the timer) and, on web
288
+ * tab-focus, re-mints immediately if already inside the lead window (a
289
+ * long-hidden tab throttles timers, so the token can be expired on return).
290
+ *
291
+ * No-ops cleanly when there is no token or an opaque/no-`exp` token — the
292
+ * reactive 401 path stays the only re-mint trigger in that case. The timer is
293
+ * `.unref?.()`-ed so it never keeps a Node/Jest event loop alive.
294
+ */
295
+ function startTokenRefreshScheduler(oxy) {
296
+ let disposed = false;
297
+ let timer = null;
298
+ // 0 = no active backoff; grows on consecutive failures, resets on success /
299
+ // token change. Keeps a failing re-mint from re-arming at zero delay.
300
+ let failureBackoffMs = 0;
301
+ const clearTimer = () => {
302
+ if (timer !== null) {
303
+ clearTimeout(timer);
304
+ timer = null;
305
+ }
306
+ };
307
+ /** Arm the timer for `delayMs`, flooring at {@link MIN_SCHEDULE_DELAY_MS} and capping at the int32 max. */
308
+ const armTimer = (delayMs) => {
309
+ clearTimer();
310
+ const clamped = Math.min(Math.max(delayMs, MIN_SCHEDULE_DELAY_MS), MAX_TIMEOUT_DELAY_MS);
311
+ timer = setTimeout(runRefresh, clamped);
312
+ // Never keep a Node/Jest event loop alive for a background re-mint timer.
313
+ timer.unref?.();
314
+ };
315
+ /** Schedule the next re-mint from the current token's expiry (the healthy path). */
316
+ const scheduleFromExpiry = () => {
317
+ clearTimer();
318
+ if (disposed || !oxy.getAccessToken()) {
319
+ return;
320
+ }
321
+ const expSeconds = oxy.getAccessTokenExpiry();
322
+ if (expSeconds === null) {
323
+ return;
324
+ }
325
+ armTimer(expSeconds * 1000 - Date.now() - exports.TOKEN_REFRESH_LEAD_MS);
326
+ };
327
+ const runRefresh = () => {
328
+ // Clear any pending timer up front so an out-of-band trigger (focus) plus
329
+ // a fired timer can never double-run.
330
+ clearTimer();
331
+ void oxy.httpService.refreshAccessToken('preflight')
332
+ .then((token) => Boolean(token))
333
+ .catch(() => false)
334
+ .then((ok) => {
335
+ if (disposed) {
336
+ return;
337
+ }
338
+ if (ok) {
339
+ // Success — drop any backoff and re-arm from the rotated token's exp.
340
+ failureBackoffMs = 0;
341
+ scheduleFromExpiry();
342
+ return;
343
+ }
344
+ // Failure — back off (never re-arm at zero) and retry.
345
+ failureBackoffMs =
346
+ failureBackoffMs === 0
347
+ ? MIN_FAILURE_BACKOFF_MS
348
+ : Math.min(failureBackoffMs * 2, MAX_FAILURE_BACKOFF_MS);
349
+ armTimer(failureBackoffMs);
350
+ });
351
+ };
352
+ /** Public (re)schedule entry: a fresh token / focus signal — drop backoff and arm from expiry. */
353
+ const schedule = () => {
354
+ failureBackoffMs = 0;
355
+ scheduleFromExpiry();
356
+ };
357
+ const onFocus = () => {
358
+ if (disposed || !oxy.getAccessToken()) {
359
+ return;
360
+ }
361
+ const expSeconds = oxy.getAccessTokenExpiry();
362
+ if (expSeconds === null) {
363
+ return;
364
+ }
365
+ const remainingMs = expSeconds * 1000 - Date.now();
366
+ if (remainingMs <= exports.TOKEN_REFRESH_LEAD_MS) {
367
+ runRefresh();
368
+ }
369
+ else {
370
+ schedule();
371
+ }
372
+ };
373
+ const unsubscribeTokens = oxy.onTokensChanged(() => {
374
+ if (!disposed) {
375
+ schedule();
376
+ }
377
+ });
378
+ let removeFocusListener = null;
379
+ if (typeof document !== 'undefined') {
380
+ const handler = () => {
381
+ if (document.visibilityState === 'visible') {
382
+ onFocus();
383
+ }
384
+ };
385
+ document.addEventListener('visibilitychange', handler);
386
+ removeFocusListener = () => document.removeEventListener('visibilitychange', handler);
387
+ }
388
+ schedule();
389
+ return {
390
+ dispose() {
391
+ disposed = true;
392
+ clearTimer();
393
+ unsubscribeTokens();
394
+ removeFocusListener?.();
395
+ removeFocusListener = null;
396
+ },
397
+ };
398
+ }
@@ -0,0 +1,34 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createSessionClientHost = createSessionClientHost;
4
+ /**
5
+ * Thin `SessionClientHost` adapter over an `OxyServices` instance.
6
+ *
7
+ * `SessionClient` is host-agnostic: it only needs a REST + token surface.
8
+ * `OxyServices` already exposes all of that except `getCurrentAccountId`,
9
+ * which has no direct equivalent — the adapter holds a mutable ref set by
10
+ * the caller (`OxyContext` in `@oxy.so/services`) via `setCurrentAccountId`.
11
+ *
12
+ * Shared here (rather than duplicated per consumer) because it is entirely
13
+ * platform-agnostic: every method it calls exists identically on
14
+ * `OxyServices` regardless of host (web, Expo/RN, Node).
15
+ */
16
+ function createSessionClientHost(oxyServices) {
17
+ let currentAccountId = null;
18
+ let deviceCredential = null;
19
+ return {
20
+ makeRequest: (method, url, data, options) => oxyServices.makeRequest(method, url, data, options),
21
+ getBaseURL: () => oxyServices.getBaseURL(),
22
+ getAccessToken: () => oxyServices.getAccessToken(),
23
+ getDeviceCredential: () => deviceCredential,
24
+ onTokensChanged: (listener) => oxyServices.onTokensChanged(listener),
25
+ setTokens: (accessToken) => oxyServices.setTokens(accessToken),
26
+ getCurrentAccountId: () => currentAccountId,
27
+ setCurrentAccountId: (id) => {
28
+ currentAccountId = id;
29
+ },
30
+ setDeviceCredential: (credential) => {
31
+ deviceCredential = credential;
32
+ },
33
+ };
34
+ }
@@ -0,0 +1,247 @@
1
+ "use strict";
2
+ /**
3
+ * The shared native DeviceSession credential — one device, one session, many apps.
4
+ *
5
+ * ## What this is, and what it deliberately is NOT
6
+ *
7
+ * Two different secrets can make a native Oxy app boot signed in, and conflating
8
+ * them is the bug this module exists to end:
9
+ *
10
+ * Commons private identity key → identity and signed approval ONLY. It is
11
+ * self-custody, irreplaceable, and must never
12
+ * become the general app session transport.
13
+ * Shared DeviceSession credential → THIS module. An ordinary `deviceId` +
14
+ * `deviceSecret` pair that restores ordinary
15
+ * official apps, follows the device's active
16
+ * context, and is individually rotatable and
17
+ * revocable server-side.
18
+ *
19
+ * An ordinary app needs the second one. Handing it the first — which is what the
20
+ * `shared-key-signin` lane does today — gives every sibling app the ability to
21
+ * sign as the user's cryptographic identity to obtain something as mundane as a
22
+ * session. That lane stays as a recovery/compatibility path; this one supersedes
23
+ * it for the ordinary case.
24
+ *
25
+ * ## Why sharing one credential is safe against the server
26
+ *
27
+ * `POST /session/device/token` does NOT rotate: the response echoes the presented
28
+ * secret back as `nextDeviceSecret` precisely so several first-party apps sharing
29
+ * one `DeviceSession` can refresh concurrently without invalidating one another.
30
+ * So N apps holding one credential is a supported server state, not a race — and
31
+ * because they then share ONE `DeviceSession`, they automatically share its
32
+ * `activeContextId` and its token-free `session_state` broadcasts.
33
+ *
34
+ * ## The one safety rule everything here is built around
35
+ *
36
+ * A read that FAILED and a slot that is EMPTY must never be the same value. The
37
+ * empty answer authorises writes (seed the slot); the failed answer must
38
+ * authorise nothing. {@link SharedDeviceCredentialRead} keeps them apart at the
39
+ * type level, and every decision below fails closed on anything that is not a
40
+ * positive `absent`/`present`.
41
+ *
42
+ * Platform-agnostic: the actual keychain / keystore access is injected as a
43
+ * {@link SharedDeviceCredentialStore} by `@oxy.so/services`. ESM-safe, no
44
+ * `require()`, no react/react-native/expo imports.
45
+ */
46
+ Object.defineProperty(exports, "__esModule", { value: true });
47
+ exports.readLocalDeviceCredential = readLocalDeviceCredential;
48
+ exports.normalizeSharedDeviceSessionRead = normalizeSharedDeviceSessionRead;
49
+ exports.decideSharedDeviceJoin = decideSharedDeviceJoin;
50
+ exports.decideSharedDevicePublish = decideSharedDevicePublish;
51
+ exports.publishProvenDeviceCredential = publishProvenDeviceCredential;
52
+ exports.createSharedMirroringAuthStateStore = createSharedMirroringAuthStateStore;
53
+ const logger_1 = require("../logger");
54
+ /** The usable `{deviceId, deviceSecret}` pair in a persisted state, or null. */
55
+ function readLocalDeviceCredential(state) {
56
+ if (!state?.deviceId || !state.deviceSecret) {
57
+ return null;
58
+ }
59
+ return { deviceId: state.deviceId, deviceSecret: state.deviceSecret };
60
+ }
61
+ /**
62
+ * Narrow an UNTRUSTED bridge payload into a {@link SharedDeviceCredentialRead}.
63
+ *
64
+ * Anything unrecognised resolves to `unavailable`, never `absent`. A native
65
+ * module returning a shape this build does not understand (an older app in the
66
+ * signing group, a partially-applied upgrade) means we do not KNOW whether the
67
+ * device has a shared session — and "do not know" must never authorise a write
68
+ * that would overwrite one.
69
+ */
70
+ function normalizeSharedDeviceSessionRead(raw) {
71
+ if (!raw || typeof raw !== 'object') {
72
+ return { state: 'unavailable', cause: new Error('shared device session bridge returned a non-object') };
73
+ }
74
+ const payload = raw;
75
+ if (payload.status === 'absent') {
76
+ return { state: 'absent' };
77
+ }
78
+ if (payload.status === 'present') {
79
+ const deviceId = payload.deviceId;
80
+ const deviceSecret = payload.deviceSecret;
81
+ if (typeof deviceId === 'string' &&
82
+ deviceId.length > 0 &&
83
+ typeof deviceSecret === 'string' &&
84
+ deviceSecret.length > 0) {
85
+ return { state: 'present', credential: { deviceId, deviceSecret } };
86
+ }
87
+ // A `present` verdict whose payload is incomplete is a broken slot, not an
88
+ // empty one. Reporting `absent` here would let the next successful sign-in
89
+ // overwrite whatever is really in there.
90
+ return {
91
+ state: 'unavailable',
92
+ cause: new Error('shared device session bridge reported `present` with an incomplete credential'),
93
+ };
94
+ }
95
+ if (payload.status === 'unavailable') {
96
+ const reason = typeof payload.reason === 'string' ? payload.reason : 'unknown';
97
+ return { state: 'unavailable', cause: new Error(`shared device session slot unavailable: ${reason}`) };
98
+ }
99
+ return {
100
+ state: 'unavailable',
101
+ cause: new Error(`shared device session bridge returned an unrecognised status: ${String(payload.status)}`),
102
+ };
103
+ }
104
+ /**
105
+ * Should this app adopt the shared credential? Pure.
106
+ *
107
+ * Adoption happens in exactly ONE case: the shared slot holds a credential and
108
+ * this app has none of its own. That single rule delivers the product
109
+ * requirement — a newly installed official app joins the device's existing
110
+ * session without another QR — while making the two failure modes that matter
111
+ * unreachable:
112
+ *
113
+ * - An app that is already signed in is NEVER moved onto another credential, so
114
+ * "no user is signed out merely because one app updates first" holds by
115
+ * construction, in both upgrade directions.
116
+ * - A failed read never looks like an empty slot, so a locked keychain resolves
117
+ * to "keep what I have" rather than "this is a fresh device".
118
+ *
119
+ * The cost is stated plainly: two apps that each already own a DIFFERENT device
120
+ * session stay on their own until one of them loses its credential. Converging
121
+ * them would mean signing one of them out or a server-side device merge, and
122
+ * neither is something a boot path may do silently.
123
+ */
124
+ function decideSharedDeviceJoin(local, shared) {
125
+ if (readLocalDeviceCredential(local) !== null) {
126
+ return { action: 'skip', reason: 'local-credential-present' };
127
+ }
128
+ switch (shared.state) {
129
+ case 'present':
130
+ return { action: 'adopt', credential: shared.credential };
131
+ case 'absent':
132
+ return { action: 'skip', reason: 'shared-empty' };
133
+ case 'unavailable':
134
+ return { action: 'skip', reason: 'shared-unreadable' };
135
+ case 'unsupported':
136
+ return { action: 'skip', reason: 'shared-unsupported' };
137
+ }
138
+ }
139
+ /**
140
+ * Should this app write the credential it just proved into the shared slot? Pure.
141
+ *
142
+ * `proven` means the server accepted it moments ago — a successful sign-in or a
143
+ * successful mint. Only a proven credential is ever published, so the slot can
144
+ * never be seeded with something no app could use.
145
+ *
146
+ * A slot already held by a DIFFERENT `deviceId` is left alone. Overwriting it
147
+ * would silently migrate every other app on this device onto our session at their
148
+ * next cold boot — a real, user-visible change of who they are signed in as, and
149
+ * not something a background persist may decide.
150
+ */
151
+ function decideSharedDevicePublish(proven, shared) {
152
+ switch (shared.state) {
153
+ case 'unsupported':
154
+ return { action: 'skip', reason: 'shared-unsupported' };
155
+ case 'unavailable':
156
+ return { action: 'skip', reason: 'shared-unreadable' };
157
+ case 'absent':
158
+ return { action: 'publish' };
159
+ case 'present': {
160
+ if (shared.credential.deviceId !== proven.deviceId) {
161
+ return { action: 'skip', reason: 'owned-by-another-device' };
162
+ }
163
+ if (shared.credential.deviceSecret === proven.deviceSecret) {
164
+ return { action: 'skip', reason: 'already-current' };
165
+ }
166
+ // Same device, newer secret. Sign-in rotates the secret (the mint does
167
+ // not), so the just-proven one is the credential a fresh install should
168
+ // join with.
169
+ return { action: 'publish' };
170
+ }
171
+ }
172
+ }
173
+ /**
174
+ * Read the shared slot, apply {@link decideSharedDevicePublish}, and write when
175
+ * it says so. Best-effort by contract: the caller's own durable credential is
176
+ * already persisted, so a failure here only means a future install will have to
177
+ * sign in interactively.
178
+ */
179
+ async function publishProvenDeviceCredential(deps) {
180
+ const read = await deps.shared.read();
181
+ const decision = decideSharedDevicePublish(deps.credential, read);
182
+ if (decision.action === 'skip') {
183
+ if (decision.reason === 'shared-unreadable') {
184
+ logger_1.logger.debug('shared device credential slot unreadable — not publishing (an unreadable slot is never an empty one)', { component: 'sharedDeviceCredential', method: 'publishProvenDeviceCredential' });
185
+ }
186
+ return { status: 'skipped', reason: decision.reason };
187
+ }
188
+ const published = await deps.shared.publish(deps.credential);
189
+ return published ? { status: 'published' } : { status: 'publish-failed' };
190
+ }
191
+ /**
192
+ * Wrap a platform {@link AuthStateStore} so that every durable credential it
193
+ * persists is ALSO mirrored into the shared slot.
194
+ *
195
+ * Writes mirror automatically; reads do NOT adopt. That split is deliberate:
196
+ *
197
+ * - Mirroring on write is the right place because `save()` is where a proven
198
+ * credential lands, on every lane there is — interactive sign-in, the cold
199
+ * boot mint, the refresh scheduler, the 401 re-mint, shared-key recovery. One
200
+ * seam, no lane left out, and no new call site to forget.
201
+ * - Adopting on read would hide a change of WHO THIS APP IS SIGNED IN AS inside
202
+ * a storage primitive, and would run on every `load()`. Adoption is an
203
+ * explicit, once-per-boot cold-boot step instead (`shared-device-adopt`).
204
+ *
205
+ * `clear()` deliberately does NOT clear the shared slot. This app signing out is
206
+ * not authority over the device-wide join point: other apps may still be signed
207
+ * in on that same credential, and once the server session is really gone the
208
+ * credential mints `no_active_session` for everyone anyway.
209
+ */
210
+ function createSharedMirroringAuthStateStore(deps) {
211
+ const { local, shared } = deps;
212
+ // Process-local memo of the credential we last observed the shared slot to
213
+ // hold. Purely an optimization to keep the refresh scheduler from re-reading
214
+ // the keychain every mint; a slot wiped out from under us is re-seeded on the
215
+ // next launch rather than mid-process.
216
+ let mirrored = null;
217
+ return {
218
+ load: () => local.load(),
219
+ clear: () => local.clear(),
220
+ save: async (state) => {
221
+ // The durable local write is the contract this store owes its caller —
222
+ // run it first and report ITS result, unchanged. The mirror is additive.
223
+ const durablePersisted = await local.save(state);
224
+ const credential = readLocalDeviceCredential(state);
225
+ if (!credential) {
226
+ return durablePersisted;
227
+ }
228
+ if (mirrored !== null &&
229
+ mirrored.deviceId === credential.deviceId &&
230
+ mirrored.deviceSecret === credential.deviceSecret) {
231
+ return durablePersisted;
232
+ }
233
+ try {
234
+ const outcome = await publishProvenDeviceCredential({ shared, credential });
235
+ if (outcome.status === 'published' || (outcome.status === 'skipped' && outcome.reason === 'already-current')) {
236
+ mirrored = credential;
237
+ }
238
+ }
239
+ catch (error) {
240
+ // A store implementation is contractually non-throwing, but a mirror
241
+ // failure must never take down the durable write that already succeeded.
242
+ logger_1.logger.debug('mirroring the device credential into the shared slot threw — the local credential is unaffected', { component: 'sharedDeviceCredential', method: 'save' }, error);
243
+ }
244
+ return durablePersisted;
245
+ },
246
+ };
247
+ }