@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,350 @@
1
+ /**
2
+ * Signature Service - ECDSA Digital Signatures (device-key bound)
3
+ *
4
+ * Handles signing and verification of messages with the user's DEVICE identity
5
+ * key (read from {@link KeyManager} / secure storage). All cryptography itself —
6
+ * canonical signing input, SHA-256, secp256k1 sign/verify, envelope assembly —
7
+ * is delegated to `@oxy.so/protocol`; this service only resolves the key from
8
+ * storage and orchestrates the protocol primitives.
9
+ */
10
+
11
+ import type { SignedRecordEnvelope } from '@oxy.so/contracts';
12
+ import {
13
+ signEnvelope,
14
+ signMessage,
15
+ verifySignature,
16
+ sha256,
17
+ loadExpoCrypto,
18
+ loadNodeCrypto,
19
+ isReactNative,
20
+ isNodeJS,
21
+ } from '@oxy.so/protocol';
22
+ import { KeyManager } from './keyManager';
23
+ import { logger } from '../logger';
24
+
25
+ export interface SignedMessage {
26
+ message: string;
27
+ signature: string;
28
+ publicKey: string;
29
+ timestamp: number;
30
+ }
31
+
32
+ export interface AuthChallenge {
33
+ challenge: string;
34
+ publicKey: string;
35
+ timestamp: number;
36
+ }
37
+
38
+ export class SignatureService {
39
+ /**
40
+ * Generate a random challenge string (for offline use)
41
+ * Uses expo-crypto in React Native, crypto.randomBytes in Node.js
42
+ */
43
+ static async generateChallenge(): Promise<string> {
44
+ // In React Native, use expo-crypto
45
+ if (isReactNative()) {
46
+ const Crypto = await loadExpoCrypto();
47
+ const randomBytes = await Crypto.getRandomBytesAsync(32);
48
+ return Array.from(new Uint8Array(randomBytes))
49
+ .map((b) => b.toString(16).padStart(2, '0'))
50
+ .join('');
51
+ }
52
+
53
+ if (isNodeJS()) {
54
+ try {
55
+ const nodeCrypto = await loadNodeCrypto();
56
+ return nodeCrypto.randomBytes(32).toString('hex');
57
+ } catch (error) {
58
+ // Node crypto failed to load — log and fall through to Web Crypto API
59
+ logger.warn('[oxy.crypto] Node crypto unavailable, falling back to Web Crypto', { component: 'SignatureService' }, error);
60
+ }
61
+ }
62
+
63
+ // Browser: use Web Crypto API
64
+ const bytes = new Uint8Array(32);
65
+ globalThis.crypto.getRandomValues(bytes);
66
+ return Array.from(bytes)
67
+ .map(b => b.toString(16).padStart(2, '0'))
68
+ .join('');
69
+ }
70
+
71
+ /**
72
+ * Hash a message using SHA-256
73
+ */
74
+ static async hashMessage(message: string): Promise<string> {
75
+ return sha256(message);
76
+ }
77
+
78
+ /**
79
+ * Sign a message using the stored device private key
80
+ * Returns the signature in DER format (hex encoded)
81
+ */
82
+ static async sign(message: string): Promise<string> {
83
+ const privateKey = await KeyManager.getPrivateKey();
84
+ if (!privateKey) {
85
+ throw new Error('No identity found. Please create or import an identity first.');
86
+ }
87
+ return signMessage(message, privateKey);
88
+ }
89
+
90
+ /**
91
+ * Create a signed message object with metadata
92
+ */
93
+ static async createSignedMessage(message: string): Promise<SignedMessage> {
94
+ const publicKey = await KeyManager.getPublicKey();
95
+ if (!publicKey) {
96
+ throw new Error('No identity found. Please create or import an identity first.');
97
+ }
98
+
99
+ const timestamp = Date.now();
100
+ const messageWithTimestamp = `${message}:${timestamp}`;
101
+ const signature = await SignatureService.sign(messageWithTimestamp);
102
+
103
+ return {
104
+ message,
105
+ signature,
106
+ publicKey,
107
+ timestamp,
108
+ };
109
+ }
110
+
111
+ /**
112
+ * Verify a signed message object
113
+ * Checks both signature validity and timestamp freshness
114
+ */
115
+ static async verifySignedMessage(
116
+ signedMessage: SignedMessage,
117
+ maxAgeMs: number = 5 * 60 * 1000 // 5 minutes default
118
+ ): Promise<boolean> {
119
+ const { message, signature, publicKey, timestamp } = signedMessage;
120
+
121
+ // Check timestamp freshness
122
+ const now = Date.now();
123
+ if (now - timestamp > maxAgeMs) {
124
+ return false;
125
+ }
126
+
127
+ // Verify signature
128
+ const messageWithTimestamp = `${message}:${timestamp}`;
129
+ return verifySignature(messageWithTimestamp, signature, publicKey);
130
+ }
131
+
132
+ /**
133
+ * Create a signed authentication challenge response
134
+ * Used for challenge-response authentication
135
+ */
136
+ static async signChallenge(challenge: string): Promise<AuthChallenge> {
137
+ const publicKey = await KeyManager.getPublicKey();
138
+ if (!publicKey) {
139
+ throw new Error('No identity found. Please create or import an identity first.');
140
+ }
141
+
142
+ const timestamp = Date.now();
143
+ const message = `auth:${publicKey}:${challenge}:${timestamp}`;
144
+ const signature = await SignatureService.sign(message);
145
+
146
+ return {
147
+ challenge: signature,
148
+ publicKey,
149
+ timestamp,
150
+ };
151
+ }
152
+
153
+ /**
154
+ * Create a signed authentication challenge response using the SHARED identity
155
+ * key (the cross-app `group.so.oxy.shared` keychain key), not the primary
156
+ * device key.
157
+ *
158
+ * Mirrors {@link signChallenge} exactly — same message format
159
+ * (`auth:${publicKey}:${challenge}:${timestamp}`) so the server verification
160
+ * path is unchanged — but sources the shared public/private key from
161
+ * `KeyManager` and signs with the protocol's explicit-key {@link signMessage}.
162
+ * Used by "Sign in with Oxy" same-device shared-keychain SSO (Mechanism A): a
163
+ * sibling native app proves control of the shared identity to mint its own
164
+ * session.
165
+ *
166
+ * Throws if no shared identity exists (native-only; the shared keychain is
167
+ * unavailable on web).
168
+ */
169
+ static async signChallengeWithSharedKey(challenge: string): Promise<AuthChallenge> {
170
+ const publicKey = await KeyManager.getSharedPublicKey();
171
+ const privateKey = await KeyManager.getSharedPrivateKey();
172
+ if (!publicKey || !privateKey) {
173
+ throw new Error('No shared identity found. Cannot sign with the shared key.');
174
+ }
175
+
176
+ const timestamp = Date.now();
177
+ const message = `auth:${publicKey}:${challenge}:${timestamp}`;
178
+ const signature = await signMessage(message, privateKey);
179
+
180
+ return {
181
+ challenge: signature,
182
+ publicKey,
183
+ timestamp,
184
+ };
185
+ }
186
+
187
+ /**
188
+ * Verify a challenge response
189
+ */
190
+ static async verifyChallengeResponse(
191
+ originalChallenge: string,
192
+ response: AuthChallenge,
193
+ maxAgeMs: number = 5 * 60 * 1000
194
+ ): Promise<boolean> {
195
+ const { challenge: signature, publicKey, timestamp } = response;
196
+
197
+ // Check timestamp freshness
198
+ const now = Date.now();
199
+ if (now - timestamp > maxAgeMs) {
200
+ return false;
201
+ }
202
+
203
+ const message = `auth:${publicKey}:${originalChallenge}:${timestamp}`;
204
+ return verifySignature(message, signature, publicKey);
205
+ }
206
+
207
+ /**
208
+ * Create a registration signature
209
+ * Used when registering a new identity with the server
210
+ * Format matches server expectation: oxy:register:{publicKey}:{timestamp}
211
+ */
212
+ static async createRegistrationSignature(): Promise<{ signature: string; publicKey: string; timestamp: number }> {
213
+ const publicKey = await KeyManager.getPublicKey();
214
+ if (!publicKey) {
215
+ throw new Error('No identity found. Please create or import an identity first.');
216
+ }
217
+
218
+ const timestamp = Date.now();
219
+ const message = `oxy:register:${publicKey}:${timestamp}`;
220
+ const signature = await SignatureService.sign(message);
221
+
222
+ return {
223
+ signature,
224
+ publicKey,
225
+ timestamp,
226
+ };
227
+ }
228
+
229
+ /**
230
+ * Sign arbitrary data for API requests
231
+ * Creates a canonical string representation and signs it
232
+ */
233
+ static async signRequestData(data: Record<string, unknown>): Promise<{
234
+ signature: string;
235
+ publicKey: string;
236
+ timestamp: number;
237
+ }> {
238
+ const publicKey = await KeyManager.getPublicKey();
239
+ if (!publicKey) {
240
+ throw new Error('No identity found. Please create or import an identity first.');
241
+ }
242
+
243
+ const timestamp = Date.now();
244
+
245
+ // Create canonical string representation
246
+ const sortedKeys = Object.keys(data).sort();
247
+ const canonicalParts = sortedKeys.map(key => `${key}:${JSON.stringify(data[key])}`);
248
+ const canonicalString = canonicalParts.join('|');
249
+
250
+ const message = `request:${publicKey}:${timestamp}:${canonicalString}`;
251
+ const signature = await SignatureService.sign(message);
252
+
253
+ return {
254
+ signature,
255
+ publicKey,
256
+ timestamp,
257
+ };
258
+ }
259
+
260
+ /**
261
+ * Build a signed-record envelope for a self-issued identity/profile record.
262
+ *
263
+ * The envelope is self-issued: `issuer` equals `subject` (the signer's DID).
264
+ * The signature covers the canonical JSON of every field EXCEPT `publicKey`
265
+ * and `signature`; `alg` is `ES256K-DER-SHA256` (secp256k1 over the SHA-256 of
266
+ * the canonical bytes, DER-encoded). The cryptography is delegated to the
267
+ * protocol's {@link signEnvelope}, which derives the (uncompressed-hex)
268
+ * `publicKey` from the stored device key — identical to the registered
269
+ * verification method.
270
+ *
271
+ * Requires a stored identity (native secure storage); throws if none exists.
272
+ *
273
+ * @param type - The record category (`'identity'` or `'profile'`).
274
+ * @param subject - The subject DID the record is about (also the issuer).
275
+ * @param record - The arbitrary record payload to attest to.
276
+ */
277
+ static async signRecord(
278
+ type: SignedRecordEnvelope['type'],
279
+ subject: string,
280
+ record: Record<string, unknown>,
281
+ ): Promise<SignedRecordEnvelope> {
282
+ const privateKey = await KeyManager.getPrivateKey();
283
+ if (!privateKey) {
284
+ throw new Error('No identity found. Please create or import an identity first.');
285
+ }
286
+
287
+ return signEnvelope(
288
+ {
289
+ version: 1,
290
+ type,
291
+ subject,
292
+ issuer: subject,
293
+ record,
294
+ issuedAt: Date.now(),
295
+ },
296
+ privateKey,
297
+ );
298
+ }
299
+
300
+ /**
301
+ * Build a signed-record envelope (v2) carrying the per-subject hash-chain
302
+ * fields.
303
+ *
304
+ * Identical to {@link signRecord} (self-issued: `issuer === subject`; same
305
+ * `ES256K-DER-SHA256` scheme) but `version` is `2` and the signed bytes
306
+ * additionally cover the chain fields:
307
+ *
308
+ * @param type - The record category.
309
+ * @param subject - The subject DID the record is about (also the issuer).
310
+ * @param record - The arbitrary record payload to attest to.
311
+ * @param chain - The hash-chain coordinates:
312
+ * - `seq` — strictly-increasing sequence number for this subject's chain.
313
+ * - `prev` — the `recordId` of the previous record, or `null` at genesis.
314
+ * - `collection` + `rkey` — the AtProto-style record key.
315
+ *
316
+ * The caller is responsible for fetching the current chain head (so `seq` /
317
+ * `prev` are correct) before signing. Requires a stored identity; throws if
318
+ * none exists.
319
+ */
320
+ static async signRecordV2(
321
+ type: SignedRecordEnvelope['type'],
322
+ subject: string,
323
+ record: Record<string, unknown>,
324
+ chain: { seq: number; prev: string | null; collection: string; rkey: string },
325
+ ): Promise<SignedRecordEnvelope> {
326
+ const privateKey = await KeyManager.getPrivateKey();
327
+ if (!privateKey) {
328
+ throw new Error('No identity found. Please create or import an identity first.');
329
+ }
330
+
331
+ const { seq, prev, collection, rkey } = chain;
332
+ return signEnvelope(
333
+ {
334
+ version: 2,
335
+ type,
336
+ subject,
337
+ issuer: subject,
338
+ record,
339
+ issuedAt: Date.now(),
340
+ seq,
341
+ prev,
342
+ collection,
343
+ rkey,
344
+ },
345
+ privateKey,
346
+ );
347
+ }
348
+ }
349
+
350
+ export default SignatureService;
@@ -0,0 +1,62 @@
1
+ import { ACCOUNT_CATEGORY_IDS, SELECTABLE_ACCOUNT_CATEGORY_IDS } from '@oxy.so/contracts';
2
+ import { accountCategoryLabel, EN_ACCOUNT_CATEGORY_LABELS } from '../accountCategoryLabels';
3
+
4
+ /**
5
+ * Every locale the SDK ships a dictionary for, plus a region variant and an
6
+ * untranslated language, because the three take different paths through
7
+ * `translate`: exact dictionary, base-subtag dictionary, and English fallback.
8
+ */
9
+ const SHIPPED_LOCALES = [
10
+ 'en-US',
11
+ 'es-ES',
12
+ 'ca-ES',
13
+ 'fr-FR',
14
+ 'de-DE',
15
+ 'it-IT',
16
+ 'pt-PT',
17
+ 'ja-JP',
18
+ 'ko-KR',
19
+ 'zh-CN',
20
+ 'ar-SA',
21
+ ] as const;
22
+ const REGION_VARIANT = 'es-MX';
23
+ const UNSHIPPED_LOCALE = 'nl-NL';
24
+
25
+ describe('accountCategoryLabel', () => {
26
+ // Vacuity floor: a traversal bug that yielded an empty id list would make
27
+ // every assertion below pass over nothing.
28
+ it('covers the whole vocabulary', () => {
29
+ expect(ACCOUNT_CATEGORY_IDS.length).toBeGreaterThanOrEqual(46);
30
+ expect(Object.keys(EN_ACCOUNT_CATEGORY_LABELS)).toHaveLength(ACCOUNT_CATEGORY_IDS.length);
31
+ });
32
+
33
+ it.each([...SHIPPED_LOCALES, REGION_VARIANT, UNSHIPPED_LOCALE])(
34
+ 'names every category in %s — never a key, never a slug, never empty',
35
+ (locale) => {
36
+ for (const id of ACCOUNT_CATEGORY_IDS) {
37
+ const label = accountCategoryLabel(locale, id);
38
+ expect(label).not.toBe('');
39
+ // `translate` echoes the key when it resolves nothing, so the key IS the
40
+ // failure signal. This is what the screen's old `t(key) || id` believed
41
+ // it was catching and could not, since a non-empty string is truthy.
42
+ expect(label).not.toBe(`accounts.accountCategory.${id}`);
43
+ // The raw slug reaching a reader is the bug this whole indirection
44
+ // exists to prevent. `ai` is excluded: its English label legitimately
45
+ // equals its id.
46
+ }
47
+ },
48
+ );
49
+
50
+ it('falls back to English for a language with no category translations', () => {
51
+ // German ships a dictionary but no category labels, so it exercises
52
+ // `translate`'s PER-KEY English fallback rather than its locale fallback.
53
+ expect(accountCategoryLabel('de-DE', 'cooperative')).toBe(
54
+ EN_ACCOUNT_CATEGORY_LABELS.cooperative,
55
+ );
56
+ });
57
+
58
+ it('resolves a region variant through its base language', () => {
59
+ expect(accountCategoryLabel('es-MX', 'news')).toBe(accountCategoryLabel('es-ES', 'news'));
60
+ expect(accountCategoryLabel('es-MX', 'news')).not.toBe(EN_ACCOUNT_CATEGORY_LABELS.news);
61
+ });
62
+ });
@@ -0,0 +1,54 @@
1
+ import type { AccountRole } from '../../mixins/OxyServices.accounts';
2
+ import { EN_ACCOUNT_ROLE_LABELS, accountRoleLabel } from '../accountRoleLabels';
3
+
4
+ const ACCOUNT_ROLES: AccountRole[] = [
5
+ 'owner',
6
+ 'admin',
7
+ 'editor',
8
+ 'developer',
9
+ 'billing',
10
+ 'viewer',
11
+ ];
12
+
13
+ const SHIPPED_LOCALES = [
14
+ 'en-US',
15
+ 'es-ES',
16
+ 'ca-ES',
17
+ 'fr-FR',
18
+ 'de-DE',
19
+ 'it-IT',
20
+ 'pt-PT',
21
+ 'ja-JP',
22
+ 'ko-KR',
23
+ 'zh-CN',
24
+ 'ar-SA',
25
+ ] as const;
26
+ const REGION_VARIANT = 'es-MX';
27
+ const UNSHIPPED_LOCALE = 'nl-NL';
28
+
29
+ describe('accountRoleLabel', () => {
30
+ it('covers the whole vocabulary', () => {
31
+ expect(ACCOUNT_ROLES.length).toBe(6);
32
+ expect(Object.keys(EN_ACCOUNT_ROLE_LABELS)).toHaveLength(ACCOUNT_ROLES.length);
33
+ });
34
+
35
+ it.each([...SHIPPED_LOCALES, REGION_VARIANT, UNSHIPPED_LOCALE])(
36
+ 'names every role in %s — never a key, never a slug, never empty',
37
+ (locale) => {
38
+ for (const role of ACCOUNT_ROLES) {
39
+ const label = accountRoleLabel(locale, role);
40
+ expect(label).not.toBe('');
41
+ expect(label).not.toBe(`accounts.roles.${role}.label`);
42
+ }
43
+ },
44
+ );
45
+
46
+ it('falls back to English for a language with no role translations', () => {
47
+ expect(accountRoleLabel('de-DE', 'developer')).toBe(EN_ACCOUNT_ROLE_LABELS.developer);
48
+ });
49
+
50
+ it('resolves a region variant through its base language', () => {
51
+ expect(accountRoleLabel('es-MX', 'admin')).toBe(accountRoleLabel('es-ES', 'admin'));
52
+ expect(accountRoleLabel('es-MX', 'admin')).not.toBe(EN_ACCOUNT_ROLE_LABELS.admin);
53
+ });
54
+ });
@@ -0,0 +1,56 @@
1
+ import { REPUTATION_CATEGORIES } from '@oxy.so/contracts';
2
+ import {
3
+ EN_REPUTATION_CATEGORY_LABELS,
4
+ reputationCategoryLabel,
5
+ } from '../reputationCategoryLabels';
6
+
7
+ const SHIPPED_LOCALES = [
8
+ 'en-US',
9
+ 'es-ES',
10
+ 'ca-ES',
11
+ 'fr-FR',
12
+ 'de-DE',
13
+ 'it-IT',
14
+ 'pt-PT',
15
+ 'ja-JP',
16
+ 'ko-KR',
17
+ 'zh-CN',
18
+ 'ar-SA',
19
+ ] as const;
20
+ const REGION_VARIANT = 'es-MX';
21
+ const UNSHIPPED_LOCALE = 'nl-NL';
22
+
23
+ describe('reputationCategoryLabel', () => {
24
+ it('covers the whole vocabulary', () => {
25
+ expect(REPUTATION_CATEGORIES.length).toBeGreaterThanOrEqual(7);
26
+ expect(Object.keys(EN_REPUTATION_CATEGORY_LABELS)).toHaveLength(
27
+ REPUTATION_CATEGORIES.length,
28
+ );
29
+ });
30
+
31
+ it.each([...SHIPPED_LOCALES, REGION_VARIANT, UNSHIPPED_LOCALE])(
32
+ 'names every category in %s — never a key, never a slug, never empty',
33
+ (locale) => {
34
+ for (const id of REPUTATION_CATEGORIES) {
35
+ const label = reputationCategoryLabel(locale, id);
36
+ expect(label).not.toBe('');
37
+ expect(label).not.toBe(`trust.rules.categories.${id}`);
38
+ }
39
+ },
40
+ );
41
+
42
+ it('falls back to English for a language with no category translations', () => {
43
+ expect(reputationCategoryLabel('de-DE', 'physical')).toBe(
44
+ EN_REPUTATION_CATEGORY_LABELS.physical,
45
+ );
46
+ });
47
+
48
+ it('resolves a region variant through its base language', () => {
49
+ expect(reputationCategoryLabel('es-MX', 'content')).toBe(
50
+ reputationCategoryLabel('es-ES', 'content'),
51
+ );
52
+ expect(reputationCategoryLabel('es-MX', 'content')).not.toBe(
53
+ EN_REPUTATION_CATEGORY_LABELS.content,
54
+ );
55
+ });
56
+ });
@@ -0,0 +1,47 @@
1
+ import { TRUST_TIERS } from '@oxy.so/contracts';
2
+ import { EN_TRUST_TIER_LABELS, trustTierLabel } from '../trustTierLabels';
3
+
4
+ const SHIPPED_LOCALES = [
5
+ 'en-US',
6
+ 'es-ES',
7
+ 'ca-ES',
8
+ 'fr-FR',
9
+ 'de-DE',
10
+ 'it-IT',
11
+ 'pt-PT',
12
+ 'ja-JP',
13
+ 'ko-KR',
14
+ 'zh-CN',
15
+ 'ar-SA',
16
+ ] as const;
17
+ const REGION_VARIANT = 'es-MX';
18
+ const UNSHIPPED_LOCALE = 'nl-NL';
19
+
20
+ describe('trustTierLabel', () => {
21
+ it('covers the whole vocabulary', () => {
22
+ expect(TRUST_TIERS.length).toBe(5);
23
+ expect(Object.keys(EN_TRUST_TIER_LABELS)).toHaveLength(TRUST_TIERS.length);
24
+ });
25
+
26
+ it.each([...SHIPPED_LOCALES, REGION_VARIANT, UNSHIPPED_LOCALE])(
27
+ 'names every tier in %s — never a key, never a slug, never empty',
28
+ (locale) => {
29
+ for (const tier of TRUST_TIERS) {
30
+ const label = trustTierLabel(locale, tier);
31
+ expect(label).not.toBe('');
32
+ expect(label).not.toBe(`trust.tiers.${tier}`);
33
+ }
34
+ },
35
+ );
36
+
37
+ it('falls back to English for a language with no tier translations', () => {
38
+ expect(trustTierLabel('de-DE', 'high_trust')).toBe(
39
+ EN_TRUST_TIER_LABELS.high_trust,
40
+ );
41
+ });
42
+
43
+ it('resolves a region variant through its base language', () => {
44
+ expect(trustTierLabel('es-MX', 'verified')).toBe(trustTierLabel('es-ES', 'verified'));
45
+ expect(trustTierLabel('es-MX', 'verified')).not.toBe(EN_TRUST_TIER_LABELS.verified);
46
+ });
47
+ });
@@ -0,0 +1,44 @@
1
+ import type { AccountCategoryId } from '@oxy.so/contracts';
2
+ import enUS from './locales/en-US.json';
3
+ import { translate } from './index';
4
+
5
+ /**
6
+ * Every account category's English name, keyed by its stable id.
7
+ *
8
+ * **The annotation is the point.** The vocabulary lives in `@oxy.so/contracts`
9
+ * and the names live in `locales/en-US.json`, so they are two lists that must
10
+ * agree and nothing but a type can make them. Declaring the JSON node as a
11
+ * TOTAL `Record<AccountCategoryId, string>` turns "somebody added a category at
12
+ * Oxy and nobody wrote its English" into a `TS2741` naming the missing id, at
13
+ * build time, instead of a picker row that paints `accounts.accountCategory.<id>`
14
+ * at a user trying to choose one.
15
+ *
16
+ * That failure is not hypothetical. The screen previously wrote `t(key) || id`,
17
+ * whose author believed an unnamed id would degrade to its raw slug. It cannot:
18
+ * {@link translate} echoes the KEY when it resolves nothing, and a non-empty
19
+ * string is never falsy, so the `|| id` arm was unreachable and the output was
20
+ * the dotted key. A runtime fallback that cannot run is worse than none,
21
+ * because it reads as protection.
22
+ *
23
+ * Totality is over `ACCOUNT_CATEGORY_IDS`, which RETAINS withdrawn ids, so an
24
+ * account still carrying a retired category keeps rendering its name while no
25
+ * picker offers it again. Retired and unknown are different cases: only an id
26
+ * outside the union is unnameable, which is why this is keyed by
27
+ * `AccountCategoryId` and not by `string`.
28
+ */
29
+ /**
30
+ * Module-scoped, NOT re-exported from the package index: the annotation is the
31
+ * whole job, and it does that job without being public API. It carries no
32
+ * `Object.freeze` and no `Readonly<>` for the same reason — those existed only
33
+ * to make an exported reference safe from a consumer's stray write, and there
34
+ * is no such consumer. Exported from the MODULE so its own test can name it.
35
+ */
36
+ export const EN_ACCOUNT_CATEGORY_LABELS: Record<AccountCategoryId, string> =
37
+ enUS.accounts.accountCategory;
38
+
39
+ export function accountCategoryLabel(
40
+ locale: string | undefined,
41
+ id: AccountCategoryId,
42
+ ): string {
43
+ return translate(locale, `accounts.accountCategory.${id}`);
44
+ }
@@ -0,0 +1,26 @@
1
+ import type { AccountRole } from '../mixins/OxyServices.accounts';
2
+ import enUS from './locales/en-US.json';
3
+ import { translate } from './index';
4
+
5
+ /**
6
+ * Every account member role's English name, keyed by its stable id.
7
+ *
8
+ * Totality is over the closed `AccountRole` union so a new role without an
9
+ * English label is a build error, not a members row that paints
10
+ * `accounts.roles.<role>.label`.
11
+ */
12
+ export const EN_ACCOUNT_ROLE_LABELS: Record<AccountRole, string> = {
13
+ owner: enUS.accounts.roles.owner.label,
14
+ admin: enUS.accounts.roles.admin.label,
15
+ editor: enUS.accounts.roles.editor.label,
16
+ developer: enUS.accounts.roles.developer.label,
17
+ billing: enUS.accounts.roles.billing.label,
18
+ viewer: enUS.accounts.roles.viewer.label,
19
+ };
20
+
21
+ export function accountRoleLabel(
22
+ locale: string | undefined,
23
+ role: AccountRole,
24
+ ): string {
25
+ return translate(locale, `accounts.roles.${role}.label`);
26
+ }