@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,227 @@
1
+ /**
2
+ * Centralized cache utility with TTL support
3
+ *
4
+ * This is a production-ready cache implementation used across the codebase
5
+ * for consistent caching behavior and performance optimization.
6
+ */
7
+ /**
8
+ * TTL-based cache implementation
9
+ *
10
+ * Features:
11
+ * - Automatic expiration based on TTL
12
+ * - Manual cleanup of expired entries
13
+ * - Statistics tracking (hits, misses, hit rate)
14
+ * - Type-safe generic interface
15
+ *
16
+ * @example
17
+ * ```typescript
18
+ * const cache = new TTLCache<string>(5 * 60 * 1000); // 5 minutes
19
+ *
20
+ * // Set with default TTL
21
+ * cache.set('key', 'value');
22
+ *
23
+ * // Set with custom TTL
24
+ * cache.set('key', 'value', 10 * 60 * 1000); // 10 minutes
25
+ *
26
+ * // Get value
27
+ * const value = cache.get('key');
28
+ *
29
+ * // Get statistics
30
+ * const stats = cache.getStats();
31
+ * ```
32
+ */
33
+ export class TTLCache {
34
+ /**
35
+ * Create a new TTL cache
36
+ * @param defaultTTL Default TTL in milliseconds (default: 5 minutes)
37
+ */
38
+ constructor(defaultTTL = 5 * 60 * 1000) {
39
+ this.cache = new Map();
40
+ this.hits = 0;
41
+ this.misses = 0;
42
+ this.defaultTTL = defaultTTL;
43
+ }
44
+ /**
45
+ * Get a value from cache
46
+ * @param key Cache key
47
+ * @returns Cached value or null if not found or expired
48
+ */
49
+ get(key) {
50
+ const entry = this.cache.get(key);
51
+ if (!entry) {
52
+ this.misses++;
53
+ return null;
54
+ }
55
+ const now = Date.now();
56
+ if (now > entry.expiresAt) {
57
+ this.cache.delete(key);
58
+ this.misses++;
59
+ return null;
60
+ }
61
+ this.hits++;
62
+ return entry.data;
63
+ }
64
+ /**
65
+ * Set a value in cache
66
+ * @param key Cache key
67
+ * @param data Data to cache
68
+ * @param ttl Optional TTL override (uses default if not provided). An
69
+ * explicit `0` or negative value is honored as "already expired" — the
70
+ * entry is stored with `expiresAt <= now`, so the next `get`/`has` treats
71
+ * it as a miss — rather than silently falling back to the default TTL.
72
+ */
73
+ set(key, data, ttl) {
74
+ const now = Date.now();
75
+ // Distinguish "no override provided" (undefined → use default) from an
76
+ // explicit `0`/negative (do not cache). `ttl || this.defaultTTL` collapsed
77
+ // both into the default, making `cacheTTL:0` impossible to honor.
78
+ const effectiveTTL = ttl === undefined ? this.defaultTTL : ttl;
79
+ const expiresAt = now + effectiveTTL;
80
+ this.cache.set(key, { data, timestamp: now, expiresAt });
81
+ }
82
+ /**
83
+ * Delete a specific cache entry
84
+ * @param key Cache key
85
+ * @returns true if entry was deleted, false if not found
86
+ */
87
+ delete(key) {
88
+ return this.cache.delete(key);
89
+ }
90
+ /**
91
+ * Clear all cache entries
92
+ */
93
+ clear() {
94
+ this.cache.clear();
95
+ this.hits = 0;
96
+ this.misses = 0;
97
+ }
98
+ /**
99
+ * Check if a key exists and is not expired
100
+ * @param key Cache key
101
+ * @returns true if key exists and is valid
102
+ */
103
+ has(key) {
104
+ const entry = this.cache.get(key);
105
+ if (!entry)
106
+ return false;
107
+ if (Date.now() > entry.expiresAt) {
108
+ this.cache.delete(key);
109
+ return false;
110
+ }
111
+ return true;
112
+ }
113
+ /**
114
+ * Get all valid cache keys
115
+ * @returns Array of valid cache keys
116
+ */
117
+ keys() {
118
+ const now = Date.now();
119
+ const validKeys = [];
120
+ for (const [key, entry] of this.cache.entries()) {
121
+ if (now <= entry.expiresAt) {
122
+ validKeys.push(key);
123
+ }
124
+ else {
125
+ this.cache.delete(key);
126
+ }
127
+ }
128
+ return validKeys;
129
+ }
130
+ /**
131
+ * Clean up expired entries
132
+ * @returns Number of entries removed
133
+ */
134
+ cleanup() {
135
+ const now = Date.now();
136
+ let removed = 0;
137
+ for (const [key, entry] of this.cache.entries()) {
138
+ if (now > entry.expiresAt) {
139
+ this.cache.delete(key);
140
+ removed++;
141
+ }
142
+ }
143
+ return removed;
144
+ }
145
+ /**
146
+ * Get cache size (number of entries)
147
+ */
148
+ size() {
149
+ return this.cache.size;
150
+ }
151
+ /**
152
+ * Get cache statistics
153
+ */
154
+ getStats() {
155
+ const total = this.hits + this.misses;
156
+ return {
157
+ size: this.cache.size,
158
+ hits: this.hits,
159
+ misses: this.misses,
160
+ hitRate: total > 0 ? this.hits / total : 0,
161
+ };
162
+ }
163
+ /**
164
+ * Reset statistics (keeps cache entries)
165
+ */
166
+ resetStats() {
167
+ this.hits = 0;
168
+ this.misses = 0;
169
+ }
170
+ }
171
+ /**
172
+ * Create a TTL cache instance (convenience function)
173
+ *
174
+ * @example
175
+ * ```typescript
176
+ * const cache = createCache<string>(5 * 60 * 1000);
177
+ * ```
178
+ */
179
+ export function createCache(ttl = 5 * 60 * 1000) {
180
+ return new TTLCache(ttl);
181
+ }
182
+ /**
183
+ * Global cache cleanup interval (runs every minute)
184
+ * This helps prevent memory leaks from expired cache entries
185
+ */
186
+ let cleanupInterval = null;
187
+ const activeCaches = new Set();
188
+ /**
189
+ * Register a cache for automatic cleanup
190
+ * @param cache Cache instance to register
191
+ */
192
+ export function registerCacheForCleanup(cache) {
193
+ activeCaches.add(cache);
194
+ // Start cleanup interval if not already running
195
+ if (!cleanupInterval) {
196
+ cleanupInterval = setInterval(() => {
197
+ for (const cache of activeCaches) {
198
+ cache.cleanup();
199
+ }
200
+ }, 60000); // Every minute
201
+ // Never block process/worker exit on a housekeeping timer.
202
+ cleanupInterval.unref?.();
203
+ }
204
+ }
205
+ /**
206
+ * Unregister a cache from automatic cleanup
207
+ * @param cache Cache instance to unregister
208
+ */
209
+ export function unregisterCacheFromCleanup(cache) {
210
+ activeCaches.delete(cache);
211
+ // Stop cleanup interval if no caches are registered
212
+ if (activeCaches.size === 0 && cleanupInterval) {
213
+ clearInterval(cleanupInterval);
214
+ cleanupInterval = null;
215
+ }
216
+ }
217
+ /**
218
+ * Stop all cleanup intervals (useful for testing)
219
+ * This will clear the interval and unregister all caches
220
+ */
221
+ export function stopAllCleanupIntervals() {
222
+ if (cleanupInterval) {
223
+ clearInterval(cleanupInterval);
224
+ cleanupInterval = null;
225
+ }
226
+ activeCaches.clear();
227
+ }
@@ -0,0 +1,80 @@
1
+ /**
2
+ * Cache-key primitives for the identity-scoped HTTP GET response cache.
3
+ *
4
+ * Extracted from {@link HttpService} so the identity-tag derivation is a pure,
5
+ * independently testable function with no dependency on instance/token state.
6
+ * The HTTP service injects the live access token; everything here is
7
+ * referentially transparent given that input.
8
+ */
9
+ import { jwtDecode } from 'jwt-decode';
10
+ /**
11
+ * Discriminator used when there is no access token at all. Anonymous responses
12
+ * must never collide with any authenticated identity.
13
+ */
14
+ export const ANON_IDENTITY = 'anon';
15
+ /**
16
+ * FNV-1a 32-bit non-cryptographic hash.
17
+ *
18
+ * Used by the cache-key generator for large payloads where full JSON inclusion
19
+ * would balloon the cache map keys, and as the fallback discriminator for an
20
+ * undecodable access token. Content-addressed: every byte of the input
21
+ * contributes to the digest, so two inputs with the same top-level shape but
22
+ * different field values produce different keys (the previous `keys + length`
23
+ * heuristic collided on these).
24
+ *
25
+ * Trade-offs:
26
+ * - 32 bits is ample for an in-process cache (collision risk negligible at our
27
+ * key counts; we also prefix with method + url which further partitions the
28
+ * keyspace).
29
+ * - Not cryptographically secure — never use for security decisions.
30
+ * - Zero dependencies, branch-free hot loop, ~1 GiB/s on V8.
31
+ */
32
+ export function fnv1a32(str) {
33
+ let h = 0x811c9dc5;
34
+ for (let i = 0; i < str.length; i++) {
35
+ h ^= str.charCodeAt(i);
36
+ // h * 16777619 mod 2^32, written as shift-and-add for portability and
37
+ // to avoid 53-bit JS number truncation in the intermediate multiply.
38
+ h = (h + ((h << 1) + (h << 4) + (h << 7) + (h << 8) + (h << 24))) >>> 0;
39
+ }
40
+ return h.toString(16).padStart(8, '0');
41
+ }
42
+ /**
43
+ * Derive a stable, non-sensitive identity discriminator for cache scoping.
44
+ *
45
+ * The GET-response cache MUST be partitioned by caller identity: endpoints with
46
+ * optional auth (e.g. `GET /profiles/recommendations`) return different content
47
+ * for an anonymous vs an authenticated caller, and per-user content for
48
+ * different authenticated users. Keying solely on `method:url:data` let an
49
+ * anonymous response be served to an authenticated caller — surfacing as
50
+ * "Who to follow" recommending accounts the user already follows after a
51
+ * cold-boot session restore.
52
+ *
53
+ * Resolution order:
54
+ * - no token → {@link ANON_IDENTITY} (`'anon'`).
55
+ * - decodable token → the token's `userId || id`.
56
+ * - undecodable token → a short FNV-1a hash of the token, prefixed `t` so it
57
+ * can never collide with `'anon'` or a real user id.
58
+ *
59
+ * We use the decoded user id rather than the raw JWT so the token never lands
60
+ * in a cache key (no token leakage through any cache-key logging, no key bloat).
61
+ * Switching into a managed account mints a REAL new session whose access token
62
+ * carries the target account's id, so the identity tag changes naturally on a
63
+ * switch — there is no separate acting-as discriminator to fold in.
64
+ *
65
+ * @param accessToken The current bearer access token, or `null` when anonymous.
66
+ */
67
+ export function computeIdentityTag(accessToken) {
68
+ if (!accessToken) {
69
+ return ANON_IDENTITY;
70
+ }
71
+ try {
72
+ const decoded = jwtDecode(accessToken);
73
+ return decoded.userId || decoded.id || `t${fnv1a32(accessToken)}`;
74
+ }
75
+ catch {
76
+ // Undecodable token — still partition it away from anon and from other
77
+ // tokens via a hash. Never silently fall back to ANON_IDENTITY.
78
+ return `t${fnv1a32(accessToken)}`;
79
+ }
80
+ }
@@ -0,0 +1,119 @@
1
+ /**
2
+ * coldBoot — a pure, ordered, short-circuit runner for "cold boot"
3
+ * authentication resolution.
4
+ *
5
+ * On a fresh page load / app launch the SDK may have several ways to recover an
6
+ * existing session (a persisted refresh-token family, a shared-keychain
7
+ * identity, a cross-domain boot-fragment return, ...). They must be attempted
8
+ * in a deterministic order, and the FIRST one that yields a session wins —
9
+ * every later step is skipped. This module encodes exactly that contract and
10
+ * nothing else.
11
+ *
12
+ * Design constraints (all enforced):
13
+ * - PURE: no DOM, no `navigator`, no `window`, no React, no platform globals.
14
+ * - NO module-level mutable state. Every call to {@link runColdBoot} is fully
15
+ * self-contained, so it is safe under bundler re-evaluation (e.g. the Metro
16
+ * web bundle — the reason any run-once guard for a step must live in the
17
+ * calling consumer, never in a core module-level singleton).
18
+ * - Architecture-agnostic: it knows nothing about HOW a step resolves a
19
+ * session; `runSessionColdBoot` (`boot/sessionColdBoot.ts`) is the current
20
+ * device-first consumer.
21
+ *
22
+ * A step is skipped (without running) when its `enabled` predicate returns
23
+ * false. Any thrown error — from either `enabled` or `run` — is reported via
24
+ * `onStepError` and treated as a non-fatal skip, so one broken recovery path
25
+ * can never prevent a later, healthy one from succeeding.
26
+ */
27
+ /**
28
+ * The unique sentinel a step's `run()` resolves to (via the internal race)
29
+ * when the overall cold-boot deadline expires before that step settled. It is
30
+ * NOT a {@link ColdBootStepResult} — the runner detects it by identity and
31
+ * treats it as "this step did not settle in time; move on".
32
+ *
33
+ * @internal
34
+ */
35
+ const DEADLINE_EXPIRED = Symbol('coldBoot.deadlineExpired');
36
+ /**
37
+ * Run the ordered cold-boot steps and resolve to the first recovered session,
38
+ * or `unauthenticated` if none recovers one.
39
+ *
40
+ * Semantics:
41
+ * 1. Iterate `steps` in order.
42
+ * 2. If a step has an `enabled` predicate, call it inside try/catch:
43
+ * - throw → report via `onStepError(id, err)` → treat as disabled → continue.
44
+ * - returns false → continue (skip, `run` not called).
45
+ * 3. Otherwise await `step.run()` inside try/catch:
46
+ * - throw → report via `onStepError(id, err)` → continue.
47
+ * - `{ kind: 'session' }` → return `{ kind: 'session', via: step.id, session }`.
48
+ * - `{ kind: 'skip' }` → continue.
49
+ * 4. After the loop with no winner → `{ kind: 'unauthenticated' }`.
50
+ */
51
+ export async function runColdBoot(options) {
52
+ const { steps, onStepError, overallDeadlineMs, onStepDeadline } = options;
53
+ // Arm the optional overall deadline. The budget is SHARED across the whole
54
+ // loop (not reset per step): a single timer resolves a reusable
55
+ // `DEADLINE_EXPIRED` sentinel that every per-step race can observe. Once it
56
+ // fires, later steps race against an already-resolved promise and so never
57
+ // block, yet the loop keeps iterating so the terminal step still fires.
58
+ const deadlineMs = typeof overallDeadlineMs === 'number' &&
59
+ Number.isFinite(overallDeadlineMs) &&
60
+ overallDeadlineMs > 0
61
+ ? overallDeadlineMs
62
+ : null;
63
+ let deadlineTimer;
64
+ let deadlinePromise;
65
+ if (deadlineMs !== null) {
66
+ deadlinePromise = new Promise((resolve) => {
67
+ deadlineTimer = setTimeout(() => resolve(DEADLINE_EXPIRED), deadlineMs);
68
+ });
69
+ }
70
+ try {
71
+ for (const step of steps) {
72
+ if (step.enabled) {
73
+ let isEnabled;
74
+ try {
75
+ isEnabled = step.enabled();
76
+ }
77
+ catch (error) {
78
+ onStepError?.(step.id, error);
79
+ continue;
80
+ }
81
+ if (!isEnabled)
82
+ continue;
83
+ }
84
+ let result;
85
+ try {
86
+ // Without a deadline, await the step directly. With a deadline, race
87
+ // the step against the shared deadline. The
88
+ // step's `run()` still STARTS synchronously up to its first `await`
89
+ // (so a terminal step's synchronous navigation side effect always
90
+ // executes), but a non-settling step can no longer block the loop —
91
+ // the race resolves with the sentinel and we move on.
92
+ result = deadlinePromise
93
+ ? await Promise.race([step.run(), deadlinePromise])
94
+ : await step.run();
95
+ }
96
+ catch (error) {
97
+ onStepError?.(step.id, error);
98
+ continue;
99
+ }
100
+ if (result === DEADLINE_EXPIRED) {
101
+ // The deadline tripped before this step settled. Abandon the await and
102
+ // continue: subsequent steps race against the already-resolved deadline
103
+ // (so they cannot block), which lets a terminal side-effect step still
104
+ // run while guaranteeing the loop terminates promptly.
105
+ onStepDeadline?.(step.id);
106
+ continue;
107
+ }
108
+ if (result.kind === 'session') {
109
+ return { kind: 'session', via: step.id, session: result.session };
110
+ }
111
+ }
112
+ return { kind: 'unauthenticated' };
113
+ }
114
+ finally {
115
+ if (deadlineTimer !== undefined) {
116
+ clearTimeout(deadlineTimer);
117
+ }
118
+ }
119
+ }
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Returns a user-facing blocking reason when an approval payload must not be
3
+ * shown as actionable, or `null` when the request is still pending and valid.
4
+ */
5
+ export function getCommonsApprovalBlockingReason(info) {
6
+ if (!info.application?.id) {
7
+ return 'The requesting application could not be resolved.';
8
+ }
9
+ if (info.status !== 'pending') {
10
+ return 'This sign-in request is invalid, already used, or expired.';
11
+ }
12
+ const expiresAtMs = parseCommonsApprovalExpiresAt(info.expiresAt);
13
+ if (expiresAtMs !== null && expiresAtMs < Date.now()) {
14
+ return 'This sign-in request has expired. Ask for a new QR code.';
15
+ }
16
+ return null;
17
+ }
18
+ /** Normalize API `expiresAt` (number or ISO string) to epoch ms. */
19
+ export function parseCommonsApprovalExpiresAt(expiresAt) {
20
+ if (typeof expiresAt === 'number' && Number.isFinite(expiresAt))
21
+ return expiresAt;
22
+ if (typeof expiresAt === 'string') {
23
+ const ms = Date.parse(expiresAt);
24
+ return Number.isFinite(ms) ? ms : null;
25
+ }
26
+ return null;
27
+ }
@@ -0,0 +1,54 @@
1
+ import { getPlatformOS } from './platform.js';
2
+ /**
3
+ * Choose the ONE primary delivery route for a "Sign in with Oxy" request.
4
+ *
5
+ * Decision order (issue #691, "Automatic delivery selection"):
6
+ *
7
+ * 1. Mobile with a verified Commons link available → open Commons directly.
8
+ * No push is needed when the identity is already reachable on this device.
9
+ * 2. At least one eligible Commons installation was pushed to → await the push.
10
+ * 3. Otherwise → QR.
11
+ *
12
+ * A caller that already knows it is on step 1 does not need to call
13
+ * `deliverCommonsSignIn` at all; every other caller runs the delivery
14
+ * round-trip first and passes its `targets` in here.
15
+ *
16
+ * `pushTargets` is server-derived, so it is validated rather than trusted: a
17
+ * negative, fractional, non-finite, or otherwise malformed count is treated as
18
+ * "no targets" and degrades to QR instead of parking the user on a "check your
19
+ * phone" screen that nothing will ever wake.
20
+ */
21
+ export function selectCommonsDelivery(facts) {
22
+ if (facts.platform === 'mobile' && facts.commonsAvailable) {
23
+ return 'open-commons';
24
+ }
25
+ if (Number.isInteger(facts.pushTargets) && facts.pushTargets >= 1) {
26
+ return 'await-push';
27
+ }
28
+ return 'qr';
29
+ }
30
+ /**
31
+ * Map a `deliverCommonsSignIn` result onto the `pushTargets` fact for
32
+ * {@link selectCommonsDelivery}. The server reports eligible install *count*
33
+ * separately from whether any push was accepted — a transport failure can leave
34
+ * `delivered: false` with `targets > 0`, which must NOT park the user on
35
+ * "check your phone".
36
+ */
37
+ export function pushTargetsFromDelivery(result) {
38
+ return result.delivered ? result.targets : 0;
39
+ }
40
+ /**
41
+ * Classify the current runtime surface for delivery selection. Callers that
42
+ * cannot confidently detect the platform should not use this — pass
43
+ * `'unknown'` explicitly instead.
44
+ */
45
+ export function commonsDeliveryPlatform() {
46
+ const os = getPlatformOS();
47
+ if (os === 'ios' || os === 'android') {
48
+ return 'mobile';
49
+ }
50
+ if (os === 'web') {
51
+ return 'desktop';
52
+ }
53
+ return 'unknown';
54
+ }
@@ -0,0 +1,170 @@
1
+ import { loadAsyncStorage } from '@oxy.so/protocol';
2
+ import { createLogger } from '../logger/index.js';
3
+ const log = createLogger('DeviceManager');
4
+ /**
5
+ * Client-side device management utility
6
+ * Handles persistent device identification across app sessions
7
+ */
8
+ export class DeviceManager {
9
+ /**
10
+ * Check if we're in React Native environment
11
+ */
12
+ static isReactNative() {
13
+ return typeof navigator !== 'undefined' && navigator.product === 'ReactNative';
14
+ }
15
+ /**
16
+ * Get appropriate storage for the platform
17
+ */
18
+ static async getStorage() {
19
+ if (this.isReactNative()) {
20
+ try {
21
+ // `loadAsyncStorage` is per-platform: the RN variant statically imports
22
+ // @react-native-async-storage/async-storage, the default variant throws
23
+ // (never called outside RN because of the `isReactNative()` gate above).
24
+ const asyncStorageModule = await loadAsyncStorage();
25
+ const storage = asyncStorageModule.default;
26
+ return {
27
+ getItem: storage.getItem.bind(storage),
28
+ setItem: storage.setItem.bind(storage),
29
+ removeItem: storage.removeItem.bind(storage),
30
+ };
31
+ }
32
+ catch (error) {
33
+ log.error('AsyncStorage not available in React Native', error);
34
+ throw new Error('AsyncStorage is required in React Native environment');
35
+ }
36
+ }
37
+ else {
38
+ // Use localStorage for web
39
+ return {
40
+ getItem: async (key) => localStorage.getItem(key),
41
+ setItem: async (key, value) => localStorage.setItem(key, value),
42
+ removeItem: async (key) => localStorage.removeItem(key)
43
+ };
44
+ }
45
+ }
46
+ /**
47
+ * Get or create device fingerprint for current device
48
+ */
49
+ static getDeviceFingerprint() {
50
+ const fingerprint = {
51
+ userAgent: typeof navigator !== 'undefined' ? navigator.userAgent : 'unknown',
52
+ platform: typeof navigator !== 'undefined' ? navigator.platform : 'unknown',
53
+ language: typeof navigator !== 'undefined' ? navigator.language : undefined,
54
+ timezone: typeof Intl !== 'undefined' ? Intl.DateTimeFormat().resolvedOptions().timeZone : undefined,
55
+ };
56
+ // Add screen info if available
57
+ if (typeof screen !== 'undefined') {
58
+ fingerprint.screen = {
59
+ width: screen.width,
60
+ height: screen.height,
61
+ colorDepth: screen.colorDepth
62
+ };
63
+ }
64
+ return fingerprint;
65
+ }
66
+ /**
67
+ * Get stored device info or create new one
68
+ */
69
+ static async getDeviceInfo() {
70
+ try {
71
+ const storage = await this.getStorage();
72
+ const stored = await storage.getItem(this.DEVICE_KEY);
73
+ if (stored) {
74
+ const deviceInfo = JSON.parse(stored);
75
+ // Update last used timestamp
76
+ deviceInfo.lastUsed = new Date().toISOString();
77
+ await this.saveDeviceInfo(deviceInfo);
78
+ return deviceInfo;
79
+ }
80
+ // Create new device info
81
+ return await this.createNewDeviceInfo();
82
+ }
83
+ catch (error) {
84
+ log.error('Error getting device info', error);
85
+ return await this.createNewDeviceInfo();
86
+ }
87
+ }
88
+ /**
89
+ * Create new device info and store it
90
+ */
91
+ static async createNewDeviceInfo() {
92
+ const deviceInfo = {
93
+ deviceId: this.generateDeviceId(),
94
+ fingerprint: JSON.stringify(this.getDeviceFingerprint()),
95
+ createdAt: new Date().toISOString(),
96
+ lastUsed: new Date().toISOString()
97
+ };
98
+ await this.saveDeviceInfo(deviceInfo);
99
+ return deviceInfo;
100
+ }
101
+ /**
102
+ * Save device info to storage
103
+ */
104
+ static async saveDeviceInfo(deviceInfo) {
105
+ try {
106
+ const storage = await this.getStorage();
107
+ await storage.setItem(this.DEVICE_KEY, JSON.stringify(deviceInfo));
108
+ }
109
+ catch (error) {
110
+ log.error('Error saving device info', error);
111
+ }
112
+ }
113
+ /**
114
+ * Update device name
115
+ */
116
+ static async updateDeviceName(deviceName) {
117
+ try {
118
+ const deviceInfo = await this.getDeviceInfo();
119
+ deviceInfo.deviceName = deviceName;
120
+ await this.saveDeviceInfo(deviceInfo);
121
+ }
122
+ catch (error) {
123
+ log.error('Error updating device name', error);
124
+ }
125
+ }
126
+ /**
127
+ * Clear stored device info (useful for testing or reset)
128
+ */
129
+ static async clearDeviceInfo() {
130
+ try {
131
+ const storage = await this.getStorage();
132
+ await storage.removeItem(this.DEVICE_KEY);
133
+ }
134
+ catch (error) {
135
+ log.error('Error clearing device info', error);
136
+ }
137
+ }
138
+ /**
139
+ * Generate a unique device ID
140
+ */
141
+ static generateDeviceId() {
142
+ if (typeof crypto !== 'undefined' && crypto.getRandomValues) {
143
+ const array = new Uint8Array(32);
144
+ crypto.getRandomValues(array);
145
+ return Array.from(array, byte => byte.toString(16).padStart(2, '0')).join('');
146
+ }
147
+ throw new Error('No secure random source available for device ID generation');
148
+ }
149
+ /**
150
+ * Get a user-friendly device name based on platform
151
+ */
152
+ static getDefaultDeviceName() {
153
+ const fingerprint = this.getDeviceFingerprint();
154
+ const platform = (fingerprint.platform || '').toLowerCase();
155
+ if (platform.includes('win'))
156
+ return 'Windows Computer';
157
+ if (platform.includes('mac'))
158
+ return 'Mac Computer';
159
+ if (platform.includes('linux'))
160
+ return 'Linux Computer';
161
+ if (platform.includes('iphone'))
162
+ return 'iPhone';
163
+ if (platform.includes('ipad'))
164
+ return 'iPad';
165
+ if (platform.includes('android'))
166
+ return 'Android Device';
167
+ return 'Unknown Device';
168
+ }
169
+ }
170
+ DeviceManager.DEVICE_KEY = 'oxy_device_info';