@oxy.so/core 1.18.1 → 3.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.
- package/README.md +13 -7
- package/dist/cjs/HttpService.js +159 -111
- package/dist/cjs/OxyServices.errors.js +48 -1
- package/dist/cjs/OxyServices.js +263 -60
- package/dist/cjs/api/accounts.js +231 -0
- package/dist/cjs/api/agency.js +102 -0
- package/dist/cjs/api/appData.js +45 -0
- package/dist/cjs/api/apps.js +197 -0
- package/dist/cjs/api/assets.js +329 -0
- package/dist/cjs/api/auth.js +900 -0
- package/dist/cjs/api/billing.js +44 -0
- package/dist/cjs/api/civic.js +289 -0
- package/dist/cjs/api/contacts.js +16 -0
- package/dist/cjs/api/devices.js +351 -0
- package/dist/cjs/api/follows.js +240 -0
- package/dist/cjs/api/identity.js +569 -0
- package/dist/cjs/api/linkedAccounts.js +48 -0
- package/dist/cjs/api/nodes.js +75 -0
- package/dist/cjs/api/notifications.js +75 -0
- package/dist/cjs/api/privacy.js +105 -0
- package/dist/cjs/api/reputation.js +74 -0
- package/dist/cjs/api/session.js +177 -0
- package/dist/cjs/api/store.js +199 -0
- package/dist/cjs/api/topics.js +66 -0
- package/dist/cjs/api/users.js +309 -0
- package/dist/cjs/boot/sessionColdBoot.js +4 -4
- package/dist/cjs/civic/index.js +16 -0
- package/dist/cjs/civic/payloads.js +156 -0
- package/dist/cjs/client/context.js +2 -0
- package/dist/cjs/crypto/identityLink.js +5 -5
- package/dist/cjs/crypto/index.js +44 -0
- package/dist/cjs/crypto/internal.js +37 -0
- package/dist/cjs/crypto/keyManager.js +2 -2
- package/dist/cjs/crypto/polyfill.js +9 -80
- package/dist/cjs/crypto/recoveryPhrase.js +1 -0
- package/dist/cjs/crypto/registrationPow.js +1 -1
- package/dist/cjs/crypto/signatureService.js +1 -0
- package/dist/cjs/i18n/accountCategoryLabels.js +3 -3
- package/dist/cjs/i18n/accountRoleLabels.js +7 -7
- package/dist/cjs/i18n/index.js +130 -52
- package/dist/cjs/i18n/locales/{ar-SA.json → ar-SA.js} +134 -52
- package/dist/cjs/i18n/locales/{ca-ES.json → ca-ES.js} +134 -52
- package/dist/{esm/i18n/locales/de-DE.json → cjs/i18n/locales/de-DE.js} +136 -54
- package/dist/{esm/i18n/locales/en-US.json → cjs/i18n/locales/en-US.js} +163 -245
- package/dist/{esm/i18n/locales/es-ES.json → cjs/i18n/locales/es-ES.js} +163 -245
- package/dist/cjs/i18n/locales/{fr-FR.json → fr-FR.js} +134 -52
- package/dist/cjs/i18n/locales/{it-IT.json → it-IT.js} +134 -52
- package/dist/{esm/i18n/locales/ja-JP.json → cjs/i18n/locales/ja-JP.js} +134 -52
- package/dist/cjs/i18n/locales/{ko-KR.json → ko-KR.js} +134 -52
- package/dist/{esm/i18n/locales/pt-PT.json → cjs/i18n/locales/pt-PT.js} +136 -54
- package/dist/{esm/i18n/locales/zh-CN.json → cjs/i18n/locales/zh-CN.js} +135 -53
- package/dist/cjs/i18n/reputationCategoryLabels.js +2 -2
- package/dist/cjs/i18n/trustTierLabels.js +2 -2
- package/dist/cjs/index.js +55 -263
- package/dist/cjs/inference/index.js +21 -0
- package/dist/cjs/server/OxyServer.js +521 -0
- package/dist/cjs/server/auth.js +2 -2
- package/dist/cjs/server/index.js +23 -6
- package/dist/cjs/server/middleware.js +1154 -0
- package/dist/cjs/server/namespaces.js +214 -0
- package/dist/cjs/server/rateLimit.js +2 -2
- package/dist/cjs/server/requesterAssertion.js +5 -5
- package/dist/cjs/server/securityHeaders.js +3 -3
- package/dist/cjs/server/traffic.js +7 -6
- package/dist/cjs/server/trafficNodeHttp.js +9 -3
- package/dist/cjs/server/userInvalidation.js +5 -5
- package/dist/cjs/session/accountDialogController.js +23 -23
- package/dist/cjs/session/authStateStore.js +2 -2
- package/dist/cjs/session/identitySession.js +3 -3
- package/dist/cjs/session/index.js +131 -0
- package/dist/cjs/session/refresh.js +37 -30
- package/dist/cjs/session/sessionClientHost.js +5 -5
- package/dist/cjs/session/sharedDeviceCredential.js +3 -2
- package/dist/cjs/shared/utils/networkUtils.js +2 -2
- package/dist/cjs/utils/accountCacheSweep.js +11 -15
- package/dist/cjs/utils/asyncUtils.js +22 -163
- package/dist/cjs/utils/authHelpers.js +2 -2
- package/dist/cjs/utils/authWebUrl.js +3 -4
- package/dist/cjs/utils/avatarUtils.js +2 -2
- package/dist/cjs/utils/cache.js +32 -2
- package/dist/cjs/utils/cacheKey.js +5 -10
- package/dist/cjs/utils/deviceManager.js +17 -16
- package/dist/cjs/utils/edgeRegion.js +2 -3
- package/dist/cjs/utils/identityCacheSweep.js +6 -10
- package/dist/cjs/utils/oxyServiceEnvironment.js +3 -7
- package/dist/cjs/utils/requestUtils.js +40 -33
- package/dist/cjs/utils/sessionUtils.js +0 -2
- package/dist/cjs/utils/tokenClaims.js +34 -0
- package/dist/esm/HttpService.js +160 -112
- package/dist/esm/OxyServices.errors.js +45 -0
- package/dist/esm/OxyServices.js +262 -57
- package/dist/esm/api/accounts.js +218 -0
- package/dist/esm/api/agency.js +95 -0
- package/dist/esm/api/appData.js +40 -0
- package/dist/esm/api/apps.js +191 -0
- package/dist/esm/api/assets.js +324 -0
- package/dist/esm/api/auth.js +858 -0
- package/dist/esm/api/billing.js +40 -0
- package/dist/esm/api/civic.js +250 -0
- package/dist/esm/api/contacts.js +12 -0
- package/dist/esm/api/devices.js +346 -0
- package/dist/esm/api/follows.js +236 -0
- package/dist/esm/api/identity.js +527 -0
- package/dist/esm/api/linkedAccounts.js +44 -0
- package/dist/esm/api/nodes.js +71 -0
- package/dist/esm/api/notifications.js +71 -0
- package/dist/esm/api/privacy.js +101 -0
- package/dist/esm/api/reputation.js +70 -0
- package/dist/esm/api/session.js +173 -0
- package/dist/esm/api/store.js +192 -0
- package/dist/esm/api/topics.js +62 -0
- package/dist/esm/api/users.js +272 -0
- package/dist/esm/boot/sessionColdBoot.js +4 -4
- package/dist/esm/civic/index.js +10 -0
- package/dist/esm/civic/payloads.js +118 -0
- package/dist/esm/client/context.js +1 -0
- package/dist/esm/crypto/identityLink.js +5 -5
- package/dist/esm/crypto/index.js +24 -0
- package/dist/esm/crypto/internal.js +19 -0
- package/dist/esm/crypto/keyManager.js +2 -2
- package/dist/esm/crypto/polyfill.js +10 -81
- package/dist/esm/crypto/recoveryPhrase.js +1 -0
- package/dist/esm/crypto/registrationPow.js +1 -1
- package/dist/esm/crypto/signatureService.js +1 -0
- package/dist/esm/i18n/accountCategoryLabels.js +2 -2
- package/dist/esm/i18n/accountRoleLabels.js +1 -1
- package/dist/esm/i18n/index.js +93 -52
- package/dist/esm/i18n/locales/{ar-SA.json → ar-SA.js} +132 -52
- package/dist/esm/i18n/locales/{ca-ES.json → ca-ES.js} +132 -52
- package/dist/{cjs/i18n/locales/de-DE.json → esm/i18n/locales/de-DE.js} +134 -54
- package/dist/{cjs/i18n/locales/en-US.json → esm/i18n/locales/en-US.js} +161 -245
- package/dist/{cjs/i18n/locales/es-ES.json → esm/i18n/locales/es-ES.js} +161 -245
- package/dist/esm/i18n/locales/{fr-FR.json → fr-FR.js} +132 -52
- package/dist/esm/i18n/locales/{it-IT.json → it-IT.js} +132 -52
- package/dist/{cjs/i18n/locales/ja-JP.json → esm/i18n/locales/ja-JP.js} +132 -52
- package/dist/esm/i18n/locales/{ko-KR.json → ko-KR.js} +132 -52
- package/dist/{cjs/i18n/locales/pt-PT.json → esm/i18n/locales/pt-PT.js} +134 -54
- package/dist/{cjs/i18n/locales/zh-CN.json → esm/i18n/locales/zh-CN.js} +133 -53
- package/dist/esm/i18n/reputationCategoryLabels.js +1 -1
- package/dist/esm/i18n/trustTierLabels.js +1 -1
- package/dist/esm/index.js +30 -166
- package/dist/esm/inference/index.js +13 -0
- package/dist/esm/server/OxyServer.js +516 -0
- package/dist/esm/server/auth.js +2 -2
- package/dist/esm/server/index.js +10 -5
- package/dist/esm/server/middleware.js +1147 -0
- package/dist/esm/server/namespaces.js +206 -0
- package/dist/esm/server/rateLimit.js +2 -2
- package/dist/esm/server/requesterAssertion.js +5 -5
- package/dist/esm/server/securityHeaders.js +3 -3
- package/dist/esm/server/traffic.js +7 -6
- package/dist/esm/server/trafficNodeHttp.js +9 -3
- package/dist/esm/server/userInvalidation.js +5 -5
- package/dist/esm/session/accountDialogController.js +23 -23
- package/dist/esm/session/authStateStore.js +2 -2
- package/dist/esm/session/identitySession.js +3 -3
- package/dist/esm/session/index.js +82 -0
- package/dist/esm/session/refresh.js +37 -30
- package/dist/esm/session/sessionClientHost.js +5 -5
- package/dist/esm/session/sharedDeviceCredential.js +3 -2
- package/dist/esm/shared/utils/networkUtils.js +2 -2
- package/dist/esm/utils/accountCacheSweep.js +11 -15
- package/dist/esm/utils/asyncUtils.js +22 -151
- package/dist/esm/utils/authHelpers.js +2 -2
- package/dist/esm/utils/authWebUrl.js +3 -4
- package/dist/esm/utils/avatarUtils.js +2 -2
- package/dist/esm/utils/cache.js +32 -2
- package/dist/esm/utils/cacheKey.js +5 -10
- package/dist/esm/utils/deviceManager.js +17 -16
- package/dist/esm/utils/edgeRegion.js +1 -2
- package/dist/esm/utils/identityCacheSweep.js +6 -10
- package/dist/esm/utils/oxyServiceEnvironment.js +3 -7
- package/dist/esm/utils/requestUtils.js +40 -33
- package/dist/esm/utils/sessionUtils.js +0 -2
- package/dist/esm/utils/tokenClaims.js +31 -0
- package/dist/types/HttpService.d.ts +26 -9
- package/dist/types/OxyServices.d.ts +160 -131
- package/dist/types/OxyServices.errors.d.ts +42 -0
- package/dist/types/api/accounts.d.ts +415 -0
- package/dist/types/api/agency.d.ts +135 -0
- package/dist/types/api/appData.d.ts +27 -0
- package/dist/types/api/apps.d.ts +433 -0
- package/dist/types/api/assets.d.ts +174 -0
- package/dist/types/api/auth.d.ts +766 -0
- package/dist/types/api/billing.d.ts +113 -0
- package/dist/types/api/civic.d.ts +203 -0
- package/dist/types/api/contacts.d.ts +31 -0
- package/{src/mixins/OxyServices.deviceBoot.ts → dist/types/api/devices.d.ts} +130 -110
- package/dist/types/api/follows.d.ts +236 -0
- package/dist/types/api/identity.d.ts +275 -0
- package/dist/types/api/linkedAccounts.d.ts +48 -0
- package/dist/types/api/nodes.d.ts +102 -0
- package/dist/types/api/notifications.d.ts +77 -0
- package/dist/types/api/privacy.d.ts +43 -0
- package/dist/types/api/reputation.d.ts +50 -0
- package/dist/types/api/session.d.ts +85 -0
- package/dist/types/api/store.d.ts +278 -0
- package/dist/types/api/topics.d.ts +34 -0
- package/dist/types/api/users.d.ts +134 -0
- package/dist/types/boot/sessionColdBoot.d.ts +1 -1
- package/dist/types/civic/index.d.ts +10 -0
- package/dist/types/civic/payloads.d.ts +83 -0
- package/dist/types/client/context.d.ts +33 -0
- package/dist/types/crypto/identityLink.d.ts +5 -5
- package/dist/types/crypto/index.d.ts +24 -0
- package/dist/types/crypto/internal.d.ts +19 -0
- package/dist/types/crypto/polyfill.d.ts +6 -9
- package/dist/types/crypto/registrationPow.d.ts +1 -1
- package/dist/types/i18n/accountCategoryLabels.d.ts +1 -1
- package/dist/types/i18n/accountRoleLabels.d.ts +1 -1
- package/dist/types/i18n/index.d.ts +20 -1
- package/dist/types/i18n/locales/ar-SA.d.ts +386 -0
- package/dist/types/i18n/locales/ca-ES.d.ts +386 -0
- package/dist/types/i18n/locales/de-DE.d.ts +386 -0
- package/dist/types/i18n/locales/en-US.d.ts +2034 -0
- package/dist/types/i18n/locales/es-ES.d.ts +2034 -0
- package/dist/types/i18n/locales/fr-FR.d.ts +386 -0
- package/dist/types/i18n/locales/it-IT.d.ts +386 -0
- package/dist/types/i18n/locales/ja-JP.d.ts +386 -0
- package/dist/types/i18n/locales/ko-KR.d.ts +386 -0
- package/dist/types/i18n/locales/pt-PT.d.ts +386 -0
- package/dist/types/i18n/locales/zh-CN.d.ts +386 -0
- package/dist/types/index.d.ts +46 -95
- package/dist/types/inference/index.d.ts +22 -0
- package/dist/types/models/interfaces.d.ts +1 -22
- package/dist/types/server/OxyServer.d.ts +183 -0
- package/dist/types/server/auth.d.ts +10 -7
- package/dist/types/server/index.d.ts +10 -4
- package/dist/types/server/middleware.d.ts +291 -0
- package/dist/types/server/namespaces.d.ts +98 -0
- package/dist/types/server/rateLimit.d.ts +7 -5
- package/dist/types/server/requesterAssertion.d.ts +14 -11
- package/dist/types/server/securityHeaders.d.ts +4 -5
- package/dist/types/server/userInvalidation.d.ts +10 -8
- package/dist/types/session/accountDelegationAccess.d.ts +1 -1
- package/dist/types/session/accountDialogController.d.ts +8 -8
- package/dist/types/session/accountSwitchTargets.d.ts +1 -1
- package/dist/types/session/authStateStore.d.ts +7 -6
- package/dist/types/session/index.d.ts +40 -0
- package/dist/types/utils/accountCacheSweep.d.ts +7 -10
- package/dist/types/utils/apiUtils.d.ts +3 -3
- package/dist/types/utils/asyncUtils.d.ts +11 -58
- package/dist/types/utils/authWebUrl.d.ts +3 -4
- package/dist/types/utils/avatarUtils.d.ts +5 -6
- package/dist/types/utils/cache.d.ts +11 -3
- package/dist/types/utils/commonsApproval.d.ts +1 -1
- package/dist/types/utils/edgeRegion.d.ts +1 -2
- package/dist/types/utils/identityCacheSweep.d.ts +6 -4
- package/dist/types/utils/oauthPkce.d.ts +2 -2
- package/dist/types/utils/oxyServiceEnvironment.d.ts +3 -7
- package/dist/types/utils/requestUtils.d.ts +18 -14
- package/dist/types/utils/tokenClaims.d.ts +9 -0
- package/package.json +68 -7
- package/src/HttpService.ts +166 -131
- package/src/OxyServices.errors.ts +73 -0
- package/src/OxyServices.ts +289 -164
- package/src/api/accounts.ts +579 -0
- package/src/api/agency.ts +277 -0
- package/src/api/appData.ts +63 -0
- package/src/api/apps.ts +596 -0
- package/src/api/assets.ts +416 -0
- package/src/api/auth.ts +1457 -0
- package/src/api/billing.ts +144 -0
- package/src/api/civic.ts +428 -0
- package/src/api/contacts.ts +41 -0
- package/src/api/devices.ts +438 -0
- package/src/api/follows.ts +414 -0
- package/src/api/identity.ts +727 -0
- package/src/api/linkedAccounts.ts +78 -0
- package/src/api/nodes.ts +169 -0
- package/src/api/notifications.ts +135 -0
- package/src/api/privacy.ts +120 -0
- package/src/api/reputation.ts +134 -0
- package/src/api/session.ts +210 -0
- package/src/api/store.ts +435 -0
- package/src/api/topics.ts +83 -0
- package/src/api/users.ts +357 -0
- package/src/boot/sessionColdBoot.ts +4 -4
- package/src/civic/index.ts +12 -0
- package/src/civic/payloads.ts +175 -0
- package/src/client/context.ts +34 -0
- package/src/crypto/identityLink.ts +5 -5
- package/src/crypto/index.ts +39 -0
- package/src/crypto/internal.ts +20 -0
- package/src/crypto/keyManager.ts +2 -2
- package/src/crypto/polyfill.ts +9 -89
- package/src/crypto/recoveryPhrase.ts +1 -0
- package/src/crypto/registrationPow.ts +1 -1
- package/src/crypto/signatureService.ts +1 -0
- package/src/i18n/accountCategoryLabels.ts +2 -2
- package/src/i18n/accountRoleLabels.ts +2 -2
- package/src/i18n/index.ts +105 -54
- package/src/i18n/locales/{ar-SA.json → ar-SA.ts} +132 -52
- package/src/i18n/locales/{ca-ES.json → ca-ES.ts} +132 -52
- package/{dist/cjs/i18n/locales/locales/de-DE.json → src/i18n/locales/de-DE.ts} +134 -54
- package/src/i18n/locales/{en-US.json → en-US.ts} +161 -245
- package/{dist/cjs/i18n/locales/locales/es-ES.json → src/i18n/locales/es-ES.ts} +161 -245
- package/src/i18n/locales/{fr-FR.json → fr-FR.ts} +132 -52
- package/src/i18n/locales/{it-IT.json → it-IT.ts} +132 -52
- package/{dist/cjs/i18n/locales/locales/ja-JP.json → src/i18n/locales/ja-JP.ts} +132 -52
- package/src/i18n/locales/{ko-KR.json → ko-KR.ts} +132 -52
- package/src/i18n/locales/{pt-PT.json → pt-PT.ts} +134 -54
- package/src/i18n/locales/{zh-CN.json → zh-CN.ts} +133 -53
- package/src/i18n/reputationCategoryLabels.ts +1 -1
- package/src/i18n/trustTierLabels.ts +1 -1
- package/src/index.ts +170 -501
- package/src/inference/index.ts +48 -0
- package/src/models/interfaces.ts +1 -22
- package/src/server/OxyServer.ts +637 -0
- package/src/server/auth.ts +12 -8
- package/src/server/index.ts +28 -5
- package/src/server/middleware.ts +1520 -0
- package/src/server/namespaces.ts +257 -0
- package/src/server/rateLimit.ts +10 -9
- package/src/server/requesterAssertion.ts +13 -10
- package/src/server/securityHeaders.ts +7 -8
- package/src/server/traffic.ts +6 -6
- package/src/server/trafficNodeHttp.ts +7 -3
- package/src/server/userInvalidation.ts +9 -9
- package/src/session/accountDelegationAccess.ts +1 -1
- package/src/session/accountDialogController.ts +24 -24
- package/src/session/accountSwitchTargets.ts +1 -1
- package/src/session/authStateStore.ts +9 -8
- package/src/session/identitySession.ts +3 -3
- package/src/session/index.ts +210 -0
- package/src/session/refresh.ts +36 -30
- package/src/session/sessionClientHost.ts +5 -5
- package/src/session/sharedDeviceCredential.ts +3 -2
- package/src/shared/utils/networkUtils.ts +2 -2
- package/src/utils/accountCacheSweep.ts +11 -15
- package/src/utils/apiUtils.ts +3 -3
- package/src/utils/asyncUtils.ts +38 -235
- package/src/utils/authHelpers.ts +2 -2
- package/src/utils/authWebUrl.ts +3 -4
- package/src/utils/avatarUtils.ts +4 -7
- package/src/utils/cache.ts +36 -5
- package/src/utils/cacheKey.ts +5 -9
- package/src/utils/commonsApproval.ts +1 -1
- package/src/utils/deviceManager.ts +17 -16
- package/src/utils/edgeRegion.ts +1 -2
- package/src/utils/identityCacheSweep.ts +7 -12
- package/src/utils/oauthPkce.ts +2 -2
- package/src/utils/oxyServiceEnvironment.ts +3 -7
- package/src/utils/requestUtils.ts +48 -44
- package/src/utils/sessionUtils.ts +0 -2
- package/src/utils/tokenClaims.ts +38 -0
- package/dist/cjs/.tsbuildinfo +0 -1
- package/dist/cjs/OxyServices.base.js +0 -392
- package/dist/cjs/i18n/locales/locales/ar-SA.json +0 -306
- package/dist/cjs/i18n/locales/locales/ca-ES.json +0 -306
- package/dist/cjs/i18n/locales/locales/en-US.json +0 -2127
- package/dist/cjs/i18n/locales/locales/fr-FR.json +0 -306
- package/dist/cjs/i18n/locales/locales/it-IT.json +0 -306
- package/dist/cjs/i18n/locales/locales/ko-KR.json +0 -306
- package/dist/cjs/i18n/locales/locales/pt-PT.json +0 -306
- package/dist/cjs/i18n/locales/locales/zh-CN.json +0 -306
- package/dist/cjs/mixins/OxyServices.accounts.js +0 -555
- package/dist/cjs/mixins/OxyServices.agency.js +0 -154
- package/dist/cjs/mixins/OxyServices.analytics.js +0 -49
- package/dist/cjs/mixins/OxyServices.appData.js +0 -108
- package/dist/cjs/mixins/OxyServices.assets.js +0 -854
- package/dist/cjs/mixins/OxyServices.auth.js +0 -1495
- package/dist/cjs/mixins/OxyServices.chains.js +0 -73
- package/dist/cjs/mixins/OxyServices.civic.js +0 -611
- package/dist/cjs/mixins/OxyServices.connectedApps.js +0 -95
- package/dist/cjs/mixins/OxyServices.contacts.js +0 -50
- package/dist/cjs/mixins/OxyServices.deviceBoot.js +0 -191
- package/dist/cjs/mixins/OxyServices.devices.js +0 -116
- package/dist/cjs/mixins/OxyServices.features.js +0 -335
- package/dist/cjs/mixins/OxyServices.followGraph.js +0 -221
- package/dist/cjs/mixins/OxyServices.identity.js +0 -562
- package/dist/cjs/mixins/OxyServices.identityBackup.js +0 -172
- package/dist/cjs/mixins/OxyServices.inference.js +0 -59
- package/dist/cjs/mixins/OxyServices.language.js +0 -125
- package/dist/cjs/mixins/OxyServices.linkedAccounts.js +0 -79
- package/dist/cjs/mixins/OxyServices.location.js +0 -43
- package/dist/cjs/mixins/OxyServices.nodes.js +0 -175
- package/dist/cjs/mixins/OxyServices.notifications.js +0 -63
- package/dist/cjs/mixins/OxyServices.payment.js +0 -158
- package/dist/cjs/mixins/OxyServices.privacy.js +0 -199
- package/dist/cjs/mixins/OxyServices.reputation.js +0 -289
- package/dist/cjs/mixins/OxyServices.security.js +0 -89
- package/dist/cjs/mixins/OxyServices.store.js +0 -266
- package/dist/cjs/mixins/OxyServices.topics.js +0 -137
- package/dist/cjs/mixins/OxyServices.user.js +0 -954
- package/dist/cjs/mixins/OxyServices.utility.js +0 -1402
- package/dist/cjs/mixins/index.js +0 -136
- package/dist/cjs/mixins/mixinHelpers.js +0 -53
- package/dist/cjs/utils/webauthnOrigin.js +0 -51
- package/dist/esm/.tsbuildinfo +0 -1
- package/dist/esm/OxyServices.base.js +0 -388
- package/dist/esm/i18n/locales/locales/ar-SA.json +0 -306
- package/dist/esm/i18n/locales/locales/ca-ES.json +0 -306
- package/dist/esm/i18n/locales/locales/de-DE.json +0 -306
- package/dist/esm/i18n/locales/locales/en-US.json +0 -2127
- package/dist/esm/i18n/locales/locales/es-ES.json +0 -2127
- package/dist/esm/i18n/locales/locales/fr-FR.json +0 -306
- package/dist/esm/i18n/locales/locales/it-IT.json +0 -306
- package/dist/esm/i18n/locales/locales/ja-JP.json +0 -306
- package/dist/esm/i18n/locales/locales/ko-KR.json +0 -306
- package/dist/esm/i18n/locales/locales/pt-PT.json +0 -306
- package/dist/esm/i18n/locales/locales/zh-CN.json +0 -306
- package/dist/esm/mixins/OxyServices.accounts.js +0 -543
- package/dist/esm/mixins/OxyServices.agency.js +0 -151
- package/dist/esm/mixins/OxyServices.analytics.js +0 -46
- package/dist/esm/mixins/OxyServices.appData.js +0 -103
- package/dist/esm/mixins/OxyServices.assets.js +0 -851
- package/dist/esm/mixins/OxyServices.auth.js +0 -1455
- package/dist/esm/mixins/OxyServices.chains.js +0 -70
- package/dist/esm/mixins/OxyServices.civic.js +0 -605
- package/dist/esm/mixins/OxyServices.connectedApps.js +0 -92
- package/dist/esm/mixins/OxyServices.contacts.js +0 -47
- package/dist/esm/mixins/OxyServices.deviceBoot.js +0 -186
- package/dist/esm/mixins/OxyServices.devices.js +0 -113
- package/dist/esm/mixins/OxyServices.features.js +0 -332
- package/dist/esm/mixins/OxyServices.followGraph.js +0 -218
- package/dist/esm/mixins/OxyServices.identity.js +0 -558
- package/dist/esm/mixins/OxyServices.identityBackup.js +0 -169
- package/dist/esm/mixins/OxyServices.inference.js +0 -56
- package/dist/esm/mixins/OxyServices.language.js +0 -122
- package/dist/esm/mixins/OxyServices.linkedAccounts.js +0 -76
- package/dist/esm/mixins/OxyServices.location.js +0 -40
- package/dist/esm/mixins/OxyServices.nodes.js +0 -172
- package/dist/esm/mixins/OxyServices.notifications.js +0 -60
- package/dist/esm/mixins/OxyServices.payment.js +0 -155
- package/dist/esm/mixins/OxyServices.privacy.js +0 -196
- package/dist/esm/mixins/OxyServices.reputation.js +0 -286
- package/dist/esm/mixins/OxyServices.security.js +0 -86
- package/dist/esm/mixins/OxyServices.store.js +0 -263
- package/dist/esm/mixins/OxyServices.topics.js +0 -134
- package/dist/esm/mixins/OxyServices.user.js +0 -951
- package/dist/esm/mixins/OxyServices.utility.js +0 -1397
- package/dist/esm/mixins/index.js +0 -133
- package/dist/esm/mixins/mixinHelpers.js +0 -48
- package/dist/esm/utils/webauthnOrigin.js +0 -48
- package/dist/types/.tsbuildinfo +0 -1
- package/dist/types/OxyServices.base.d.ts +0 -189
- package/dist/types/mixins/OxyServices.accounts.d.ts +0 -868
- package/dist/types/mixins/OxyServices.agency.d.ts +0 -176
- package/dist/types/mixins/OxyServices.analytics.d.ts +0 -72
- package/dist/types/mixins/OxyServices.appData.d.ts +0 -108
- package/dist/types/mixins/OxyServices.assets.d.ts +0 -371
- package/dist/types/mixins/OxyServices.auth.d.ts +0 -998
- package/dist/types/mixins/OxyServices.chains.d.ts +0 -156
- package/dist/types/mixins/OxyServices.civic.d.ts +0 -520
- package/dist/types/mixins/OxyServices.connectedApps.d.ts +0 -184
- package/dist/types/mixins/OxyServices.contacts.d.ts +0 -100
- package/dist/types/mixins/OxyServices.deviceBoot.d.ts +0 -185
- package/dist/types/mixins/OxyServices.devices.d.ts +0 -103
- package/dist/types/mixins/OxyServices.features.d.ts +0 -250
- package/dist/types/mixins/OxyServices.followGraph.d.ts +0 -223
- package/dist/types/mixins/OxyServices.identity.d.ts +0 -337
- package/dist/types/mixins/OxyServices.identityBackup.d.ts +0 -129
- package/dist/types/mixins/OxyServices.inference.d.ts +0 -95
- package/dist/types/mixins/OxyServices.language.d.ts +0 -87
- package/dist/types/mixins/OxyServices.linkedAccounts.d.ts +0 -107
- package/dist/types/mixins/OxyServices.location.d.ts +0 -70
- package/dist/types/mixins/OxyServices.nodes.d.ts +0 -198
- package/dist/types/mixins/OxyServices.notifications.d.ts +0 -143
- package/dist/types/mixins/OxyServices.payment.d.ts +0 -117
- package/dist/types/mixins/OxyServices.privacy.d.ts +0 -146
- package/dist/types/mixins/OxyServices.reputation.d.ts +0 -202
- package/dist/types/mixins/OxyServices.security.d.ts +0 -84
- package/dist/types/mixins/OxyServices.store.d.ts +0 -334
- package/dist/types/mixins/OxyServices.topics.d.ts +0 -110
- package/dist/types/mixins/OxyServices.user.d.ts +0 -600
- package/dist/types/mixins/OxyServices.utility.d.ts +0 -526
- package/dist/types/mixins/index.d.ts +0 -87
- package/dist/types/mixins/mixinHelpers.d.ts +0 -31
- package/dist/types/utils/webauthnOrigin.d.ts +0 -32
- package/src/OxyServices.base.ts +0 -480
- package/src/__tests__/authSocket.test.ts +0 -96
- package/src/__tests__/fixEsmImports.test.ts +0 -132
- package/src/__tests__/httpServiceAbort.test.ts +0 -308
- package/src/__tests__/httpServiceActivityId.test.ts +0 -49
- package/src/__tests__/httpServiceAuthSelfAwait.test.ts +0 -108
- package/src/__tests__/httpServiceCache.test.ts +0 -318
- package/src/__tests__/httpServiceFormEncoded.test.ts +0 -139
- package/src/__tests__/httpServiceQueueDeadlock.test.ts +0 -128
- package/src/__tests__/httpServiceRateLimitedRefresh.test.ts +0 -160
- package/src/__tests__/httpServiceUnwrapEnvelope.test.ts +0 -115
- package/src/__tests__/httpServiceWrites.test.ts +0 -175
- package/src/__tests__/inSessionRefresh.test.ts +0 -313
- package/src/__tests__/linkedClient.test.ts +0 -363
- package/src/__tests__/nearExpiryMintStorm.test.ts +0 -165
- package/src/__tests__/parseHttpErrorBody.test.ts +0 -116
- package/src/__tests__/publicInterfaceParity.test.ts +0 -75
- package/src/__tests__/serverValueImportsDeclared.test.ts +0 -120
- package/src/__tests__/serviceIdentityWhenAnonymous.test.ts +0 -159
- package/src/__tests__/serviceTokenWorkloadFallback.test.ts +0 -85
- package/src/__tests__/userIdentity.test.ts +0 -143
- package/src/boot/__tests__/sessionColdBoot.identity.test.ts +0 -393
- package/src/boot/__tests__/sessionColdBoot.sharedDevice.test.ts +0 -325
- package/src/boot/__tests__/sessionColdBoot.test.ts +0 -570
- package/src/crypto/__tests__/backupMaterial.test.ts +0 -86
- package/src/crypto/__tests__/cryptoPrimitives.test.ts +0 -226
- package/src/crypto/__tests__/identityLink.test.ts +0 -18
- package/src/crypto/__tests__/identityMocks.ts +0 -125
- package/src/crypto/__tests__/identityProof.test.ts +0 -81
- package/src/crypto/__tests__/keyManager.atomicity.test.ts +0 -272
- package/src/crypto/__tests__/keyManager.cacheSafety.test.ts +0 -175
- package/src/crypto/__tests__/keyManager.deviceBackup.test.ts +0 -310
- package/src/crypto/__tests__/keyManager.identityStatus.test.ts +0 -217
- package/src/crypto/__tests__/keyManager.recoveryLadder.test.ts +0 -179
- package/src/crypto/__tests__/keyManager.recoveryMnemonic.test.ts +0 -138
- package/src/crypto/__tests__/keyManager.sharedSlotSync.test.ts +0 -150
- package/src/crypto/__tests__/keyManager.storageMigration.test.ts +0 -227
- package/src/crypto/__tests__/keyManager.test.ts +0 -329
- package/src/crypto/__tests__/polyfill.test.ts +0 -109
- package/src/crypto/__tests__/polyfillOrder.test.ts +0 -114
- package/src/crypto/__tests__/recoveryPhrase.test.ts +0 -61
- package/src/crypto/__tests__/registrationPow.test.ts +0 -61
- package/src/crypto/__tests__/scopedSeed.test.ts +0 -126
- package/src/crypto/__tests__/signChallengeShared.test.ts +0 -63
- package/src/crypto/__tests__/signedRecord.test.ts +0 -230
- package/src/i18n/__tests__/accountCategoryLabels.test.ts +0 -62
- package/src/i18n/__tests__/accountRoleLabels.test.ts +0 -54
- package/src/i18n/__tests__/reputationCategoryLabels.test.ts +0 -56
- package/src/i18n/__tests__/trustTierLabels.test.ts +0 -47
- package/src/i18n/locales/de-DE.json +0 -306
- package/src/i18n/locales/es-ES.json +0 -2127
- package/src/i18n/locales/ja-JP.json +0 -306
- package/src/inference/__tests__/OxyInferenceClient.test.ts +0 -899
- package/src/logger/__tests__/logger.test.ts +0 -207
- package/src/mixins/OxyServices.accounts.ts +0 -1330
- package/src/mixins/OxyServices.agency.ts +0 -353
- package/src/mixins/OxyServices.analytics.ts +0 -53
- package/src/mixins/OxyServices.appData.ts +0 -158
- package/src/mixins/OxyServices.assets.ts +0 -964
- package/src/mixins/OxyServices.auth.ts +0 -2083
- package/src/mixins/OxyServices.chains.ts +0 -134
- package/src/mixins/OxyServices.civic.ts +0 -945
- package/src/mixins/OxyServices.connectedApps.ts +0 -212
- package/src/mixins/OxyServices.contacts.ts +0 -73
- package/src/mixins/OxyServices.devices.ts +0 -120
- package/src/mixins/OxyServices.features.ts +0 -454
- package/src/mixins/OxyServices.followGraph.ts +0 -293
- package/src/mixins/OxyServices.identity.ts +0 -787
- package/src/mixins/OxyServices.identityBackup.ts +0 -250
- package/src/mixins/OxyServices.inference.ts +0 -57
- package/src/mixins/OxyServices.language.ts +0 -144
- package/src/mixins/OxyServices.linkedAccounts.ts +0 -129
- package/src/mixins/OxyServices.location.ts +0 -46
- package/src/mixins/OxyServices.nodes.ts +0 -337
- package/src/mixins/OxyServices.notifications.ts +0 -142
- package/src/mixins/OxyServices.payment.ts +0 -163
- package/src/mixins/OxyServices.privacy.ts +0 -219
- package/src/mixins/OxyServices.reputation.ts +0 -436
- package/src/mixins/OxyServices.security.ts +0 -110
- package/src/mixins/OxyServices.store.ts +0 -585
- package/src/mixins/OxyServices.topics.ts +0 -169
- package/src/mixins/OxyServices.user.ts +0 -1208
- package/src/mixins/OxyServices.utility.ts +0 -1803
- package/src/mixins/__tests__/OxyServices.civic.test.ts +0 -1095
- package/src/mixins/__tests__/OxyServices.deviceBoot.test.ts +0 -124
- package/src/mixins/__tests__/OxyServices.identity.test.ts +0 -301
- package/src/mixins/__tests__/OxyServices.nodes.test.ts +0 -341
- package/src/mixins/__tests__/OxyServices.rotateKey.test.ts +0 -323
- package/src/mixins/__tests__/OxyServices.serviceAssetMetadata.test.ts +0 -192
- package/src/mixins/__tests__/OxyServices.serviceAssetMetadataBySha.test.ts +0 -135
- package/src/mixins/__tests__/OxyServices.serviceLinkedDownloadUrl.test.ts +0 -139
- package/src/mixins/__tests__/accountEvents.test.ts +0 -158
- package/src/mixins/__tests__/accounts.test.ts +0 -727
- package/src/mixins/__tests__/agency.test.ts +0 -120
- package/src/mixins/__tests__/appData.test.ts +0 -203
- package/src/mixins/__tests__/assetCredentials.test.ts +0 -47
- package/src/mixins/__tests__/assetUpload.test.ts +0 -191
- package/src/mixins/__tests__/authRefusalObservability.test.ts +0 -396
- package/src/mixins/__tests__/backgroundCredential.httpIntegration.test.ts +0 -130
- package/src/mixins/__tests__/chains.test.ts +0 -113
- package/src/mixins/__tests__/commonsSignIn.test.ts +0 -1147
- package/src/mixins/__tests__/connectedApps.test.ts +0 -146
- package/src/mixins/__tests__/deviceTokenMintPinned.test.ts +0 -113
- package/src/mixins/__tests__/discoveryErrorHandling.test.ts +0 -265
- package/src/mixins/__tests__/followCacheInvalidation.test.ts +0 -173
- package/src/mixins/__tests__/followGraph.test.ts +0 -147
- package/src/mixins/__tests__/followGraphPagination.test.ts +0 -271
- package/src/mixins/__tests__/getFileDownloadUrl.test.ts +0 -346
- package/src/mixins/__tests__/getFollowStatuses.test.ts +0 -95
- package/src/mixins/__tests__/getUsersByIds.test.ts +0 -176
- package/src/mixins/__tests__/identityBackup.test.ts +0 -315
- package/src/mixins/__tests__/identityLink.test.ts +0 -89
- package/src/mixins/__tests__/identityWriteCacheInvalidation.test.ts +0 -407
- package/src/mixins/__tests__/inferenceFactory.test.ts +0 -58
- package/src/mixins/__tests__/linkedAccounts.test.ts +0 -109
- package/src/mixins/__tests__/notifications.read.test.ts +0 -82
- package/src/mixins/__tests__/onTokensChanged.test.ts +0 -129
- package/src/mixins/__tests__/preSessionSkipAuth.test.ts +0 -284
- package/src/mixins/__tests__/privacyCacheInvalidation.test.ts +0 -155
- package/src/mixins/__tests__/reputation.test.ts +0 -522
- package/src/mixins/__tests__/serviceAuth.test.ts +0 -889
- package/src/mixins/__tests__/serviceTokenJwks.test.ts +0 -208
- package/src/mixins/__tests__/store.test.ts +0 -304
- package/src/mixins/__tests__/topics.test.ts +0 -155
- package/src/mixins/__tests__/userReadCacheBypass.test.ts +0 -129
- package/src/mixins/__tests__/userTokenAuth.test.ts +0 -746
- package/src/mixins/__tests__/verifyChallenge.test.ts +0 -161
- package/src/mixins/__tests__/verifyServiceActingAs.test.ts +0 -167
- package/src/mixins/__tests__/webauthnAuth.test.ts +0 -279
- package/src/mixins/index.ts +0 -203
- package/src/mixins/mixinHelpers.ts +0 -69
- package/src/server/__tests__/auth.test.ts +0 -78
- package/src/server/__tests__/capabilityTicket.test.ts +0 -111
- package/src/server/__tests__/cors.socket.test.ts +0 -225
- package/src/server/__tests__/cors.test.ts +0 -158
- package/src/server/__tests__/rateLimit.test.ts +0 -257
- package/src/server/__tests__/requesterAssertion.test.ts +0 -359
- package/src/server/__tests__/safeFetch.test.ts +0 -232
- package/src/server/__tests__/securityHeaders.test.ts +0 -387
- package/src/server/__tests__/serviceTokenAttribution.test.ts +0 -396
- package/src/server/__tests__/traffic.test.ts +0 -180
- package/src/server/__tests__/trafficNodeHttp.test.ts +0 -38
- package/src/server/__tests__/userInvalidation.test.ts +0 -203
- package/src/server/__tests__/verifySecret.test.ts +0 -40
- package/src/server/__tests__/workloadIdentity.client.test.ts +0 -16
- package/src/server/__tests__/workloadIdentity.test.ts +0 -128
- package/src/session/__tests__/SessionClient.additive.test.ts +0 -153
- package/src/session/__tests__/SessionClient.broadcastChannel.test.ts +0 -114
- package/src/session/__tests__/SessionClient.diagnostics.test.ts +0 -91
- package/src/session/__tests__/SessionClient.directory.test.ts +0 -688
- package/src/session/__tests__/SessionClient.httpIntegration.test.ts +0 -65
- package/src/session/__tests__/SessionClient.identityPin.test.ts +0 -175
- package/src/session/__tests__/SessionClient.rest.test.ts +0 -119
- package/src/session/__tests__/SessionClient.serverEvents.test.ts +0 -72
- package/src/session/__tests__/SessionClient.socket.test.ts +0 -202
- package/src/session/__tests__/SessionClient.socketFactory.test.ts +0 -81
- package/src/session/__tests__/SessionClient.state.test.ts +0 -78
- package/src/session/__tests__/SessionClient.switchTokenOrder.test.ts +0 -170
- package/src/session/__tests__/accountDelegationAccess.test.ts +0 -104
- package/src/session/__tests__/accountDialogController.test.ts +0 -2502
- package/src/session/__tests__/accountDialogShape.test.ts +0 -120
- package/src/session/__tests__/accountSwitchTargets.test.ts +0 -137
- package/src/session/__tests__/authStateStore.test.ts +0 -451
- package/src/session/__tests__/deviceDirectory.test.ts +0 -422
- package/src/session/__tests__/deviceSwitcherRows.test.ts +0 -223
- package/src/session/__tests__/identityPin.test.ts +0 -131
- package/src/session/__tests__/identitySession.test.ts +0 -194
- package/src/session/__tests__/projectSessionState.test.ts +0 -105
- package/src/session/__tests__/refresh.identityPin.test.ts +0 -307
- package/src/session/__tests__/refresh.test.ts +0 -606
- package/src/session/__tests__/sessionIntegration.test.ts +0 -209
- package/src/session/__tests__/sharedDeviceCredential.test.ts +0 -300
- package/src/utils/__tests__/accountUtils.test.ts +0 -151
- package/src/utils/__tests__/activityId.test.ts +0 -45
- package/src/utils/__tests__/asyncUtils.test.ts +0 -279
- package/src/utils/__tests__/authWebUrl.test.ts +0 -15
- package/src/utils/__tests__/cacheKey.test.ts +0 -0
- package/src/utils/__tests__/cacheLifecycle.test.ts +0 -65
- package/src/utils/__tests__/coldBoot.test.ts +0 -496
- package/src/utils/__tests__/commonsApproval.test.ts +0 -60
- package/src/utils/__tests__/identityCacheSweep.test.ts +0 -151
- package/src/utils/__tests__/languageUtils.test.ts +0 -244
- package/src/utils/__tests__/oauthPkce.test.ts +0 -303
- package/src/utils/__tests__/officialOrigins.test.ts +0 -31
- package/src/utils/__tests__/oxyServiceEnvironment.test.ts +0 -7
- package/src/utils/__tests__/profileLinks.test.ts +0 -180
- package/src/utils/__tests__/redactUrl.test.ts +0 -33
- package/src/utils/__tests__/registrableApex.test.ts +0 -62
- package/src/utils/__tests__/requestUtilsAbort.test.ts +0 -155
- package/src/utils/__tests__/textNormalization.test.ts +0 -205
- package/src/utils/__tests__/validationUtils.test.ts +0 -703
- package/src/utils/__tests__/webauthnOrigin.test.ts +0 -83
- package/src/utils/webauthnOrigin.ts +0 -52
|
@@ -1,160 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* The post-429 refresh cooldown.
|
|
3
|
-
*
|
|
4
|
-
* `POST /session/device/token` is budgeted at 30 mints/minute
|
|
5
|
-
* (`packages/api/src/routes/sessionDevice.ts`). Once the access token is
|
|
6
|
-
* EXPIRED, the request-driven refresh lanes — the request-time preflight in
|
|
7
|
-
* `getAuthHeader` and the 401 retry — reattempt on
|
|
8
|
-
* `EXPIRED_TOKEN_REFRESH_COOLDOWN_MS`, i.e. one mint per second, 60/min. That
|
|
9
|
-
* is correct against an unreachable server (recover the instant it returns) and
|
|
10
|
-
* exactly wrong against a rationing one: the retries spend the very budget they
|
|
11
|
-
* are waiting on, so the limiter stays tripped for as long as the app keeps
|
|
12
|
-
* issuing requests and the session can never heal itself.
|
|
13
|
-
*
|
|
14
|
-
* These tests pin the discrimination: a 429 lengthens the NEXT cooldown to the
|
|
15
|
-
* limiter's own window, every other failure keeps the token-state cooldowns, and
|
|
16
|
-
* a success clears it.
|
|
17
|
-
*
|
|
18
|
-
* `Date.now` is stubbed rather than using fake timers: the cooldown is a pure
|
|
19
|
-
* comparison against a stored epoch, so moving the clock is the whole
|
|
20
|
-
* experiment, and real microtasks keep the refresh promises resolving normally.
|
|
21
|
-
*/
|
|
22
|
-
import { HttpService } from '../HttpService';
|
|
23
|
-
|
|
24
|
-
function createJwt(payload: Record<string, unknown>): string {
|
|
25
|
-
const encode = (value: unknown): string => Buffer.from(JSON.stringify(value)).toString('base64url');
|
|
26
|
-
return `${encode({ alg: 'HS256', typ: 'JWT' })}.${encode(payload)}.signature`;
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
/** The server's mint budget window — the interval the fix must wait out. */
|
|
30
|
-
const LIMITER_WINDOW_MS = 60_000;
|
|
31
|
-
|
|
32
|
-
/** Comfortably past the expired-token cooldown (1s) but inside the 429 window. */
|
|
33
|
-
const BETWEEN_COOLDOWNS_MS = 30_000;
|
|
34
|
-
|
|
35
|
-
describe('HttpService — refresh cooldown after a rate-limited mint', () => {
|
|
36
|
-
let clock = 1_700_000_000_000;
|
|
37
|
-
|
|
38
|
-
beforeEach(() => {
|
|
39
|
-
clock = 1_700_000_000_000;
|
|
40
|
-
jest.spyOn(Date, 'now').mockImplementation(() => clock);
|
|
41
|
-
});
|
|
42
|
-
|
|
43
|
-
afterEach(() => {
|
|
44
|
-
jest.restoreAllMocks();
|
|
45
|
-
});
|
|
46
|
-
|
|
47
|
-
/** A client whose CURRENT access token is already past `exp`. */
|
|
48
|
-
function expiredTokenClient(): HttpService {
|
|
49
|
-
const http = new HttpService({ baseURL: 'https://api.oxy.so', enableRetry: false });
|
|
50
|
-
http.setTokens(createJwt({ userId: 'u', exp: Math.floor(clock / 1000) - 60 }));
|
|
51
|
-
return http;
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
it('retries an expired token ~1s after an ORDINARY failure (the unreachable-server lane is untouched)', async () => {
|
|
55
|
-
const http = expiredTokenClient();
|
|
56
|
-
const handler = jest.fn(async () => null);
|
|
57
|
-
http.setAuthRefreshHandler(handler);
|
|
58
|
-
|
|
59
|
-
expect(await http.refreshAccessToken('preflight')).toBeNull();
|
|
60
|
-
expect(handler).toHaveBeenCalledTimes(1);
|
|
61
|
-
|
|
62
|
-
clock += 1_001;
|
|
63
|
-
expect(await http.refreshAccessToken('preflight')).toBeNull();
|
|
64
|
-
expect(handler).toHaveBeenCalledTimes(2);
|
|
65
|
-
});
|
|
66
|
-
|
|
67
|
-
it('suppresses the retry for the limiter window after a 429, instead of hammering once a second', async () => {
|
|
68
|
-
const http = expiredTokenClient();
|
|
69
|
-
const handler = jest.fn(async () => {
|
|
70
|
-
// What `refreshDeviceSecretArm` does when the mint answers 429.
|
|
71
|
-
http.noteRefreshRateLimited();
|
|
72
|
-
return null;
|
|
73
|
-
});
|
|
74
|
-
http.setAuthRefreshHandler(handler);
|
|
75
|
-
|
|
76
|
-
expect(await http.refreshAccessToken('preflight')).toBeNull();
|
|
77
|
-
expect(handler).toHaveBeenCalledTimes(1);
|
|
78
|
-
|
|
79
|
-
// Past the expired-token cooldown. Without the 429 discrimination this is
|
|
80
|
-
// where the client resumes one mint per second and holds the limiter down.
|
|
81
|
-
clock += BETWEEN_COOLDOWNS_MS;
|
|
82
|
-
expect(await http.refreshAccessToken('preflight')).toBeNull();
|
|
83
|
-
expect(handler).toHaveBeenCalledTimes(1);
|
|
84
|
-
|
|
85
|
-
// Once the limiter's window has drained, exactly one probe goes out.
|
|
86
|
-
clock += LIMITER_WINDOW_MS;
|
|
87
|
-
expect(await http.refreshAccessToken('preflight')).toBeNull();
|
|
88
|
-
expect(handler).toHaveBeenCalledTimes(2);
|
|
89
|
-
});
|
|
90
|
-
|
|
91
|
-
it('holds a rate-limited client under the mint budget while requests keep arriving', async () => {
|
|
92
|
-
const http = expiredTokenClient();
|
|
93
|
-
const handler = jest.fn(async () => {
|
|
94
|
-
http.noteRefreshRateLimited();
|
|
95
|
-
return null;
|
|
96
|
-
});
|
|
97
|
-
http.setAuthRefreshHandler(handler);
|
|
98
|
-
|
|
99
|
-
// One simulated minute of a busy app: a request every 250ms, each one
|
|
100
|
-
// driving the preflight/401 refresh lane.
|
|
101
|
-
for (let elapsed = 0; elapsed < 60_000; elapsed += 250) {
|
|
102
|
-
await http.refreshAccessToken('preflight');
|
|
103
|
-
clock += 250;
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
// The server's budget is 30/min. The unfixed client issues 60.
|
|
107
|
-
expect(handler.mock.calls.length).toBeLessThanOrEqual(2);
|
|
108
|
-
});
|
|
109
|
-
|
|
110
|
-
it('clears the lengthened cooldown once a refresh succeeds', async () => {
|
|
111
|
-
const http = expiredTokenClient();
|
|
112
|
-
const fresh = createJwt({ userId: 'u', exp: Math.floor(clock / 1000) + 900 });
|
|
113
|
-
const handler = jest
|
|
114
|
-
.fn<Promise<string | null>, []>()
|
|
115
|
-
.mockImplementationOnce(async () => {
|
|
116
|
-
http.noteRefreshRateLimited();
|
|
117
|
-
return null;
|
|
118
|
-
})
|
|
119
|
-
.mockImplementationOnce(async () => fresh)
|
|
120
|
-
// A later ordinary failure must be back on the short cooldown, proving the
|
|
121
|
-
// 429 state did not become sticky.
|
|
122
|
-
.mockImplementation(async () => null);
|
|
123
|
-
http.setAuthRefreshHandler(handler);
|
|
124
|
-
|
|
125
|
-
await http.refreshAccessToken('preflight');
|
|
126
|
-
clock += LIMITER_WINDOW_MS + 1;
|
|
127
|
-
expect(await http.refreshAccessToken('preflight')).toBe(fresh);
|
|
128
|
-
|
|
129
|
-
// The planted token is fresh, so this is the still-valid (15s) cooldown.
|
|
130
|
-
clock += 16_000;
|
|
131
|
-
await http.refreshAccessToken('preflight');
|
|
132
|
-
expect(handler).toHaveBeenCalledTimes(3);
|
|
133
|
-
|
|
134
|
-
clock += 16_000;
|
|
135
|
-
await http.refreshAccessToken('preflight');
|
|
136
|
-
expect(handler).toHaveBeenCalledTimes(4);
|
|
137
|
-
});
|
|
138
|
-
|
|
139
|
-
it('returns to the short cooldown when a later failure is NOT a 429', async () => {
|
|
140
|
-
const http = expiredTokenClient();
|
|
141
|
-
const handler = jest
|
|
142
|
-
.fn<Promise<string | null>, []>()
|
|
143
|
-
.mockImplementationOnce(async () => {
|
|
144
|
-
http.noteRefreshRateLimited();
|
|
145
|
-
return null;
|
|
146
|
-
})
|
|
147
|
-
// The limiter window passed and the endpoint is merely erroring now.
|
|
148
|
-
.mockImplementation(async () => null);
|
|
149
|
-
http.setAuthRefreshHandler(handler);
|
|
150
|
-
|
|
151
|
-
await http.refreshAccessToken('preflight');
|
|
152
|
-
clock += LIMITER_WINDOW_MS + 1;
|
|
153
|
-
await http.refreshAccessToken('preflight');
|
|
154
|
-
expect(handler).toHaveBeenCalledTimes(2);
|
|
155
|
-
|
|
156
|
-
clock += 1_001;
|
|
157
|
-
await http.refreshAccessToken('preflight');
|
|
158
|
-
expect(handler).toHaveBeenCalledTimes(3);
|
|
159
|
-
});
|
|
160
|
-
});
|
|
@@ -1,115 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* `HttpService.unwrapResponse` envelope tests — driven through the REAL class
|
|
3
|
-
* against a stubbed `fetch`, never by calling the private method.
|
|
4
|
-
*
|
|
5
|
-
* The convenience unwrap reduces the house `{ data: <payload> }` envelope to its
|
|
6
|
-
* payload, and in doing so it discards every sibling key. That silently killed
|
|
7
|
-
* pagination on the account audit trails (`GET /accounts/:id/audit` and
|
|
8
|
-
* `GET /accounts/:id/billing/audit`, which answer `{ data, count, nextCursor }`):
|
|
9
|
-
* the caller got a bare array, `getNextPageParam` read `undefined`, and there was
|
|
10
|
-
* nothing at the call site to show that page 2 could never be requested.
|
|
11
|
-
*
|
|
12
|
-
* The three cases below are the whole contract, and each is load-bearing:
|
|
13
|
-
*
|
|
14
|
-
* - a cursor page travels WHOLE (the regression),
|
|
15
|
-
* - a `{ data, pagination }` page still travels whole (the behaviour that
|
|
16
|
-
* already existed — the positive control for "pages are preserved"),
|
|
17
|
-
* - a bare `{ data }` body still unwraps (the control proving the convenience
|
|
18
|
-
* every other call site depends on is intact).
|
|
19
|
-
*
|
|
20
|
-
* Reverting the fix must redden the first and leave the other two green.
|
|
21
|
-
*/
|
|
22
|
-
|
|
23
|
-
import { HttpService } from '../HttpService';
|
|
24
|
-
|
|
25
|
-
/** One entry of an audit page — only the shape matters here. */
|
|
26
|
-
const ENTRY = { source: 'application_credential', eventType: 'created' } as const;
|
|
27
|
-
|
|
28
|
-
function jsonBody(body: unknown): Response {
|
|
29
|
-
return new Response(JSON.stringify(body), {
|
|
30
|
-
status: 200,
|
|
31
|
-
headers: { 'content-type': 'application/json' },
|
|
32
|
-
});
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
describe('HttpService response-envelope unwrapping', () => {
|
|
36
|
-
const originalFetch = globalThis.fetch;
|
|
37
|
-
|
|
38
|
-
afterEach(() => {
|
|
39
|
-
globalThis.fetch = originalFetch;
|
|
40
|
-
});
|
|
41
|
-
|
|
42
|
-
/** Drive a real `HttpService.get` against a stubbed wire body. */
|
|
43
|
-
async function fetchWireBody<T>(body: unknown): Promise<T> {
|
|
44
|
-
globalThis.fetch = jest.fn(async () => jsonBody(body)) as unknown as typeof fetch;
|
|
45
|
-
const http = new HttpService({ baseURL: 'http://api.test.invalid' });
|
|
46
|
-
return http.get<T>('/accounts/acct-1/audit', { cache: false });
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
it('preserves a cursor page whole — `count` and `nextCursor` reach the caller', async () => {
|
|
50
|
-
const wire = { data: [ENTRY], count: 1, nextCursor: 'CURSOR-XYZ' };
|
|
51
|
-
|
|
52
|
-
const page = await fetchWireBody<typeof wire>(wire);
|
|
53
|
-
|
|
54
|
-
expect(page).toEqual(wire);
|
|
55
|
-
// The cursor is the only thing that says where page 2 starts. Asserted on
|
|
56
|
-
// its own because `toEqual` above would also pass a body that merely
|
|
57
|
-
// happened to be an array of one entry.
|
|
58
|
-
expect(page.nextCursor).toBe('CURSOR-XYZ');
|
|
59
|
-
expect(page.count).toBe(1);
|
|
60
|
-
expect(page.data).toEqual([ENTRY]);
|
|
61
|
-
});
|
|
62
|
-
|
|
63
|
-
it('preserves the LAST cursor page, where `nextCursor` is null', async () => {
|
|
64
|
-
// The recognition is by key presence, not truthiness: if the envelope
|
|
65
|
-
// collapsed into a bare array exactly when the stream ended, every caller
|
|
66
|
-
// would crash on the final page instead of finishing.
|
|
67
|
-
const wire = { data: [ENTRY], count: 1, nextCursor: null };
|
|
68
|
-
|
|
69
|
-
const page = await fetchWireBody<typeof wire>(wire);
|
|
70
|
-
|
|
71
|
-
expect(page).toEqual(wire);
|
|
72
|
-
expect(page.nextCursor).toBeNull();
|
|
73
|
-
});
|
|
74
|
-
|
|
75
|
-
it('preserves the offset-paginated `{ data, pagination }` envelope (control)', async () => {
|
|
76
|
-
const wire = {
|
|
77
|
-
data: [ENTRY],
|
|
78
|
-
pagination: { total: 1, limit: 50, offset: 0, hasMore: false },
|
|
79
|
-
};
|
|
80
|
-
|
|
81
|
-
const page = await fetchWireBody<typeof wire>(wire);
|
|
82
|
-
|
|
83
|
-
expect(page).toEqual(wire);
|
|
84
|
-
});
|
|
85
|
-
|
|
86
|
-
it('still unwraps a bare `{ data }` success envelope to its payload (control)', async () => {
|
|
87
|
-
const payload = { id: 'acct-1', name: 'Acme' };
|
|
88
|
-
|
|
89
|
-
const unwrapped = await fetchWireBody<typeof payload>({ data: payload });
|
|
90
|
-
|
|
91
|
-
expect(unwrapped).toEqual(payload);
|
|
92
|
-
});
|
|
93
|
-
|
|
94
|
-
it('still unwraps `{ data, count }`, which a dozen callers type as the bare payload', async () => {
|
|
95
|
-
// `{ data, count }` is answered by ~15 routes whose Console call sites type
|
|
96
|
-
// the result `Array<T>`. `count` is `data.length` — recoverable — so this
|
|
97
|
-
// envelope deliberately does NOT survive, and widening the rule to "any
|
|
98
|
-
// sibling key" would break every one of those callers at runtime.
|
|
99
|
-
const entries = [ENTRY, ENTRY];
|
|
100
|
-
|
|
101
|
-
const unwrapped = await fetchWireBody<typeof entries>({ data: entries, count: 2 });
|
|
102
|
-
|
|
103
|
-
expect(unwrapped).toEqual(entries);
|
|
104
|
-
});
|
|
105
|
-
|
|
106
|
-
it('passes through a body that has no `data` key at all', async () => {
|
|
107
|
-
// The cursor surfaces already in the SDK (`{ follows, nextCursor }`,
|
|
108
|
-
// `{ records, nextCursor }`) rely on this lane.
|
|
109
|
-
const wire = { follows: [{ relationshipId: 'rel-1' }], nextCursor: 'CURSOR-ABC' };
|
|
110
|
-
|
|
111
|
-
const passed = await fetchWireBody<typeof wire>(wire);
|
|
112
|
-
|
|
113
|
-
expect(passed).toEqual(wire);
|
|
114
|
-
});
|
|
115
|
-
});
|
|
@@ -1,175 +0,0 @@
|
|
|
1
|
-
import { HttpService } from '../HttpService';
|
|
2
|
-
|
|
3
|
-
interface FetchCall {
|
|
4
|
-
url: string;
|
|
5
|
-
init: RequestInit | undefined;
|
|
6
|
-
}
|
|
7
|
-
|
|
8
|
-
function createJwt(payload: Record<string, unknown>): string {
|
|
9
|
-
const encode = (value: unknown): string => Buffer.from(JSON.stringify(value)).toString('base64url');
|
|
10
|
-
return `${encode({ alg: 'HS256', typ: 'JWT' })}.${encode(payload)}.signature`;
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
function jsonResponse(data: unknown): Response {
|
|
14
|
-
return new Response(JSON.stringify({ data }), {
|
|
15
|
-
status: 200,
|
|
16
|
-
headers: { 'content-type': 'application/json' },
|
|
17
|
-
});
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
function readHeaders(init: RequestInit | undefined): Record<string, string> {
|
|
21
|
-
const headers = init?.headers;
|
|
22
|
-
if (!headers) {
|
|
23
|
-
return {};
|
|
24
|
-
}
|
|
25
|
-
if (headers instanceof Headers) {
|
|
26
|
-
return Object.fromEntries(headers.entries());
|
|
27
|
-
}
|
|
28
|
-
if (Array.isArray(headers)) {
|
|
29
|
-
return Object.fromEntries(headers);
|
|
30
|
-
}
|
|
31
|
-
return headers as Record<string, string>;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
/**
|
|
35
|
-
* Writes carry exactly one credential: the bearer, when there is one. Oxy's API
|
|
36
|
-
* has no CSRF layer (issue #1044) and the SDK neither fetches `/csrf-token` nor
|
|
37
|
-
* sends `X-CSRF-Token` / `X-Native-App`, for its own API or a linked one.
|
|
38
|
-
*/
|
|
39
|
-
describe('HttpService writes', () => {
|
|
40
|
-
const originalFetch = globalThis.fetch;
|
|
41
|
-
|
|
42
|
-
afterEach(() => {
|
|
43
|
-
globalThis.fetch = originalFetch;
|
|
44
|
-
jest.restoreAllMocks();
|
|
45
|
-
});
|
|
46
|
-
|
|
47
|
-
function recordFetches(respond: (url: string) => Response = () => jsonResponse({ ok: true })): FetchCall[] {
|
|
48
|
-
const calls: FetchCall[] = [];
|
|
49
|
-
globalThis.fetch = async (input, init) => {
|
|
50
|
-
const url = String(input);
|
|
51
|
-
calls.push({ url, init });
|
|
52
|
-
return respond(url);
|
|
53
|
-
};
|
|
54
|
-
return calls;
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
it('sends a bearer-authenticated write as a single request', async () => {
|
|
58
|
-
const calls = recordFetches();
|
|
59
|
-
|
|
60
|
-
const http = new HttpService({ baseURL: 'https://api.mention.earth', enableRetry: false });
|
|
61
|
-
const accessToken = createJwt({
|
|
62
|
-
userId: 'user_1',
|
|
63
|
-
exp: Math.floor(Date.now() / 1000) + 3600,
|
|
64
|
-
});
|
|
65
|
-
http.setTokens(accessToken);
|
|
66
|
-
|
|
67
|
-
await http.post('/posts', { text: 'hello' });
|
|
68
|
-
|
|
69
|
-
expect(calls.map((call) => call.url)).toEqual(['https://api.mention.earth/posts']);
|
|
70
|
-
const headers = readHeaders(calls[0].init);
|
|
71
|
-
expect(headers.Authorization).toBe(`Bearer ${accessToken}`);
|
|
72
|
-
expect(headers['X-CSRF-Token']).toBeUndefined();
|
|
73
|
-
expect(headers['X-Native-App']).toBeUndefined();
|
|
74
|
-
});
|
|
75
|
-
|
|
76
|
-
it('sends a write without a bearer as a single request with no CSRF preflight', async () => {
|
|
77
|
-
const calls = recordFetches();
|
|
78
|
-
|
|
79
|
-
const http = new HttpService({ baseURL: 'https://api.oxy.so', enableRetry: false });
|
|
80
|
-
|
|
81
|
-
await http.post('/users/by-ids', { ids: ['user_1'] });
|
|
82
|
-
|
|
83
|
-
// POSITIVE CONTROL: the write itself went out, so the absence below is not
|
|
84
|
-
// the absence of any request at all.
|
|
85
|
-
expect(calls.map((call) => call.url)).toEqual(['https://api.oxy.so/users/by-ids']);
|
|
86
|
-
const headers = readHeaders(calls[0].init);
|
|
87
|
-
expect(headers.Authorization).toBeUndefined();
|
|
88
|
-
expect(headers['X-CSRF-Token']).toBeUndefined();
|
|
89
|
-
expect(headers['X-Native-App']).toBeUndefined();
|
|
90
|
-
});
|
|
91
|
-
|
|
92
|
-
it('keeps a valid near-expiry bearer token when preflight refresh cannot refresh', async () => {
|
|
93
|
-
const calls = recordFetches();
|
|
94
|
-
|
|
95
|
-
const http = new HttpService({ baseURL: 'https://api.mention.earth', enableRetry: false });
|
|
96
|
-
const accessToken = createJwt({
|
|
97
|
-
userId: 'user_1',
|
|
98
|
-
exp: Math.floor(Date.now() / 1000) + 30,
|
|
99
|
-
});
|
|
100
|
-
let refreshAttempts = 0;
|
|
101
|
-
http.setTokens(accessToken);
|
|
102
|
-
http.setAuthRefreshHandler(async () => {
|
|
103
|
-
refreshAttempts += 1;
|
|
104
|
-
return null;
|
|
105
|
-
});
|
|
106
|
-
|
|
107
|
-
await http.post('/posts', { text: 'hello' });
|
|
108
|
-
|
|
109
|
-
expect(refreshAttempts).toBe(1);
|
|
110
|
-
expect(calls.map((call) => call.url)).toEqual(['https://api.mention.earth/posts']);
|
|
111
|
-
expect(readHeaders(calls[0].init).Authorization).toBe(`Bearer ${accessToken}`);
|
|
112
|
-
});
|
|
113
|
-
|
|
114
|
-
it('does not use an expired bearer token when preflight refresh cannot refresh', async () => {
|
|
115
|
-
const calls = recordFetches();
|
|
116
|
-
|
|
117
|
-
const http = new HttpService({ baseURL: 'https://api.mention.earth', enableRetry: false });
|
|
118
|
-
const accessToken = createJwt({
|
|
119
|
-
userId: 'user_1',
|
|
120
|
-
exp: Math.floor(Date.now() / 1000) - 10,
|
|
121
|
-
});
|
|
122
|
-
let refreshAttempts = 0;
|
|
123
|
-
http.setTokens(accessToken);
|
|
124
|
-
http.setAuthRefreshHandler(async () => {
|
|
125
|
-
refreshAttempts += 1;
|
|
126
|
-
return null;
|
|
127
|
-
});
|
|
128
|
-
|
|
129
|
-
await http.post('/posts', { text: 'hello' });
|
|
130
|
-
|
|
131
|
-
expect(refreshAttempts).toBe(1);
|
|
132
|
-
expect(calls.map((call) => call.url)).toEqual(['https://api.mention.earth/posts']);
|
|
133
|
-
expect(readHeaders(calls[0].init).Authorization).toBeUndefined();
|
|
134
|
-
});
|
|
135
|
-
|
|
136
|
-
it('does not retry a 403, whatever its code says', async () => {
|
|
137
|
-
const calls = recordFetches(
|
|
138
|
-
() =>
|
|
139
|
-
new Response(JSON.stringify({ code: 'CSRF_TOKEN_INVALID' }), {
|
|
140
|
-
status: 403,
|
|
141
|
-
statusText: 'Forbidden',
|
|
142
|
-
headers: { 'content-type': 'application/json' },
|
|
143
|
-
}),
|
|
144
|
-
);
|
|
145
|
-
|
|
146
|
-
const http = new HttpService({ baseURL: 'https://api.mention.earth', enableRetry: false });
|
|
147
|
-
|
|
148
|
-
await expect(http.post('/posts', { text: 'hello' })).rejects.toBeDefined();
|
|
149
|
-
expect(calls.map((call) => call.url)).toEqual(['https://api.mention.earth/posts']);
|
|
150
|
-
});
|
|
151
|
-
|
|
152
|
-
it('includes credentials for configured API origin requests', async () => {
|
|
153
|
-
const calls = recordFetches();
|
|
154
|
-
|
|
155
|
-
const http = new HttpService({ baseURL: 'https://api.oxy.so', enableRetry: false });
|
|
156
|
-
|
|
157
|
-
await http.get('/users/me');
|
|
158
|
-
|
|
159
|
-
expect(calls).toHaveLength(1);
|
|
160
|
-
expect(calls[0].url).toBe('https://api.oxy.so/users/me');
|
|
161
|
-
expect(calls[0].init?.credentials).toBe('include');
|
|
162
|
-
});
|
|
163
|
-
|
|
164
|
-
it('omits credentials for caller-supplied absolute URLs outside the configured API origin', async () => {
|
|
165
|
-
const calls = recordFetches();
|
|
166
|
-
|
|
167
|
-
const http = new HttpService({ baseURL: 'https://api.oxy.so', enableRetry: false });
|
|
168
|
-
|
|
169
|
-
await http.get('https://attacker.oxy.so/collect');
|
|
170
|
-
|
|
171
|
-
expect(calls).toHaveLength(1);
|
|
172
|
-
expect(calls[0].url).toBe('https://attacker.oxy.so/collect');
|
|
173
|
-
expect(calls[0].init?.credentials).toBe('omit');
|
|
174
|
-
});
|
|
175
|
-
});
|