@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,225 @@
1
+ "use strict";
2
+ /**
3
+ * Strict CORS allowlist for Oxy backends.
4
+ *
5
+ * WHY THIS EXISTS
6
+ * ---------------
7
+ * App backends kept hand-rolling CORS, and the unsafe patterns recurred:
8
+ * - `Access-Control-Allow-Origin: *` together with credentials (which is
9
+ * spec-invalid AND a credential-leak vector), or
10
+ * - a "reflect whatever Origin the request carried" fallback (effectively
11
+ * `*` for credentialed requests — the Allo wildcard-fallback class).
12
+ *
13
+ * `createOxyCors` returns a self-contained Express middleware (no `cors`
14
+ * package dependency) that:
15
+ * - allows the Oxy apex origin family over HTTPS only: the apex plus
16
+ * one-label subdomains such as `auth.oxy.so`, `api.oxy.so`,
17
+ * `accounts.oxy.so`, `console.oxy.so`, and `inbox.oxy.so`,
18
+ * - allows the caller's explicit `appOrigins`,
19
+ * - REFUSES the opaque origin on both sides (see `OPAQUE_ORIGIN`),
20
+ * - DENIES everything else (no reflection, never a wildcard with credentials),
21
+ * - echoes back the EXACT matched origin (so credentialed requests work) and
22
+ * sets `Vary: Origin` for correct caching,
23
+ * - answers CORS preflight (`OPTIONS`) with `204`.
24
+ *
25
+ * Node/Express-only: exported solely from `@oxy.so/core/server`.
26
+ */
27
+ Object.defineProperty(exports, "__esModule", { value: true });
28
+ exports.normalizeAppOrigins = normalizeAppOrigins;
29
+ exports.matchesAllowedOrigin = matchesAllowedOrigin;
30
+ exports.createOxyCors = createOxyCors;
31
+ const logger_1 = require("../logger");
32
+ const authWebUrl_1 = require("../utils/authWebUrl");
33
+ const log = (0, logger_1.createLogger)('OxyCors');
34
+ /** Default HTTP methods allowed across origins. */
35
+ const DEFAULT_ALLOWED_METHODS = ['GET', 'HEAD', 'PUT', 'PATCH', 'POST', 'DELETE', 'OPTIONS'];
36
+ /** Default request headers a browser may send on a credentialed cross-origin call. */
37
+ const DEFAULT_ALLOWED_HEADERS = [
38
+ 'Content-Type',
39
+ 'Authorization',
40
+ 'X-Requested-With',
41
+ 'X-Oxy-User-Id',
42
+ 'X-Oxy-Internal',
43
+ 'X-CSRF-Token',
44
+ 'X-Oxy-Edge-Region',
45
+ 'X-Oxy-Activity-Id',
46
+ ];
47
+ /** How long (seconds) a browser may cache a successful preflight. */
48
+ const DEFAULT_MAX_AGE_SECONDS = 86400;
49
+ const OXY_ONE_LABEL_SUBDOMAIN_PATTERN = new RegExp(`^[a-z0-9-]+\\.${authWebUrl_1.CENTRAL_IDP_APEX.replace('.', '\\.')}$`);
50
+ /**
51
+ * Whether `candidate` belongs to the built-in Oxy apex origin family. This
52
+ * intentionally mirrors the API allowlist shape: HTTPS only, no custom port,
53
+ * the apex itself (`https://oxy.so`), or exactly one lowercase subdomain label
54
+ * (`https://auth.oxy.so`, `https://api.oxy.so`, …).
55
+ *
56
+ * Arbitrary/multi-level subdomains and `http://*.oxy.so` are not implicitly
57
+ * trusted for credentialed CORS. If a service needs a non-standard development
58
+ * or tenant origin, it must opt in explicitly via `appOrigins`.
59
+ */
60
+ function isOxyFamilyOrigin(candidate) {
61
+ try {
62
+ const url = new URL(candidate);
63
+ if (url.protocol !== 'https:' || url.port !== '')
64
+ return false;
65
+ const hostname = url.hostname;
66
+ if (hostname === authWebUrl_1.CENTRAL_IDP_APEX)
67
+ return true;
68
+ return OXY_ONE_LABEL_SUBDOMAIN_PATTERN.test(hostname);
69
+ }
70
+ catch {
71
+ return false;
72
+ }
73
+ }
74
+ /**
75
+ * The URL standard's serialization of an OPAQUE origin: the literal string
76
+ * `"null"`, which `new URL(x).origin` returns for every scheme that has no
77
+ * origin to speak of — `exp:`, `capacitor:`, `chrome-extension:`,
78
+ * `vscode-webview:`, and also `file:`, `data:` and `about:`.
79
+ *
80
+ * This value is why an allowlist may never store it. Every such scheme
81
+ * normalizes to the SAME `"null"`, so a set built by normalization cannot tell
82
+ * them apart: ONE opaque entry admits ALL of them. With credentials on and the
83
+ * raw header echoed back, a single `myapp://` in `appOrigins` turned this
84
+ * helper into "allow any custom-scheme browsing context" — measured live, an
85
+ * `exp://localhost:8150` entry answered `Origin: vscode-webview://…` with
86
+ * `access-control-allow-origin: vscode-webview://…` and
87
+ * `access-control-allow-credentials: true`.
88
+ *
89
+ * There is deliberately no escape hatch that matches such an origin by raw
90
+ * string instead. Admitting a custom-scheme browsing context to a CREDENTIALED
91
+ * allowlist is a distinct decision with its own threat model, and it must not
92
+ * arrive as a side effect of someone adding one line to `appOrigins`. Note
93
+ * also that a native client is not subject to CORS at all — React Native sends
94
+ * no `Origin` header — so a mobile app never needs an entry here.
95
+ */
96
+ const OPAQUE_ORIGIN = 'null';
97
+ /** Normalize a raw origin string to its canonical `scheme://host[:port]` form. */
98
+ function normalizeOrigin(raw) {
99
+ try {
100
+ return new URL(raw).origin;
101
+ }
102
+ catch {
103
+ return null;
104
+ }
105
+ }
106
+ /**
107
+ * Normalize the configured `appOrigins` into the exact-match set — the
108
+ * CONFIGURE-SIDE half of the opaque-origin guard.
109
+ *
110
+ * An entry that is not a URL, or whose origin is opaque, is dropped and named
111
+ * in an error log. Dropped rather than thrown on because `appOrigins` is
112
+ * deployment configuration — at least one Oxy backend reads it from the
113
+ * environment — and a typo there must cost that one origin its CORS headers,
114
+ * never the whole service its boot. Both failure modes are equally SAFE (the
115
+ * entry is absent from the set either way), so the choice is purely about
116
+ * blast radius, and dropping keeps it to one origin whose requests then fail
117
+ * visibly in the browser.
118
+ *
119
+ * Exported for `__tests__/cors.socket.test.ts` and NOT re-exported from
120
+ * `server/index.ts`, so it is not part of the package's public surface. The
121
+ * two halves of the guard are separately exported because they are separately
122
+ * testable only that way: with this half in place the match-side half is
123
+ * unreachable through `createOxyCors`, so a test driving the public API alone
124
+ * would measure this function twice and the other one never.
125
+ */
126
+ function normalizeAppOrigins(appOrigins) {
127
+ const explicit = new Set();
128
+ for (const raw of appOrigins) {
129
+ const normalized = normalizeOrigin(raw);
130
+ if (normalized === null) {
131
+ log.error('CORS allowlist entry ignored: it is not a URL', undefined, { entry: raw });
132
+ continue;
133
+ }
134
+ if (normalized === OPAQUE_ORIGIN) {
135
+ log.error('CORS allowlist entry ignored: it has no origin to match against', undefined, {
136
+ entry: raw,
137
+ });
138
+ continue;
139
+ }
140
+ explicit.add(normalized);
141
+ }
142
+ return explicit;
143
+ }
144
+ /**
145
+ * Whether `origin` may be echoed back: it is in the built-in HTTPS Oxy apex
146
+ * family, or it exactly matches one of the configured app origins.
147
+ *
148
+ * The opaque-origin refusal here is the MATCH-SIDE half of the guard, and it
149
+ * is what makes the property hold regardless of how `explicit` was built — a
150
+ * set that somehow contains `"null"` still matches nothing, because no
151
+ * incoming origin ever normalizes past this line. `normalizeAppOrigins` is
152
+ * what stops such a set existing today; this is what stops it mattering.
153
+ *
154
+ * Exported for the same reason as `normalizeAppOrigins`, and likewise absent
155
+ * from `server/index.ts`.
156
+ */
157
+ function matchesAllowedOrigin(explicit, origin) {
158
+ const normalized = normalizeOrigin(origin);
159
+ if (normalized === null)
160
+ return false;
161
+ if (normalized === OPAQUE_ORIGIN)
162
+ return false;
163
+ if (explicit.has(normalized))
164
+ return true;
165
+ return isOxyFamilyOrigin(normalized);
166
+ }
167
+ /**
168
+ * Create a strict Oxy CORS middleware. See module docs.
169
+ *
170
+ * @example
171
+ * ```ts
172
+ * app.use(createOxyCors({ appOrigins: ['https://app.example.com'] }));
173
+ * ```
174
+ */
175
+ function createOxyCors(options = {}) {
176
+ const { appOrigins = [], allowCredentials = true, methods = DEFAULT_ALLOWED_METHODS, allowedHeaders = DEFAULT_ALLOWED_HEADERS, exposedHeaders = [], maxAgeSeconds = DEFAULT_MAX_AGE_SECONDS, } = options;
177
+ const explicitOrigins = normalizeAppOrigins(appOrigins);
178
+ const methodsHeader = methods.join(', ');
179
+ const allowedHeadersHeader = allowedHeaders.join(', ');
180
+ const exposedHeadersHeader = exposedHeaders.join(', ');
181
+ return (req, res, next) => {
182
+ const origin = req.headers.origin;
183
+ // Same-origin or non-browser requests carry no Origin header — pass through
184
+ // untouched (no ACAO header is emitted, which is correct for them).
185
+ if (typeof origin !== 'string' || origin.length === 0) {
186
+ if (req.method === 'OPTIONS') {
187
+ res.sendStatus(204);
188
+ return;
189
+ }
190
+ next();
191
+ return;
192
+ }
193
+ // Origin is present. Caching correctness: this response varies by Origin.
194
+ res.setHeader('Vary', 'Origin');
195
+ if (!matchesAllowedOrigin(explicitOrigins, origin)) {
196
+ // DENY: do NOT reflect the origin, do NOT emit a wildcard. The browser
197
+ // will block the cross-origin read. Preflights for denied origins get a
198
+ // 204 with no CORS headers (the actual request then fails CORS).
199
+ if (req.method === 'OPTIONS') {
200
+ res.sendStatus(204);
201
+ return;
202
+ }
203
+ next();
204
+ return;
205
+ }
206
+ // ALLOW: echo the EXACT matched origin — never `*`, even without credentials.
207
+ res.setHeader('Access-Control-Allow-Origin', origin);
208
+ if (allowCredentials) {
209
+ res.setHeader('Access-Control-Allow-Credentials', 'true');
210
+ }
211
+ if (exposedHeadersHeader) {
212
+ res.setHeader('Access-Control-Expose-Headers', exposedHeadersHeader);
213
+ }
214
+ if (req.method === 'OPTIONS') {
215
+ res.setHeader('Access-Control-Allow-Methods', methodsHeader);
216
+ // Honour the browser's requested headers when present, else the default set.
217
+ const requested = req.headers['access-control-request-headers'];
218
+ res.setHeader('Access-Control-Allow-Headers', typeof requested === 'string' && requested.length > 0 ? requested : allowedHeadersHeader);
219
+ res.setHeader('Access-Control-Max-Age', String(maxAgeSeconds));
220
+ res.sendStatus(204);
221
+ return;
222
+ }
223
+ next();
224
+ };
225
+ }
@@ -0,0 +1,97 @@
1
+ "use strict";
2
+ /**
3
+ * @oxy.so/core/server — Server-only utilities for Oxy backends
4
+ *
5
+ * This subpath export provides Express middleware and Node.js-specific
6
+ * utilities that are not available in React Native or browser environments.
7
+ *
8
+ * @example
9
+ * ```ts
10
+ * import { createOxyRateLimit } from '@oxy.so/core/server';
11
+ * import { oxyClient } from '@oxy.so/core';
12
+ *
13
+ * const oxy = oxyClient({ apiUrl: 'https://api.oxy.so' });
14
+ *
15
+ * app.use(createOxyRateLimit(oxy, { store: redisStore }));
16
+ * ```
17
+ */
18
+ Object.defineProperty(exports, "__esModule", { value: true });
19
+ exports.isOfficialWebOrigin = exports.registrableApex = exports.OXY_IDENTITY_CACHE_PREFIXES = exports.oxyUserByIdCacheKey = exports.evictOxyIdentityCache = exports.publishOxyUserInvalidation = exports.createOxyUserInvalidationHandler = exports.verifySecret = exports.verifyCapabilityTicket = exports.readCapabilityAuthorization = exports.issueCapabilityTicket = exports.inputSatisfiesCapabilityLimits = exports.createCapabilityTicketMiddleware = exports.CapabilityTicketError = exports.OXY_CSP_BASELINE = exports.inlineScriptCspHash = exports.formatOxyCspPolicy = exports.extractInlineScripts = exports.cspSourcesFor = exports.createOxySecurityHeaders = exports.buildOxyPagesHeaders = exports.buildOxyCspDirectives = exports.createOxyCors = exports.UPSTREAM_HEADERS_TIMEOUT_MS = exports.MAX_URL_LENGTH = exports.MAX_REDIRECTS = exports.DEFAULT_USER_AGENT = exports.BLOCKED_HOSTNAMES = exports.ALLOWED_PROTOCOLS = exports.ALLOWED_PORTS = exports.UpstreamError = exports.SsrfRejection = exports.safeFetch = exports.isBlockedIp = exports.assertSafePublicUrl = exports.createOxyRateLimit = exports.OXY_SERVICE_ENVIRONMENTS = exports.requireOxyAuth = exports.isOxyAuthenticated = exports.getRequiredOxyUserId = exports.getRequiredOxyBillingPrincipal = exports.getOxyUserId = exports.getOxyRequestAttribution = exports.getOxyDelegatedUserId = exports.getOxyBillingPrincipal = exports.createOxyAuthMiddleware = exports.createOptionalOxyAuth = void 0;
20
+ var auth_1 = require("./auth");
21
+ Object.defineProperty(exports, "createOptionalOxyAuth", { enumerable: true, get: function () { return auth_1.createOptionalOxyAuth; } });
22
+ Object.defineProperty(exports, "createOxyAuthMiddleware", { enumerable: true, get: function () { return auth_1.createOxyAuthMiddleware; } });
23
+ Object.defineProperty(exports, "getOxyBillingPrincipal", { enumerable: true, get: function () { return auth_1.getOxyBillingPrincipal; } });
24
+ Object.defineProperty(exports, "getOxyDelegatedUserId", { enumerable: true, get: function () { return auth_1.getOxyDelegatedUserId; } });
25
+ Object.defineProperty(exports, "getOxyRequestAttribution", { enumerable: true, get: function () { return auth_1.getOxyRequestAttribution; } });
26
+ Object.defineProperty(exports, "getOxyUserId", { enumerable: true, get: function () { return auth_1.getOxyUserId; } });
27
+ Object.defineProperty(exports, "getRequiredOxyBillingPrincipal", { enumerable: true, get: function () { return auth_1.getRequiredOxyBillingPrincipal; } });
28
+ Object.defineProperty(exports, "getRequiredOxyUserId", { enumerable: true, get: function () { return auth_1.getRequiredOxyUserId; } });
29
+ Object.defineProperty(exports, "isOxyAuthenticated", { enumerable: true, get: function () { return auth_1.isOxyAuthenticated; } });
30
+ Object.defineProperty(exports, "requireOxyAuth", { enumerable: true, get: function () { return auth_1.requireOxyAuth; } });
31
+ Object.defineProperty(exports, "OXY_SERVICE_ENVIRONMENTS", { enumerable: true, get: function () { return auth_1.OXY_SERVICE_ENVIRONMENTS; } });
32
+ var rateLimit_1 = require("./rateLimit");
33
+ Object.defineProperty(exports, "createOxyRateLimit", { enumerable: true, get: function () { return rateLimit_1.createOxyRateLimit; } });
34
+ // SSRF-safe upstream fetch + URL validation (Node-only).
35
+ var safeFetch_1 = require("./safeFetch");
36
+ Object.defineProperty(exports, "assertSafePublicUrl", { enumerable: true, get: function () { return safeFetch_1.assertSafePublicUrl; } });
37
+ Object.defineProperty(exports, "isBlockedIp", { enumerable: true, get: function () { return safeFetch_1.isBlockedIp; } });
38
+ Object.defineProperty(exports, "safeFetch", { enumerable: true, get: function () { return safeFetch_1.safeFetch; } });
39
+ Object.defineProperty(exports, "SsrfRejection", { enumerable: true, get: function () { return safeFetch_1.SsrfRejection; } });
40
+ Object.defineProperty(exports, "UpstreamError", { enumerable: true, get: function () { return safeFetch_1.UpstreamError; } });
41
+ Object.defineProperty(exports, "ALLOWED_PORTS", { enumerable: true, get: function () { return safeFetch_1.ALLOWED_PORTS; } });
42
+ Object.defineProperty(exports, "ALLOWED_PROTOCOLS", { enumerable: true, get: function () { return safeFetch_1.ALLOWED_PROTOCOLS; } });
43
+ Object.defineProperty(exports, "BLOCKED_HOSTNAMES", { enumerable: true, get: function () { return safeFetch_1.BLOCKED_HOSTNAMES; } });
44
+ Object.defineProperty(exports, "DEFAULT_USER_AGENT", { enumerable: true, get: function () { return safeFetch_1.DEFAULT_USER_AGENT; } });
45
+ Object.defineProperty(exports, "MAX_REDIRECTS", { enumerable: true, get: function () { return safeFetch_1.MAX_REDIRECTS; } });
46
+ Object.defineProperty(exports, "MAX_URL_LENGTH", { enumerable: true, get: function () { return safeFetch_1.MAX_URL_LENGTH; } });
47
+ Object.defineProperty(exports, "UPSTREAM_HEADERS_TIMEOUT_MS", { enumerable: true, get: function () { return safeFetch_1.UPSTREAM_HEADERS_TIMEOUT_MS; } });
48
+ // Strict CORS allowlist (Oxy apex family + explicit app origins).
49
+ var cors_1 = require("./cors");
50
+ Object.defineProperty(exports, "createOxyCors", { enumerable: true, get: function () { return cors_1.createOxyCors; } });
51
+ // Shared Helmet + Content-Security-Policy baseline (Cloudflare Insights beacon,
52
+ // Oxy API/CDN origins) with additive, per-app extensions.
53
+ //
54
+ // `extractInlineScripts` / `inlineScriptCspHash` / `cspSourcesFor` are exported
55
+ // so a post-deploy gate can ask the SERVED document and the SERVED policy the
56
+ // same questions `buildOxyPagesHeaders` asked the built ones. A gate that
57
+ // re-implemented the scan or the parse would be testing its own copy, and would
58
+ // agree with a broken original.
59
+ var securityHeaders_1 = require("./securityHeaders");
60
+ Object.defineProperty(exports, "buildOxyCspDirectives", { enumerable: true, get: function () { return securityHeaders_1.buildOxyCspDirectives; } });
61
+ Object.defineProperty(exports, "buildOxyPagesHeaders", { enumerable: true, get: function () { return securityHeaders_1.buildOxyPagesHeaders; } });
62
+ Object.defineProperty(exports, "createOxySecurityHeaders", { enumerable: true, get: function () { return securityHeaders_1.createOxySecurityHeaders; } });
63
+ Object.defineProperty(exports, "cspSourcesFor", { enumerable: true, get: function () { return securityHeaders_1.cspSourcesFor; } });
64
+ Object.defineProperty(exports, "extractInlineScripts", { enumerable: true, get: function () { return securityHeaders_1.extractInlineScripts; } });
65
+ Object.defineProperty(exports, "formatOxyCspPolicy", { enumerable: true, get: function () { return securityHeaders_1.formatOxyCspPolicy; } });
66
+ Object.defineProperty(exports, "inlineScriptCspHash", { enumerable: true, get: function () { return securityHeaders_1.inlineScriptCspHash; } });
67
+ Object.defineProperty(exports, "OXY_CSP_BASELINE", { enumerable: true, get: function () { return securityHeaders_1.OXY_CSP_BASELINE; } });
68
+ var capabilityTicket_1 = require("./capabilityTicket");
69
+ Object.defineProperty(exports, "CapabilityTicketError", { enumerable: true, get: function () { return capabilityTicket_1.CapabilityTicketError; } });
70
+ Object.defineProperty(exports, "createCapabilityTicketMiddleware", { enumerable: true, get: function () { return capabilityTicket_1.createCapabilityTicketMiddleware; } });
71
+ Object.defineProperty(exports, "inputSatisfiesCapabilityLimits", { enumerable: true, get: function () { return capabilityTicket_1.inputSatisfiesCapabilityLimits; } });
72
+ Object.defineProperty(exports, "issueCapabilityTicket", { enumerable: true, get: function () { return capabilityTicket_1.issueCapabilityTicket; } });
73
+ Object.defineProperty(exports, "readCapabilityAuthorization", { enumerable: true, get: function () { return capabilityTicket_1.readCapabilityAuthorization; } });
74
+ Object.defineProperty(exports, "verifyCapabilityTicket", { enumerable: true, get: function () { return capabilityTicket_1.verifyCapabilityTicket; } });
75
+ // Constant-time secret comparison.
76
+ var verifySecret_1 = require("./verifySecret");
77
+ Object.defineProperty(exports, "verifySecret", { enumerable: true, get: function () { return verifySecret_1.verifySecret; } });
78
+ // Cross-service user-invalidation signal: oxy-api publishes when identity
79
+ // changes, every consuming backend sweeps its caches instead of waiting out a TTL.
80
+ var userInvalidation_1 = require("./userInvalidation");
81
+ Object.defineProperty(exports, "createOxyUserInvalidationHandler", { enumerable: true, get: function () { return userInvalidation_1.createOxyUserInvalidationHandler; } });
82
+ Object.defineProperty(exports, "publishOxyUserInvalidation", { enumerable: true, get: function () { return userInvalidation_1.publishOxyUserInvalidation; } });
83
+ // The identity-key enumeration itself is platform-neutral (`src/utils/`) so the
84
+ // client mixins and this Node-only subscriber sweep the SAME list — a second
85
+ // copy is what let `updateAccount` and `updateProfile` drift apart.
86
+ var identityCacheSweep_1 = require("../utils/identityCacheSweep");
87
+ Object.defineProperty(exports, "evictOxyIdentityCache", { enumerable: true, get: function () { return identityCacheSweep_1.evictOxyIdentityCache; } });
88
+ Object.defineProperty(exports, "oxyUserByIdCacheKey", { enumerable: true, get: function () { return identityCacheSweep_1.oxyUserByIdCacheKey; } });
89
+ Object.defineProperty(exports, "OXY_IDENTITY_CACHE_PREFIXES", { enumerable: true, get: function () { return identityCacheSweep_1.OXY_IDENTITY_CACHE_PREFIXES; } });
90
+ // Registrable-apex (eTLD+1) derivation via the Public Suffix List — the SINGLE
91
+ // SOURCE OF TRUTH shared with the IdP worker and the client FAPI auto-detect.
92
+ // Pure host handling (no browser deps), so it is safe on the server subpath and
93
+ // lets `@oxy.so/api` derive `auth.<apex>` without duplicating PSL logic.
94
+ var registrableApex_1 = require("../utils/registrableApex");
95
+ Object.defineProperty(exports, "registrableApex", { enumerable: true, get: function () { return registrableApex_1.registrableApex; } });
96
+ var officialOrigins_1 = require("../utils/officialOrigins");
97
+ Object.defineProperty(exports, "isOfficialWebOrigin", { enumerable: true, get: function () { return officialOrigins_1.isOfficialWebOrigin; } });
@@ -0,0 +1,207 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.createOxyRateLimit = createOxyRateLimit;
7
+ const node_crypto_1 = require("node:crypto");
8
+ const node_net_1 = require("node:net");
9
+ const express_rate_limit_1 = __importDefault(require("express-rate-limit"));
10
+ const auth_1 = require("./auth");
11
+ /**
12
+ * Built-in exemptions. A media app's cover-art/avatar fan-out and HLS
13
+ * sub-requests must not consume the coarse global budget; health probes from
14
+ * the load balancer must never be limited; CORS preflight is not a real call.
15
+ */
16
+ function isBuiltInExempt(req) {
17
+ const path = req.path;
18
+ return (req.method === 'OPTIONS' ||
19
+ path.startsWith('/files/upload') ||
20
+ path.includes('/images/') ||
21
+ path.includes('/media/') ||
22
+ path.startsWith('/api/stream/') ||
23
+ path.includes('/stream/') ||
24
+ path === '/health' ||
25
+ path.endsWith('/health'));
26
+ }
27
+ /**
28
+ * Anonymous rate-limit keys must be PRIVACY-PRESERVING: the raw client IP must
29
+ * never reach a store at rest (in-memory or Redis). We therefore HMAC-hash the
30
+ * IP into a short, transient-only bucket key. Two IPv6-specific concerns shape
31
+ * the pre-hash normalization:
32
+ *
33
+ * - IPv6 hosts are typically handed an entire /64 (often a /56), so a single
34
+ * host can rotate through an enormous address space and evade a per-address
35
+ * limit. We bucket IPv6 to its /56 prefix BEFORE hashing.
36
+ * - express-rate-limit only exposes an `ipKeyGenerator` /56 helper from v8
37
+ * onwards; `@oxy.so/core` pins v7 (peer `^7.0.0`), so the masking is
38
+ * implemented here rather than pulling a major-version bump of a
39
+ * security-critical dependency (and its rate-limit-redis compatibility) into
40
+ * an unrelated privacy change. This mirrors `packages/api/src/utils/ipKey.ts`.
41
+ */
42
+ const IPV6_SUBNET_BITS = 56;
43
+ /** Expand an IPv6 literal (handling `::` and embedded IPv4) to 8 numeric hextets, or null if unparseable. */
44
+ function ipv6Hextets(ip) {
45
+ let addr = ip;
46
+ const zone = addr.indexOf('%');
47
+ if (zone !== -1) {
48
+ addr = addr.slice(0, zone);
49
+ }
50
+ // Embedded IPv4 tail (e.g. `::ffff:203.0.113.7`) → fold the dotted quad into two hextets.
51
+ const lastColon = addr.lastIndexOf(':');
52
+ if (lastColon !== -1 && addr.slice(lastColon + 1).includes('.')) {
53
+ const v4 = addr.slice(lastColon + 1);
54
+ if (!(0, node_net_1.isIPv4)(v4)) {
55
+ return null;
56
+ }
57
+ const octets = v4.split('.').map((part) => Number.parseInt(part, 10));
58
+ const high = ((octets[0] << 8) | octets[1]).toString(16);
59
+ const low = ((octets[2] << 8) | octets[3]).toString(16);
60
+ addr = `${addr.slice(0, lastColon + 1)}${high}:${low}`;
61
+ }
62
+ const halves = addr.split('::');
63
+ if (halves.length > 2) {
64
+ return null;
65
+ }
66
+ const head = halves[0] ? halves[0].split(':') : [];
67
+ const tail = halves.length === 2 && halves[1] ? halves[1].split(':') : [];
68
+ let groups;
69
+ if (halves.length === 1) {
70
+ groups = head;
71
+ }
72
+ else {
73
+ const missing = 8 - (head.length + tail.length);
74
+ if (missing < 0) {
75
+ return null;
76
+ }
77
+ groups = [...head, ...new Array(missing).fill('0'), ...tail];
78
+ }
79
+ if (groups.length !== 8) {
80
+ return null;
81
+ }
82
+ const hextets = groups.map((group) => Number.parseInt(group || '0', 16));
83
+ if (hextets.some((value) => Number.isNaN(value) || value < 0 || value > 0xffff)) {
84
+ return null;
85
+ }
86
+ return hextets;
87
+ }
88
+ /** Mask an IPv6 address to its /{bits} prefix, returned as a canonical hex string. */
89
+ function maskIPv6(ip, bits) {
90
+ const hextets = ipv6Hextets(ip);
91
+ if (!hextets) {
92
+ return ip;
93
+ }
94
+ const masked = hextets.map((hextet, index) => {
95
+ const groupStart = index * 16;
96
+ if (groupStart >= bits) {
97
+ return 0;
98
+ }
99
+ const keepBits = Math.min(16, bits - groupStart);
100
+ const mask = keepBits >= 16 ? 0xffff : (0xffff << (16 - keepBits)) & 0xffff;
101
+ return hextet & mask;
102
+ });
103
+ return `${masked.map((hextet) => hextet.toString(16)).join(':')}/${bits}`;
104
+ }
105
+ /**
106
+ * Hash a client IP into a privacy-preserving bucket key. IPv6 is bucketed to its
107
+ * /56 prefix first (so a single v6 host can't rotate through its allocation to
108
+ * mint fresh keys), then HMAC'd with the server-side salt. The salt is resolved
109
+ * at CALL time (`IP_HASH_SALT`, else `DEVICE_ID_SALT`, else empty) — an empty
110
+ * salt still hashes, which beats storing a raw IP; backends SHOULD set one of
111
+ * those envs. The `rl|` namespace ensures a rate-limit key can never collide
112
+ * with, or be correlated against, a deviceId derivation that reuses the same
113
+ * salt. The result is a short hex digest with no colons, so it is Redis-safe.
114
+ */
115
+ function hashAnonymousIp(ip) {
116
+ const normalized = (0, node_net_1.isIPv6)(ip) && !ip.startsWith('::ffff:') ? maskIPv6(ip, IPV6_SUBNET_BITS) : ip;
117
+ const salt = process.env.IP_HASH_SALT || process.env.DEVICE_ID_SALT || '';
118
+ return (0, node_crypto_1.createHmac)('sha256', salt).update(`rl|${normalized}`).digest('hex').slice(0, 24);
119
+ }
120
+ /**
121
+ * Resolve the trusted authenticated rate-limit key.
122
+ *
123
+ * Only identities that came from a server-validated session or a verified
124
+ * service token/delegation may pick a bucket. `req.sessionId` is the marker
125
+ * for the former: `oxy.auth()` sets it only after `validateSession()` came
126
+ * back valid, so requiring it here means an identity written by some OTHER
127
+ * middleware — which this package cannot vouch for — shares the anonymous
128
+ * per-IP bucket rather than getting the authenticated quota.
129
+ */
130
+ function resolveTrustedAuthenticatedKey(req) {
131
+ const userId = req.userId ?? req.user?.id ?? req.user?._id;
132
+ if (userId && req.sessionId) {
133
+ return `user:${userId}`;
134
+ }
135
+ const delegatedUserId = req.serviceActingAs?.userId;
136
+ if (delegatedUserId && req.serviceApp?.appId) {
137
+ return `user:${delegatedUserId}`;
138
+ }
139
+ const serviceAppId = req.serviceApp?.appId;
140
+ if (serviceAppId) {
141
+ return `service:${serviceAppId}`;
142
+ }
143
+ return null;
144
+ }
145
+ /** Resolve the rate-limit key: per trusted authenticated identity, else per hashed (IPv6-bucketed) IP. */
146
+ function resolveKey(req) {
147
+ const authenticatedKey = resolveTrustedAuthenticatedKey(req);
148
+ if (authenticatedKey) {
149
+ return authenticatedKey;
150
+ }
151
+ const ip = req.ip || req.socket.remoteAddress;
152
+ if (!ip) {
153
+ return 'unknown';
154
+ }
155
+ return hashAnonymousIp(ip);
156
+ }
157
+ /**
158
+ * Build the composed Oxy rate-limit middleware. See module docs for rationale.
159
+ */
160
+ function createOxyRateLimit(oxy, options = {}) {
161
+ const { authenticatedMax = 5000, anonymousMax = 600, windowMs = 15 * 60 * 1000, store, exempt, message = 'Too many requests, please try again later.', auth, } = options;
162
+ // Idempotent optional-auth resolver. Reuses the SAME session resolution as
163
+ // every protected route, so the limiter keys by the real user identity.
164
+ //
165
+ // `createOptionalOxyAuth` — NOT the raw `oxy.auth({ optional: true })` —
166
+ // because only the former skips resolution when a preceding middleware has
167
+ // already resolved a user. The raw middleware writes `req.userId = null` on
168
+ // every request it cannot authenticate, and because it mutates the shared
169
+ // `req` that erasure is visible to every handler downstream of the limiter,
170
+ // not just to the bucket calculation.
171
+ const resolveSession = (0, auth_1.createOptionalOxyAuth)(oxy, { auth });
172
+ const skip = (req) => isBuiltInExempt(req) || (exempt ? exempt(req) : false);
173
+ const limiter = (0, express_rate_limit_1.default)({
174
+ windowMs,
175
+ ...(store ? { store } : {}),
176
+ max: (req) => {
177
+ return resolveTrustedAuthenticatedKey(req)
178
+ ? authenticatedMax
179
+ : anonymousMax;
180
+ },
181
+ keyGenerator: (req) => resolveKey(req),
182
+ message,
183
+ standardHeaders: true,
184
+ legacyHeaders: false,
185
+ skip,
186
+ // hashAnonymousIp already buckets IPv6 to /56 before HMAC; disable the v8
187
+ // static source scan that false-positives on req.ip (ERR_ERL_KEY_GEN_IPV6).
188
+ validate: { keyGeneratorIpFallback: false },
189
+ });
190
+ return (req, res, next) => {
191
+ // Skipped paths bypass BOTH session resolution and limiting — cheap and
192
+ // safe for static/streaming/health traffic.
193
+ if (skip(req)) {
194
+ next();
195
+ return;
196
+ }
197
+ resolveSession(req, res, (err) => {
198
+ if (err) {
199
+ // Optional auth never rejects; a token error just means "anonymous".
200
+ // Swallow the error and continue through the anonymous limiter.
201
+ limiter(req, res, next);
202
+ return;
203
+ }
204
+ limiter(req, res, next);
205
+ });
206
+ };
207
+ }