@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,76 @@
1
+ "use strict";
2
+ /**
3
+ * The device switcher's RENDER model: the directory's people and contexts with
4
+ * their names, handles and avatar URLs already resolved.
5
+ *
6
+ * Pure. It takes the projection {@link projectDevicePrincipals} produces from
7
+ * the directory and answers the five questions a row asks —
8
+ * what is it called, what is its handle, where is its avatar, what accent is it
9
+ * drawn in, may it be activated — so the views stay presentational and neither
10
+ * of them re-derives a display rule.
11
+ *
12
+ * One thing the flat account rows this replaced carried is deliberately absent,
13
+ * because the directory does not carry it and inventing it would mean going back
14
+ * to fetching another person's profiles: **email**. The directory profile is the
15
+ * minimum that renders a row, so the secondary line is the `@handle` — never a
16
+ * synthesized `username@oxy.so`.
17
+ *
18
+ * The accent is NOT in that category. It was, briefly, and it was wrong: an
19
+ * accent is part of drawing the row rather than profile data about its owner,
20
+ * and without it every non-active row falls back to the ambient theme accent, so
21
+ * a device holding two people draws them identically (issue #961). The server
22
+ * carries it on the directory profile, so no client has to guess or fetch.
23
+ *
24
+ * It lives here rather than in a UI package because there is more than one
25
+ * switcher — the SDK's account dialog and the `auth.oxy.so` chooser — and the
26
+ * whole point of ADR 0002 is that they render ONE list, built once.
27
+ */
28
+ Object.defineProperty(exports, "__esModule", { value: true });
29
+ exports.buildSwitcherRows = buildSwitcherRows;
30
+ exports.showsPrincipalHeaders = showsPrincipalHeaders;
31
+ const deviceDirectory_1 = require("./deviceDirectory");
32
+ function toContextRow(context, activeContextId, resolveAvatarUrl, locale) {
33
+ return {
34
+ contextId: context.contextId,
35
+ accountId: context.subject.accountId,
36
+ displayName: (0, deviceDirectory_1.directoryDisplayName)(context.subject.profile, locale),
37
+ handle: (0, deviceDirectory_1.directoryHandle)(context.subject.profile),
38
+ avatarUrl: resolveAvatarUrl(context.subject.profile.avatar),
39
+ color: context.subject.profile.color ?? null,
40
+ // Compared on the CONTEXT id, never the account id: on a device holding two
41
+ // people the same account is active through exactly one of them, and an
42
+ // account comparison would light up both rows.
43
+ isActive: context.contextId === activeContextId,
44
+ isDelegated: context.isDelegated,
45
+ canActivate: (0, deviceDirectory_1.canActivateContext)(context.subject),
46
+ };
47
+ }
48
+ /** The directory's people and their contexts, ready to render. */
49
+ function buildSwitcherRows(groups, activeContextId, resolveAvatarUrl, locale) {
50
+ return groups.map((group) => ({
51
+ principalId: group.principalId,
52
+ displayName: (0, deviceDirectory_1.directoryDisplayName)(group.profile, locale),
53
+ handle: (0, deviceDirectory_1.directoryHandle)(group.profile),
54
+ avatarUrl: resolveAvatarUrl(group.profile.avatar),
55
+ color: group.profile.color ?? null,
56
+ isActive: group.isActive,
57
+ contexts: group.contexts.map((context) => toContextRow(context, activeContextId, resolveAvatarUrl, locale)),
58
+ }));
59
+ }
60
+ /**
61
+ * Whether the switcher should name the person above each block.
62
+ *
63
+ * The question a header answers is "who is operating this account", and that is
64
+ * only a question worth printing once somebody holds MORE THAN ONE account
65
+ * here. Two people with one personal account each is the flat list again — every
66
+ * row already IS a person, and a header would just print each name twice.
67
+ *
68
+ * The moment any one of them can act as a second account, every group gets a
69
+ * header, including the single-context ones: an inconsistent list is harder to
70
+ * read than a slightly redundant one, and it is exactly then that "The Oxy
71
+ * Collective, under Nate" and "The Oxy Collective, under Alice" become two
72
+ * different rows that must be told apart.
73
+ */
74
+ function showsPrincipalHeaders(rows) {
75
+ return rows.some((row) => row.contexts.length > 1);
76
+ }
@@ -0,0 +1,256 @@
1
+ "use strict";
2
+ /**
3
+ * Identity pin — the durable binding between THIS device's PRIMARY identity key
4
+ * and the account that key authenticates as.
5
+ *
6
+ * An identity-bound client (Commons, the identity vault) must always act as the
7
+ * owner of the local signing key — permanently. The `DeviceSession` it shares
8
+ * with every other Oxy app on the same device tracks a MUTABLE `activeAccountId`
9
+ * that any sibling app can switch; following it silently changes both the user
10
+ * such a client renders and the bearer it sends. The pin is the client-side
11
+ * record that breaks that coupling: `{ publicKey, accountId }`, written when an
12
+ * identity-mode session is established (the only moment both facts are known
13
+ * first-hand), read on every boot, and reconciled against the live
14
+ * `KeyManager.getPublicKey()` before it is trusted (see
15
+ * `resolveIdentityPin` in `identitySession.ts`).
16
+ *
17
+ * It holds NO secret — a public key and an account id, both already known to the
18
+ * server — so it lives in the same per-origin storage as {@link PersistedAuthState}
19
+ * (`authStateStore.ts`) rather than the keychain, and mirrors that module's
20
+ * store shape: `load / save / clear`, an in-memory mirror, a read-back-verified
21
+ * durable write, and graceful degradation when storage is unavailable.
22
+ *
23
+ * ESM-safe (no `require()`); no react/react-native/expo imports.
24
+ */
25
+ Object.defineProperty(exports, "__esModule", { value: true });
26
+ exports.IDENTITY_PIN_STORAGE_KEY = void 0;
27
+ exports.identityPinMatches = identityPinMatches;
28
+ exports.createMemoryIdentityPinStore = createMemoryIdentityPinStore;
29
+ exports.createWebIdentityPinStore = createWebIdentityPinStore;
30
+ exports.createNativeIdentityPinStore = createNativeIdentityPinStore;
31
+ const logger_1 = require("../logger");
32
+ /**
33
+ * Versioned storage key. Deliberately distinct from the `oxy.auth.*` keys so a
34
+ * session sign-out (which clears the auth blob) and an identity change (which
35
+ * clears the pin) can never take each other down.
36
+ */
37
+ exports.IDENTITY_PIN_STORAGE_KEY = 'oxy.identity.pin.v1';
38
+ /**
39
+ * Structural check for a storable identity public key: `KeyManager` only ever
40
+ * persists secp256k1 hex — compressed (66 chars) or uncompressed (130). A stored
41
+ * value of any other shape is corrupt, so it is treated as "no pin" (fail
42
+ * closed) rather than compared. Full curve validation belongs to `KeyManager`;
43
+ * the pin's real authority is the reconcile against the live local key.
44
+ */
45
+ function isStorablePublicKey(value) {
46
+ if (typeof value !== 'string') {
47
+ return false;
48
+ }
49
+ if (value.length !== 66 && value.length !== 130) {
50
+ return false;
51
+ }
52
+ return /^[0-9a-fA-F]+$/.test(value);
53
+ }
54
+ /**
55
+ * Parse + shape-validate a stored blob. Returns `null` for anything that is not
56
+ * a well-formed {@link IdentityPin} (absent, malformed JSON, wrong types, junk
57
+ * public key) so a corrupt entry degrades to "not pinned" rather than throwing —
58
+ * and, critically, never yields a pin that could bind a client to the wrong
59
+ * account.
60
+ */
61
+ function deserialize(raw) {
62
+ if (!raw) {
63
+ return null;
64
+ }
65
+ let parsed;
66
+ try {
67
+ parsed = JSON.parse(raw);
68
+ }
69
+ catch {
70
+ return null;
71
+ }
72
+ if (!parsed || typeof parsed !== 'object') {
73
+ return null;
74
+ }
75
+ const candidate = parsed;
76
+ if (!isStorablePublicKey(candidate.publicKey)) {
77
+ return null;
78
+ }
79
+ if (typeof candidate.accountId !== 'string' || candidate.accountId.length === 0) {
80
+ return null;
81
+ }
82
+ return {
83
+ publicKey: candidate.publicKey.toLowerCase(),
84
+ accountId: candidate.accountId,
85
+ };
86
+ }
87
+ /**
88
+ * Serialize a pin, or `null` when the caller handed over a value that would not
89
+ * survive {@link deserialize} — writing it would produce an entry that silently
90
+ * reads back as "not pinned".
91
+ */
92
+ function serialize(pin) {
93
+ if (!isStorablePublicKey(pin.publicKey) || pin.accountId.length === 0) {
94
+ return null;
95
+ }
96
+ return JSON.stringify({ publicKey: pin.publicKey.toLowerCase(), accountId: pin.accountId });
97
+ }
98
+ /**
99
+ * Whether `pin` still describes the identity currently on this device.
100
+ *
101
+ * `publicKey` comparison is case-insensitive (hex). A `null` local key is a
102
+ * definitive "no identity here" and therefore never a match — the caller clears
103
+ * the pin rather than binding to an account whose key is gone.
104
+ */
105
+ function identityPinMatches(pin, localPublicKey) {
106
+ if (!pin || !localPublicKey) {
107
+ return false;
108
+ }
109
+ return pin.publicKey.toLowerCase() === localPublicKey.toLowerCase();
110
+ }
111
+ /**
112
+ * A process-lifetime, in-memory {@link IdentityPinStore}. Used directly for
113
+ * tests/SSR and as the degraded fallback of the web store.
114
+ */
115
+ function createMemoryIdentityPinStore() {
116
+ let current = null;
117
+ return {
118
+ load: async () => current,
119
+ save: async (pin) => {
120
+ if (!serialize(pin)) {
121
+ return false;
122
+ }
123
+ // Memory IS this store's durability backing — the write always lands.
124
+ current = { publicKey: pin.publicKey.toLowerCase(), accountId: pin.accountId };
125
+ return true;
126
+ },
127
+ clear: async () => {
128
+ current = null;
129
+ },
130
+ };
131
+ }
132
+ /**
133
+ * Read the ambient `localStorage`, tolerating the case where merely ACCESSING
134
+ * `window.localStorage` throws (sandboxed iframe `SecurityError`). Returns
135
+ * `null` when storage is unavailable.
136
+ */
137
+ function safeGetLocalStorage() {
138
+ try {
139
+ if (typeof globalThis === 'undefined') {
140
+ return null;
141
+ }
142
+ const store = globalThis.localStorage;
143
+ return store ?? null;
144
+ }
145
+ catch {
146
+ return null;
147
+ }
148
+ }
149
+ /**
150
+ * A `localStorage`-backed {@link IdentityPinStore}. Degrades to an in-memory
151
+ * store when `localStorage` is unreachable, and keeps an in-memory mirror so a
152
+ * failed persist still pins THIS page's lifetime.
153
+ */
154
+ function createWebIdentityPinStore() {
155
+ const storage = safeGetLocalStorage();
156
+ if (!storage) {
157
+ return createMemoryIdentityPinStore();
158
+ }
159
+ // `undefined` = never written this session → fall back to storage; any set
160
+ // value (including `null` after clear) is authoritative.
161
+ let sessionMirror;
162
+ return {
163
+ load: async () => {
164
+ if (sessionMirror !== undefined) {
165
+ return sessionMirror;
166
+ }
167
+ try {
168
+ return deserialize(storage.getItem(exports.IDENTITY_PIN_STORAGE_KEY));
169
+ }
170
+ catch {
171
+ return null;
172
+ }
173
+ },
174
+ save: async (pin) => {
175
+ const json = serialize(pin);
176
+ if (!json) {
177
+ logger_1.logger.error('[identityPin] refusing to persist a malformed identity pin', undefined, { component: 'identityPin' });
178
+ return false;
179
+ }
180
+ sessionMirror = { publicKey: pin.publicKey.toLowerCase(), accountId: pin.accountId };
181
+ try {
182
+ storage.setItem(exports.IDENTITY_PIN_STORAGE_KEY, json);
183
+ if (storage.getItem(exports.IDENTITY_PIN_STORAGE_KEY) === json) {
184
+ return true;
185
+ }
186
+ logger_1.logger.error('[identityPin] read-back mismatch after save — the identity pin did not persist; this process stays pinned via the in-memory mirror but the next boot must re-establish the identity session', undefined, { component: 'identityPin' });
187
+ return false;
188
+ }
189
+ catch (error) {
190
+ logger_1.logger.error('[identityPin] persist threw — the identity pin did not persist; this process stays pinned via the in-memory mirror but the next boot must re-establish the identity session', error, { component: 'identityPin' });
191
+ return false;
192
+ }
193
+ },
194
+ clear: async () => {
195
+ sessionMirror = null;
196
+ try {
197
+ storage.removeItem(exports.IDENTITY_PIN_STORAGE_KEY);
198
+ }
199
+ catch (error) {
200
+ logger_1.logger.debug('[identityPin] clear failed', { component: 'identityPin' }, error);
201
+ }
202
+ },
203
+ };
204
+ }
205
+ /**
206
+ * A native {@link IdentityPinStore} over an injected async key/value store —
207
+ * the same seam `createNativeAuthStateStore` uses, so `@oxy.so/core` never
208
+ * imports `expo-secure-store`.
209
+ */
210
+ function createNativeIdentityPinStore(storage) {
211
+ let sessionMirror;
212
+ return {
213
+ load: async () => {
214
+ if (sessionMirror !== undefined) {
215
+ return sessionMirror;
216
+ }
217
+ try {
218
+ return deserialize(await storage.getItem(exports.IDENTITY_PIN_STORAGE_KEY));
219
+ }
220
+ catch {
221
+ return null;
222
+ }
223
+ },
224
+ save: async (pin) => {
225
+ const json = serialize(pin);
226
+ if (!json) {
227
+ logger_1.logger.error('[identityPin] refusing to persist a malformed identity pin', undefined, { component: 'identityPin' });
228
+ return false;
229
+ }
230
+ sessionMirror = { publicKey: pin.publicKey.toLowerCase(), accountId: pin.accountId };
231
+ try {
232
+ await storage.setItem(exports.IDENTITY_PIN_STORAGE_KEY, json);
233
+ // A native write can resolve WITHOUT throwing yet not land, so a
234
+ // read-back is the only reliable proof.
235
+ if ((await storage.getItem(exports.IDENTITY_PIN_STORAGE_KEY)) === json) {
236
+ return true;
237
+ }
238
+ logger_1.logger.error('[identityPin] read-back mismatch after save — the identity pin did not persist; this app run stays pinned via the in-memory mirror but the next cold start must re-establish the identity session', undefined, { component: 'identityPin' });
239
+ return false;
240
+ }
241
+ catch (error) {
242
+ logger_1.logger.error('[identityPin] persist threw — the identity pin did not persist; this app run stays pinned via the in-memory mirror but the next cold start must re-establish the identity session', error, { component: 'identityPin' });
243
+ return false;
244
+ }
245
+ },
246
+ clear: async () => {
247
+ sessionMirror = null;
248
+ try {
249
+ await storage.removeItem(exports.IDENTITY_PIN_STORAGE_KEY);
250
+ }
251
+ catch (error) {
252
+ logger_1.logger.debug('[identityPin] clear failed', { component: 'identityPin' }, error);
253
+ }
254
+ },
255
+ };
256
+ }
@@ -0,0 +1,135 @@
1
+ "use strict";
2
+ /**
3
+ * Identity-bound session — pin reconciliation + establishment.
4
+ *
5
+ * This is the SDK half of "an identity vault's authenticated user is whoever
6
+ * owns the local primary key". Two operations, both consumed by the cold boot
7
+ * (`boot/sessionColdBoot.ts`) and the re-mint lane (`session/refresh.ts`):
8
+ *
9
+ * - {@link resolveIdentityPin} — read the persisted `{publicKey, accountId}`
10
+ * pin and reconcile it against the identity currently on this device. A
11
+ * definitive mismatch (the key was replaced, or is gone) CLEARS the pin; an
12
+ * INDETERMINATE read (keychain locked / storage threw) leaves it untouched.
13
+ * - {@link establishIdentitySession} — mint a session from the PRIMARY local
14
+ * key (`getPublicKey` → `requestChallenge` → `signChallenge` →
15
+ * `verifyChallenge`), persist the resulting device credential, and write the
16
+ * pin. This is the identity-mode replacement for the shared-keychain lane,
17
+ * which reads the CROSS-APP shared slot and may therefore hold a different
18
+ * identity than this device's primary.
19
+ *
20
+ * Both take their key/signature functions from an injectable {@link IdentityBinding}
21
+ * (defaulting to `KeyManager` / `SignatureService`) so the lanes above stay
22
+ * testable without a keychain.
23
+ *
24
+ * ESM-safe (no `require()`); no react/react-native/expo imports.
25
+ */
26
+ Object.defineProperty(exports, "__esModule", { value: true });
27
+ exports.resolveIdentityPin = resolveIdentityPin;
28
+ exports.establishIdentitySession = establishIdentitySession;
29
+ const keyManager_1 = require("../crypto/keyManager");
30
+ const signatureService_1 = require("../crypto/signatureService");
31
+ const identityPin_1 = require("./identityPin");
32
+ const logger_1 = require("../logger");
33
+ function readPublicKeyOf(binding) {
34
+ return binding.readPublicKey ?? (() => keyManager_1.KeyManager.getPublicKey());
35
+ }
36
+ function signChallengeOf(binding) {
37
+ return binding.signChallenge ?? ((challenge) => signatureService_1.SignatureService.signChallenge(challenge));
38
+ }
39
+ /**
40
+ * Read the persisted pin and reconcile it against the identity on this device.
41
+ *
42
+ * Returns the pin ONLY when the local primary public key still matches it — that
43
+ * is the single condition under which a client may bind its token and its
44
+ * rendered user to that account.
45
+ *
46
+ * Outcomes:
47
+ * - no pin stored → `null` (nothing to clear).
48
+ * - local key MATCHES → the pin (trusted).
49
+ * - local key read succeeded and differs / is absent → the identity was
50
+ * replaced or lost: CLEAR the pin and return `null`. Keeping it would pin the
51
+ * client to an account it can no longer prove control of.
52
+ * - the local key read THREW (keychain locked, storage unavailable) → return
53
+ * `null` WITHOUT clearing. A read that produced no verdict is never evidence
54
+ * of an identity change (the same rule `KeyManager` applies to its own
55
+ * transient errors); the caller falls through to the identity sign-in lane,
56
+ * which fails closed on a locked keychain rather than adopting a foreign
57
+ * account.
58
+ */
59
+ async function resolveIdentityPin(binding) {
60
+ const pin = await binding.pinStore.load();
61
+ if (!pin) {
62
+ return null;
63
+ }
64
+ let localPublicKey;
65
+ try {
66
+ localPublicKey = await readPublicKeyOf(binding)();
67
+ }
68
+ catch (error) {
69
+ logger_1.logger.debug('Identity key read did not produce a verdict — keeping the pin untouched', { component: 'identitySession', method: 'resolveIdentityPin' }, error);
70
+ return null;
71
+ }
72
+ if ((0, identityPin_1.identityPinMatches)(pin, localPublicKey)) {
73
+ return pin;
74
+ }
75
+ logger_1.logger.warn('Identity pin no longer matches the device identity key — clearing it (the identity was replaced or removed)', { component: 'identitySession', method: 'resolveIdentityPin' });
76
+ await binding.pinStore.clear();
77
+ return null;
78
+ }
79
+ /**
80
+ * Establish a session for the device's PRIMARY identity key and pin it.
81
+ *
82
+ * `requestChallenge` → `signChallenge` → `verifyChallenge`; `verifyChallenge`
83
+ * plants the access token itself. The server resolves the account from the
84
+ * VERIFIED SIGNER, so the returned session is identity-authoritative — it
85
+ * ignores the device's `activeAccountId` entirely.
86
+ *
87
+ * Side effects on success: the durable device credential is persisted (so the
88
+ * next boot can take the fast pinned-mint lane) and the pin is written.
89
+ *
90
+ * Returns `null` — never throws — for the two "nothing to do" cases: no local
91
+ * identity (including every web caller, where `KeyManager` has no key), and a
92
+ * verify that produced no access token. Network/crypto failures propagate so the
93
+ * caller can classify them.
94
+ */
95
+ async function establishIdentitySession(args) {
96
+ const { oxy, store, binding, requestOptions } = args;
97
+ const publicKey = await readPublicKeyOf(binding)();
98
+ if (!publicKey) {
99
+ return null;
100
+ }
101
+ const { challenge } = await oxy.requestChallenge(publicKey, requestOptions);
102
+ const signed = await signChallengeOf(binding)(challenge);
103
+ if (signed.publicKey.toLowerCase() !== publicKey.toLowerCase()) {
104
+ // The signer disagrees with the key we resolved a challenge for — the
105
+ // identity changed mid-flight, or a custom signer was misconfigured. Refuse:
106
+ // verifying under a different key would bind this client to another account.
107
+ throw new Error('Identity sign-in aborted: the signing key does not match the device identity key');
108
+ }
109
+ // `signed.challenge` carries the SIGNATURE (mirrors `signChallengeWithSharedKey`).
110
+ const session = await oxy.verifyChallenge(signed.publicKey, challenge, signed.challenge, signed.timestamp, binding.deviceName, binding.deviceFingerprint, requestOptions);
111
+ if (!session?.accessToken) {
112
+ return null;
113
+ }
114
+ // Persist the rotating device credential so later boots re-mint through the
115
+ // fast `POST /session/device/token` lane instead of re-signing a challenge.
116
+ if (session.deviceId && session.deviceSecret) {
117
+ await store.save({
118
+ sessionId: session.sessionId,
119
+ userId: session.user.id,
120
+ deviceId: session.deviceId,
121
+ deviceSecret: session.deviceSecret,
122
+ accessToken: session.accessToken,
123
+ expiresAt: session.expiresAt,
124
+ });
125
+ }
126
+ const pin = { publicKey: publicKey.toLowerCase(), accountId: session.user.id };
127
+ // A failed pin persist is NOT fatal: this process is already pinned in memory,
128
+ // and a later boot without a pin skips the (unpinned) mint lane and re-runs
129
+ // this exact lane, which rewrites it. Never fail an established session on it.
130
+ const pinned = await binding.pinStore.save(pin);
131
+ if (!pinned) {
132
+ logger_1.logger.warn('Identity session established but the pin did not durably persist — the next cold start will re-establish it', { component: 'identitySession', method: 'establishIdentitySession' });
133
+ }
134
+ return { session, pin };
135
+ }
@@ -0,0 +1,121 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.boundAccountIdOf = boundAccountIdOf;
4
+ exports.deviceStateToClientSessions = deviceStateToClientSessions;
5
+ exports.activeSessionIdOf = activeSessionIdOf;
6
+ exports.activeUserOf = activeUserOf;
7
+ exports.accountIdsOf = accountIdsOf;
8
+ /**
9
+ * Pure projection helpers: `DeviceSessionState` (the device-scoped
10
+ * multi-account session-sync state produced by `SessionClient`) -> the
11
+ * shapes `@oxy.so/services` consumers render today
12
+ * (`ClientSession[]`, an active session id, an active `User`).
13
+ *
14
+ * No I/O. The caller fetches profiles via
15
+ * `oxyServices.getUsersByIds(accountIdsOf(state))` and builds `usersById`
16
+ * from the result before calling `deviceStateToClientSessions` /
17
+ * `activeUserOf`.
18
+ *
19
+ * Each projection takes an OPTIONAL `pinnedAccountId`. Omit it (or pass `null`)
20
+ * and the projection resolves the device's `activeAccountId` exactly as before.
21
+ * Pass it — an IDENTITY-BOUND client, whose user is fixed by the local identity
22
+ * key — and the projection resolves THAT account instead, so an account switch
23
+ * made by another app on the same device changes `state` but never the user this
24
+ * client renders.
25
+ */
26
+ /**
27
+ * The account a projection should resolve: the pin when one is supplied and
28
+ * non-empty, else the device's active account. An empty-string pin is treated as
29
+ * "not pinned" rather than as an account that can never match.
30
+ *
31
+ * Exported so no other projection over the same state answers it a second,
32
+ * subtly different way. A null state with
33
+ * a pin still resolves to the pin: the pinned identity is bound by a local key,
34
+ * not by device membership.
35
+ */
36
+ function boundAccountIdOf(state, pinnedAccountId) {
37
+ if (typeof pinnedAccountId === 'string' && pinnedAccountId.length > 0) {
38
+ return pinnedAccountId;
39
+ }
40
+ return state?.activeAccountId ?? null;
41
+ }
42
+ /**
43
+ * Maps every `SessionAccount` in `state.accounts` to a `ClientSession`.
44
+ *
45
+ * `DeviceSessionState` carries no per-account `expiresAt` / `lastActive` —
46
+ * both are set to `state.updatedAt` (converted to an ISO-8601 string; the
47
+ * wire value is an epoch-ms number) as a provisional value.
48
+ *
49
+ * `usersById` is accepted for signature symmetry with `activeUserOf` even
50
+ * though `ClientSession` only stores `userId` — a session is still
51
+ * projected for an account whose id is absent from `usersById` (no
52
+ * placeholder user is fabricated).
53
+ *
54
+ * `isCurrent` marks the PINNED account when one is supplied, so it can never
55
+ * disagree with {@link activeSessionIdOf} / {@link activeUserOf} for the same
56
+ * pin.
57
+ */
58
+ function deviceStateToClientSessions(state, usersById, pinnedAccountId) {
59
+ const provisionalTimestamp = new Date(state.updatedAt).toISOString();
60
+ const boundAccountId = boundAccountIdOf(state, pinnedAccountId);
61
+ return state.accounts.map((account) => ({
62
+ sessionId: account.sessionId,
63
+ deviceId: state.deviceId,
64
+ // provisional: expiresAt/lastActive are not carried on DeviceSessionState
65
+ expiresAt: provisionalTimestamp,
66
+ lastActive: provisionalTimestamp,
67
+ userId: account.accountId,
68
+ isCurrent: account.accountId === boundAccountId,
69
+ authuser: account.authuser,
70
+ operatedByUserId: account.operatedByUserId,
71
+ }));
72
+ }
73
+ /**
74
+ * The bound account's `sessionId`, or `null` when there is no state, no bound
75
+ * account, or that account has no session on this device.
76
+ *
77
+ * A pinned account that is ABSENT from `state.accounts` yields `null` — the
78
+ * honest signal that this device no longer carries a session for the pinned
79
+ * identity, which the caller answers by re-establishing the identity session
80
+ * (never by adopting the device's active account).
81
+ */
82
+ function activeSessionIdOf(state, pinnedAccountId) {
83
+ if (state === null) {
84
+ return null;
85
+ }
86
+ const boundAccountId = boundAccountIdOf(state, pinnedAccountId);
87
+ if (boundAccountId === null) {
88
+ return null;
89
+ }
90
+ const boundAccount = state.accounts.find((account) => account.accountId === boundAccountId);
91
+ return boundAccount?.sessionId ?? null;
92
+ }
93
+ /**
94
+ * The bound account's `User`, resolved from `usersById`. `null` when there is no
95
+ * state, no bound account, or the bound account id is absent from `usersById`.
96
+ *
97
+ * A pinned user is resolved from `usersById` alone — deliberately NOT gated on
98
+ * device membership — so a transient device-state gap cannot flicker the
99
+ * identity vault's rendered user. Whether the pinned session still exists on the
100
+ * device is answered by {@link activeSessionIdOf}.
101
+ */
102
+ function activeUserOf(state, usersById, pinnedAccountId) {
103
+ if (state === null) {
104
+ return null;
105
+ }
106
+ const boundAccountId = boundAccountIdOf(state, pinnedAccountId);
107
+ if (boundAccountId === null) {
108
+ return null;
109
+ }
110
+ return usersById.get(boundAccountId) ?? null;
111
+ }
112
+ /**
113
+ * All account ids in `state`, suitable for an `oxyServices.getUsersByIds(...)`
114
+ * fetch. `[]` for `null` state.
115
+ */
116
+ function accountIdsOf(state) {
117
+ if (state === null) {
118
+ return [];
119
+ }
120
+ return state.accounts.map((account) => account.accountId);
121
+ }