@oxy.so/core 1.18.0 → 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 +189 -112
- 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 +190 -113
- 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 +47 -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 -1
- 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 +201 -132
- 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 -1
- 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 -1440
- 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 -1400
- 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 -965
- 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__/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 -2028
- 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
|
@@ -0,0 +1,521 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.OxyServer = exports.ServiceCredentialMismatchError = exports.ANONYMOUS_SERVICE_TOKEN_RETRY_MS = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* `OxyServer` — the Oxy client for a backend.
|
|
6
|
+
*
|
|
7
|
+
* ```ts
|
|
8
|
+
* import { OxyServer } from '@oxy.so/core/server';
|
|
9
|
+
*
|
|
10
|
+
* const oxy = new OxyServer({
|
|
11
|
+
* baseURL: 'https://api.oxy.so',
|
|
12
|
+
* serviceAuth: { apiKey: process.env.OXY_SERVICE_API_KEY!, apiSecret: process.env.OXY_SERVICE_API_SECRET! },
|
|
13
|
+
* });
|
|
14
|
+
*
|
|
15
|
+
* app.use('/api', oxy.middleware.auth());
|
|
16
|
+
* io.use(oxy.middleware.socket());
|
|
17
|
+
* app.use('/internal', oxy.middleware.service(), oxy.middleware.requireScope('files:read'));
|
|
18
|
+
*
|
|
19
|
+
* const people = await oxy.users.getMany(ids); // service lane when available
|
|
20
|
+
* const meta = await oxy.assets.metadataByIds(fileIds); // service-only
|
|
21
|
+
* ```
|
|
22
|
+
*
|
|
23
|
+
* Everything `OxyServices` has, plus the service-token lane (a key pair from
|
|
24
|
+
* `serviceAuth` / `configureServiceAuth`, or — with neither — the process's
|
|
25
|
+
* attested workload identity, ADR 0026), the Express / Socket.IO middleware,
|
|
26
|
+
* account events, and the service-only methods of `assets`, `notifications`,
|
|
27
|
+
* `linkedAccounts`, `agency` and `reputation`.
|
|
28
|
+
*
|
|
29
|
+
* Node only.
|
|
30
|
+
*/
|
|
31
|
+
const jwt_decode_1 = require("jwt-decode");
|
|
32
|
+
const protocol_1 = require("@oxy.so/protocol");
|
|
33
|
+
const OxyServices_1 = require("../OxyServices");
|
|
34
|
+
const logger_1 = require("../logger");
|
|
35
|
+
const workloadIdentity_1 = require("./workloadIdentity");
|
|
36
|
+
const middleware_1 = require("./middleware");
|
|
37
|
+
const namespaces_1 = require("./namespaces");
|
|
38
|
+
/**
|
|
39
|
+
* How long a failed service-token mint sends session-less requests anonymous
|
|
40
|
+
* before the next attempt, under `serviceIdentity: 'when-anonymous'`.
|
|
41
|
+
*/
|
|
42
|
+
exports.ANONYMOUS_SERVICE_TOKEN_RETRY_MS = 30000;
|
|
43
|
+
/**
|
|
44
|
+
* Sentinel error raised when a service token is asked for with a known apiKey
|
|
45
|
+
* but a non-matching secret: credential drift in the caller, or a cross-tenant
|
|
46
|
+
* cache lookup attempt. Surface as a 401-equivalent.
|
|
47
|
+
*/
|
|
48
|
+
class ServiceCredentialMismatchError extends Error {
|
|
49
|
+
constructor() {
|
|
50
|
+
super('Service credential mismatch: provided secret does not match the secret stored for this apiKey');
|
|
51
|
+
this.name = 'ServiceCredentialMismatchError';
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
exports.ServiceCredentialMismatchError = ServiceCredentialMismatchError;
|
|
55
|
+
const WORKLOAD_CACHE_KEY = 'workload-identity';
|
|
56
|
+
/** A token is reused until 60s before expiry (clock drift). */
|
|
57
|
+
const TOKEN_REUSE_MARGIN_MS = 60000;
|
|
58
|
+
/** Bound on remembered `appId:userId` delegation answers. */
|
|
59
|
+
const ACTING_AS_CACHE_MAX = 1000;
|
|
60
|
+
/** A positive grant is reused for 5 minutes — the revocation latency window. */
|
|
61
|
+
const ACTING_AS_GRANT_TTL_MS = 5 * 60 * 1000;
|
|
62
|
+
/** A negative answer (or a failed lookup) is reused for 1 minute. */
|
|
63
|
+
const ACTING_AS_DENIAL_TTL_MS = 60 * 1000;
|
|
64
|
+
class OxyServer extends OxyServices_1.OxyServices {
|
|
65
|
+
constructor(config) {
|
|
66
|
+
super(config);
|
|
67
|
+
this.serviceTokens = new Map();
|
|
68
|
+
this.serviceApiKey = null;
|
|
69
|
+
this.serviceApiSecret = null;
|
|
70
|
+
this.actingAs = new Map();
|
|
71
|
+
this.actingAsPending = new Map();
|
|
72
|
+
/** Public keys only; never private material. */
|
|
73
|
+
this.jwksCache = { keys: new Map(), expiresAt: 0, lastAttemptAt: 0 };
|
|
74
|
+
/**
|
|
75
|
+
* Before this instant a request without a user session does not try to mint
|
|
76
|
+
* a service token and goes out anonymous. Set after a failed mint.
|
|
77
|
+
*/
|
|
78
|
+
this.anonymousServiceTokenRetryAt = 0;
|
|
79
|
+
/**
|
|
80
|
+
* Account events addressed to this application (Oxy account deletions every
|
|
81
|
+
* relying application must honour, OxyHQ/Mention#1169).
|
|
82
|
+
*/
|
|
83
|
+
this.accountEvents = {
|
|
84
|
+
/**
|
|
85
|
+
* Verify an account event token — a webhook body, or a feed entry's `token`
|
|
86
|
+
* — and return the event. Throws {@link OxyAccountEventError} unless it is
|
|
87
|
+
* an EdDSA `secevent+jwt` from Oxy's key set, issued by `oxy-auth`,
|
|
88
|
+
* addressed to this application, carrying exactly one known event. Be
|
|
89
|
+
* idempotent on `eventId`: Oxy delivers at least once.
|
|
90
|
+
*/
|
|
91
|
+
verify: (token, options = {}) => this.verifyAccountEvent(token, options),
|
|
92
|
+
/**
|
|
93
|
+
* One page of account events for this application, oldest first — the pull
|
|
94
|
+
* feed behind the webhook. Verify each entry's `token` before acting on it.
|
|
95
|
+
*/
|
|
96
|
+
list: async (options = {}) => {
|
|
97
|
+
const query = {};
|
|
98
|
+
if (options.after)
|
|
99
|
+
query.after = options.after;
|
|
100
|
+
if (options.limit !== undefined)
|
|
101
|
+
query.limit = String(options.limit);
|
|
102
|
+
return this.serviceRequest('GET', '/account-events', query);
|
|
103
|
+
},
|
|
104
|
+
};
|
|
105
|
+
if (config.serviceAuth) {
|
|
106
|
+
this.configureServiceAuth(config.serviceAuth.apiKey, config.serviceAuth.apiSecret);
|
|
107
|
+
}
|
|
108
|
+
const server = this;
|
|
109
|
+
const serviceLane = {
|
|
110
|
+
get available() {
|
|
111
|
+
return server.canMintServiceToken();
|
|
112
|
+
},
|
|
113
|
+
request: (...args) => this.serviceRequest(...args),
|
|
114
|
+
};
|
|
115
|
+
this.context.service = serviceLane;
|
|
116
|
+
if (config.serviceIdentity === 'when-anonymous') {
|
|
117
|
+
this.http.setAnonymousAuthProvider(() => this.serviceTokenForAnonymousRequest());
|
|
118
|
+
}
|
|
119
|
+
this.middleware = (0, middleware_1.createOxyMiddleware)({
|
|
120
|
+
get baseURL() {
|
|
121
|
+
return server.baseURL;
|
|
122
|
+
},
|
|
123
|
+
jwksCache: this.jwksCache,
|
|
124
|
+
validateSession: (sessionId, options) => this.session.validate(sessionId, options),
|
|
125
|
+
verifyActingAs: (appId, userId) => this.verifyActingAs(appId, userId),
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
/** Files, plus the service-only metadata and linked-URL lookups. */
|
|
129
|
+
get assets() {
|
|
130
|
+
if (!this._serverAssets)
|
|
131
|
+
this._serverAssets = new namespaces_1.ServerAssetsApi(this.context);
|
|
132
|
+
return this._serverAssets;
|
|
133
|
+
}
|
|
134
|
+
/** The inbox and push tokens, plus `create`. */
|
|
135
|
+
get notifications() {
|
|
136
|
+
if (!this._serverNotifications)
|
|
137
|
+
this._serverNotifications = new namespaces_1.ServerNotificationsApi(this.context);
|
|
138
|
+
return this._serverNotifications;
|
|
139
|
+
}
|
|
140
|
+
/** Linked external accounts, plus `forUser`. */
|
|
141
|
+
get linkedAccounts() {
|
|
142
|
+
if (!this._serverLinkedAccounts)
|
|
143
|
+
this._serverLinkedAccounts = new namespaces_1.ServerLinkedAccountsApi(this.context);
|
|
144
|
+
return this._serverLinkedAccounts;
|
|
145
|
+
}
|
|
146
|
+
/** Delegated capabilities, plus `introspectRequesterAssertion`. */
|
|
147
|
+
get agency() {
|
|
148
|
+
if (!this._serverAgency)
|
|
149
|
+
this._serverAgency = new namespaces_1.ServerAgencyApi(this.context);
|
|
150
|
+
return this._serverAgency;
|
|
151
|
+
}
|
|
152
|
+
/** Reputation reads, plus `award`. */
|
|
153
|
+
get reputation() {
|
|
154
|
+
if (!this._serverReputation)
|
|
155
|
+
this._serverReputation = new namespaces_1.ServerReputationApi(this.context);
|
|
156
|
+
return this._serverReputation;
|
|
157
|
+
}
|
|
158
|
+
// ── Service token ────────────────────────────────────────────────────────
|
|
159
|
+
/**
|
|
160
|
+
* Set this service's application credential. Each `(apiKey, apiSecret)` pair
|
|
161
|
+
* is cached independently, so a multi-tenant host switching credentials
|
|
162
|
+
* cannot leak one tenant's token to another.
|
|
163
|
+
*/
|
|
164
|
+
configureServiceAuth(apiKey, apiSecret) {
|
|
165
|
+
this.serviceApiKey = apiKey;
|
|
166
|
+
this.serviceApiSecret = apiSecret;
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* A service token (short-lived, cached and refreshed per credential pair;
|
|
170
|
+
* concurrent callers share one mint).
|
|
171
|
+
*
|
|
172
|
+
* With no credential configured or passed, the token comes from the process's
|
|
173
|
+
* attested workload identity (ADR 0026); with neither, this throws.
|
|
174
|
+
*
|
|
175
|
+
* If the cache already holds a token for `apiKey` but `apiSecret` does not
|
|
176
|
+
* constant-time match the secret that produced it, this throws
|
|
177
|
+
* {@link ServiceCredentialMismatchError} rather than return the cached token.
|
|
178
|
+
*/
|
|
179
|
+
async serviceToken(apiKey, apiSecret) {
|
|
180
|
+
const key = apiKey || this.serviceApiKey;
|
|
181
|
+
const secret = apiSecret || this.serviceApiSecret;
|
|
182
|
+
if (!key || !secret) {
|
|
183
|
+
// No credential — prove what this process IS instead. The fallback, not the
|
|
184
|
+
// preference: a deployment that still has a credential keeps using it.
|
|
185
|
+
if ((0, workloadIdentity_1.canAttestWorkloadIdentity)()) {
|
|
186
|
+
return this.workloadServiceToken();
|
|
187
|
+
}
|
|
188
|
+
throw new Error('Service credentials not provided. Pass serviceAuth, call configureServiceAuth(), or pass apiKey and apiSecret.');
|
|
189
|
+
}
|
|
190
|
+
// The apiKey is the credential's PUBLIC id (`oxy_dk_…`, the OAuth
|
|
191
|
+
// client_id), so it keys the in-memory cache as is; the secret never does.
|
|
192
|
+
const cacheKey = key;
|
|
193
|
+
const now = Date.now();
|
|
194
|
+
const providedSecretBuf = Buffer.from(secret, 'utf8');
|
|
195
|
+
let entry = this.serviceTokens.get(cacheKey);
|
|
196
|
+
if (entry) {
|
|
197
|
+
// Verify the secret on every hit, fresh token or not. Constant-time, and
|
|
198
|
+
// run on equal-length inputs even when the lengths differ.
|
|
199
|
+
const nodeCrypto = await (0, protocol_1.loadNodeCrypto)();
|
|
200
|
+
const stored = entry.secretBuf;
|
|
201
|
+
const lengthMatch = stored.length === providedSecretBuf.length;
|
|
202
|
+
const compareBuf = lengthMatch ? providedSecretBuf : Buffer.alloc(stored.length);
|
|
203
|
+
const equal = nodeCrypto.timingSafeEqual(stored, compareBuf);
|
|
204
|
+
if (!lengthMatch || !equal) {
|
|
205
|
+
logger_1.logger.warn('[oxy.auth] Service token cache hit with mismatched secret', {
|
|
206
|
+
component: 'auth',
|
|
207
|
+
method: 'serviceToken',
|
|
208
|
+
});
|
|
209
|
+
throw new ServiceCredentialMismatchError();
|
|
210
|
+
}
|
|
211
|
+
if (entry.token && entry.expiresAt > now + TOKEN_REUSE_MARGIN_MS) {
|
|
212
|
+
return entry.token;
|
|
213
|
+
}
|
|
214
|
+
if (entry.pending) {
|
|
215
|
+
return entry.pending;
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
else {
|
|
219
|
+
// Seed an empty entry so concurrent callers serialize on one promise.
|
|
220
|
+
entry = { token: '', expiresAt: 0, secretBuf: providedSecretBuf, pending: null, apiKey: key };
|
|
221
|
+
this.serviceTokens.set(cacheKey, entry);
|
|
222
|
+
}
|
|
223
|
+
const pending = this.mintServiceToken(key, secret, cacheKey, providedSecretBuf);
|
|
224
|
+
entry.pending = pending;
|
|
225
|
+
try {
|
|
226
|
+
return await pending;
|
|
227
|
+
}
|
|
228
|
+
catch (error) {
|
|
229
|
+
// Never keep an entry that never held a token: a wrong first secret must
|
|
230
|
+
// not make the right one fail locally as a mismatch later.
|
|
231
|
+
const failed = this.serviceTokens.get(cacheKey);
|
|
232
|
+
if (failed?.pending === pending && !failed.token) {
|
|
233
|
+
this.serviceTokens.delete(cacheKey);
|
|
234
|
+
}
|
|
235
|
+
throw error;
|
|
236
|
+
}
|
|
237
|
+
finally {
|
|
238
|
+
const settled = this.serviceTokens.get(cacheKey);
|
|
239
|
+
if (settled?.pending === pending)
|
|
240
|
+
settled.pending = null;
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
/**
|
|
244
|
+
* Forget cached service token(s) so the next `serviceToken()` mints anew —
|
|
245
|
+
* the way back from a 401 after a credential was revoked or rotated.
|
|
246
|
+
*
|
|
247
|
+
* `apiKey` clears that credential's entry; with none, the configured
|
|
248
|
+
* credential's; with neither, every entry. Synchronous.
|
|
249
|
+
*/
|
|
250
|
+
invalidateServiceToken(apiKey) {
|
|
251
|
+
const targetKey = apiKey ?? this.serviceApiKey;
|
|
252
|
+
if (!targetKey) {
|
|
253
|
+
this.serviceTokens.clear();
|
|
254
|
+
return;
|
|
255
|
+
}
|
|
256
|
+
this.serviceTokens.delete(targetKey);
|
|
257
|
+
}
|
|
258
|
+
/**
|
|
259
|
+
* One request with this service's token. `actAs` sends `X-Oxy-User-Id`: the
|
|
260
|
+
* request is on behalf of that user (the API checks the delegation grant).
|
|
261
|
+
* Never cached unless `cache` says so. Rejects with `OxyApiError`.
|
|
262
|
+
*/
|
|
263
|
+
async serviceRequest(method, url, data, options = {}) {
|
|
264
|
+
const { actAs, headers, ...rest } = options;
|
|
265
|
+
const token = await this.serviceToken();
|
|
266
|
+
const merged = { ...headers, Authorization: `Bearer ${token}` };
|
|
267
|
+
if (actAs)
|
|
268
|
+
merged['X-Oxy-User-Id'] = actAs;
|
|
269
|
+
return this.request(method, url, data, { cache: false, ...rest, headers: merged });
|
|
270
|
+
}
|
|
271
|
+
// ── Delegation and account events ────────────────────────────────────────
|
|
272
|
+
/**
|
|
273
|
+
* Whether service app `appId` holds an active delegation grant to act for
|
|
274
|
+
* `userId`; the grant's scopes, or `null`. Used by `middleware.auth()` for
|
|
275
|
+
* `X-Oxy-User-Id`.
|
|
276
|
+
*
|
|
277
|
+
* Answers are cached per `appId:userId` (a grant for 5 minutes — the
|
|
278
|
+
* revocation window; a denial or failed lookup for 1 minute), bounded to the
|
|
279
|
+
* 1000 most recent pairs, and concurrent lookups of one pair share a single
|
|
280
|
+
* request.
|
|
281
|
+
*/
|
|
282
|
+
async verifyActingAs(appId, userId) {
|
|
283
|
+
const cacheKey = `${appId}:${userId}`;
|
|
284
|
+
const cached = this.actingAs.get(cacheKey);
|
|
285
|
+
if (cached && cached.expiresAt > Date.now()) {
|
|
286
|
+
// Refresh recency for the LRU bound.
|
|
287
|
+
this.actingAs.delete(cacheKey);
|
|
288
|
+
this.actingAs.set(cacheKey, cached);
|
|
289
|
+
return cached.result;
|
|
290
|
+
}
|
|
291
|
+
const inflight = this.actingAsPending.get(cacheKey);
|
|
292
|
+
if (inflight)
|
|
293
|
+
return inflight;
|
|
294
|
+
const lookup = this.lookupActingAs(appId, userId).finally(() => {
|
|
295
|
+
this.actingAsPending.delete(cacheKey);
|
|
296
|
+
});
|
|
297
|
+
this.actingAsPending.set(cacheKey, lookup);
|
|
298
|
+
return lookup;
|
|
299
|
+
}
|
|
300
|
+
// ── Internals ────────────────────────────────────────────────────────────
|
|
301
|
+
/**
|
|
302
|
+
* The bearer for a request with no user session, under `serviceIdentity:
|
|
303
|
+
* 'when-anonymous'`: this process's service token, or `null` to send the
|
|
304
|
+
* request anonymous.
|
|
305
|
+
*
|
|
306
|
+
* `null`, never a throw, whenever there is no token to offer:
|
|
307
|
+
* - no key pair and no attestable workload (a local checkout);
|
|
308
|
+
* - the mint failed. The request still goes out, anonymous, and so does every
|
|
309
|
+
* request for the next {@link ANONYMOUS_SERVICE_TOKEN_RETRY_MS}, so an Oxy
|
|
310
|
+
* refusing attestation is asked once per window rather than once per read.
|
|
311
|
+
*
|
|
312
|
+
* The token comes from {@link serviceToken}: cached and single-flight, so
|
|
313
|
+
* concurrent reads share one mint.
|
|
314
|
+
*/
|
|
315
|
+
async serviceTokenForAnonymousRequest() {
|
|
316
|
+
if (Date.now() < this.anonymousServiceTokenRetryAt)
|
|
317
|
+
return null;
|
|
318
|
+
if (!this.canMintServiceToken())
|
|
319
|
+
return null;
|
|
320
|
+
try {
|
|
321
|
+
return await this.serviceToken();
|
|
322
|
+
}
|
|
323
|
+
catch (error) {
|
|
324
|
+
this.anonymousServiceTokenRetryAt = Date.now() + exports.ANONYMOUS_SERVICE_TOKEN_RETRY_MS;
|
|
325
|
+
logger_1.logger.warn('[oxy.auth] No service token for a request without a session; sending it anonymous', {
|
|
326
|
+
component: 'auth',
|
|
327
|
+
method: 'serviceTokenForAnonymousRequest',
|
|
328
|
+
retryInMs: exports.ANONYMOUS_SERVICE_TOKEN_RETRY_MS,
|
|
329
|
+
error: error instanceof Error ? error.message : String(error),
|
|
330
|
+
});
|
|
331
|
+
return null;
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
canMintServiceToken() {
|
|
335
|
+
return Boolean(this.serviceApiKey && this.serviceApiSecret) || (0, workloadIdentity_1.canAttestWorkloadIdentity)();
|
|
336
|
+
}
|
|
337
|
+
async mintServiceToken(key, secret, cacheKey, secretBuf) {
|
|
338
|
+
const response = await this.request('POST', '/auth/service-token', { apiKey: key, apiSecret: secret }, { cache: false, retry: false, skipAuth: true });
|
|
339
|
+
const expiresAt = Date.now() + response.expiresIn * 1000;
|
|
340
|
+
const entry = this.serviceTokens.get(cacheKey);
|
|
341
|
+
if (entry) {
|
|
342
|
+
entry.token = response.token;
|
|
343
|
+
entry.expiresAt = expiresAt;
|
|
344
|
+
entry.secretBuf = secretBuf;
|
|
345
|
+
}
|
|
346
|
+
else {
|
|
347
|
+
this.serviceTokens.set(cacheKey, { token: response.token, expiresAt, secretBuf, pending: null, apiKey: key });
|
|
348
|
+
}
|
|
349
|
+
return response.token;
|
|
350
|
+
}
|
|
351
|
+
/** A token obtained by attestation, cached like a credential's (one identity per process). */
|
|
352
|
+
async workloadServiceToken() {
|
|
353
|
+
const entry = this.serviceTokens.get(WORKLOAD_CACHE_KEY);
|
|
354
|
+
if (entry?.token && entry.expiresAt > Date.now() + TOKEN_REUSE_MARGIN_MS)
|
|
355
|
+
return entry.token;
|
|
356
|
+
if (entry?.pending)
|
|
357
|
+
return entry.pending;
|
|
358
|
+
const seeded = entry ?? { token: '', expiresAt: 0, secretBuf: Buffer.alloc(0), pending: null, apiKey: WORKLOAD_CACHE_KEY };
|
|
359
|
+
this.serviceTokens.set(WORKLOAD_CACHE_KEY, seeded);
|
|
360
|
+
const pending = (async () => {
|
|
361
|
+
const granted = await (0, workloadIdentity_1.requestWorkloadServiceToken)({ baseUrl: this.baseURL });
|
|
362
|
+
const current = this.serviceTokens.get(WORKLOAD_CACHE_KEY);
|
|
363
|
+
if (current) {
|
|
364
|
+
current.token = granted.token;
|
|
365
|
+
current.expiresAt = Date.now() + granted.expiresIn * 1000;
|
|
366
|
+
}
|
|
367
|
+
return granted.token;
|
|
368
|
+
})();
|
|
369
|
+
seeded.pending = pending;
|
|
370
|
+
try {
|
|
371
|
+
return await pending;
|
|
372
|
+
}
|
|
373
|
+
catch (error) {
|
|
374
|
+
const failed = this.serviceTokens.get(WORKLOAD_CACHE_KEY);
|
|
375
|
+
if (failed?.pending === pending && !failed.token)
|
|
376
|
+
this.serviceTokens.delete(WORKLOAD_CACHE_KEY);
|
|
377
|
+
throw error;
|
|
378
|
+
}
|
|
379
|
+
finally {
|
|
380
|
+
const settled = this.serviceTokens.get(WORKLOAD_CACHE_KEY);
|
|
381
|
+
if (settled?.pending === pending)
|
|
382
|
+
settled.pending = null;
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
async lookupActingAs(appId, userId) {
|
|
386
|
+
try {
|
|
387
|
+
// The verify endpoint admits only a platform-trusted caller, so this
|
|
388
|
+
// carries the VERIFIER's own service token. No retry and a short timeout:
|
|
389
|
+
// it runs inside request-handling middleware, and a retry loop would
|
|
390
|
+
// multiply the latency of every delegated request. A verifier with no
|
|
391
|
+
// credential throws here and is refused below — a host that cannot prove
|
|
392
|
+
// who it is has no business learning who delegated to whom.
|
|
393
|
+
const serviceToken = await this.serviceToken();
|
|
394
|
+
const result = await this.request('GET', '/internal/service-acting-as/verify', { appId, userId }, { cache: false, retry: false, timeout: 5000, headers: { Authorization: `Bearer ${serviceToken}` } });
|
|
395
|
+
const verified = result?.authorized
|
|
396
|
+
? { authorized: true, scopes: Array.isArray(result.scopes) ? result.scopes : [] }
|
|
397
|
+
: null;
|
|
398
|
+
this.rememberActingAs(`${appId}:${userId}`, verified, ACTING_AS_GRANT_TTL_MS);
|
|
399
|
+
return verified;
|
|
400
|
+
}
|
|
401
|
+
catch (error) {
|
|
402
|
+
logger_1.logger.warn('[oxy.auth] verifyActingAs lookup failed — caching negative result', {
|
|
403
|
+
component: 'auth',
|
|
404
|
+
method: 'verifyActingAs',
|
|
405
|
+
appId,
|
|
406
|
+
userId,
|
|
407
|
+
}, error);
|
|
408
|
+
this.rememberActingAs(`${appId}:${userId}`, null, ACTING_AS_DENIAL_TTL_MS);
|
|
409
|
+
return null;
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
rememberActingAs(cacheKey, result, ttlMs) {
|
|
413
|
+
this.actingAs.delete(cacheKey);
|
|
414
|
+
this.actingAs.set(cacheKey, { result, expiresAt: Date.now() + ttlMs });
|
|
415
|
+
if (this.actingAs.size > ACTING_AS_CACHE_MAX) {
|
|
416
|
+
const oldest = this.actingAs.keys().next().value;
|
|
417
|
+
if (oldest !== undefined)
|
|
418
|
+
this.actingAs.delete(oldest);
|
|
419
|
+
}
|
|
420
|
+
}
|
|
421
|
+
async verifyAccountEvent(token, options) {
|
|
422
|
+
if (typeof token !== 'string' || token.length === 0 || token.length > 16 * 1024) {
|
|
423
|
+
throw new middleware_1.OxyAccountEventError('Account event token is missing or oversized');
|
|
424
|
+
}
|
|
425
|
+
const parts = token.split('.');
|
|
426
|
+
if (parts.length !== 3 || parts.some((part) => part.length === 0)) {
|
|
427
|
+
throw new middleware_1.OxyAccountEventError('Account event token is not a compact JWS');
|
|
428
|
+
}
|
|
429
|
+
const [headerB64, payloadB64, signatureB64] = parts;
|
|
430
|
+
let header;
|
|
431
|
+
let payload;
|
|
432
|
+
try {
|
|
433
|
+
header = (0, middleware_1.parseJsonSegment)(headerB64);
|
|
434
|
+
payload = (0, middleware_1.parseJsonSegment)(payloadB64);
|
|
435
|
+
}
|
|
436
|
+
catch {
|
|
437
|
+
throw new middleware_1.OxyAccountEventError('Account event token is malformed');
|
|
438
|
+
}
|
|
439
|
+
if (Object.keys(header).length !== 3
|
|
440
|
+
|| header.alg !== 'EdDSA'
|
|
441
|
+
|| header.typ !== 'secevent+jwt'
|
|
442
|
+
|| typeof header.kid !== 'string'
|
|
443
|
+
|| !/^[A-Za-z0-9._-]{1,128}$/.test(header.kid)) {
|
|
444
|
+
throw new middleware_1.OxyAccountEventError('Account event token header is not supported');
|
|
445
|
+
}
|
|
446
|
+
const nodeCrypto = await (0, protocol_1.loadNodeCrypto)();
|
|
447
|
+
let jwk;
|
|
448
|
+
try {
|
|
449
|
+
jwk = await (0, middleware_1.resolveServiceTokenPublicKey)(header.kid, options.jwksUrl ?? new URL('/.well-known/jwks.json', this.baseURL).toString(), this.jwksCache);
|
|
450
|
+
}
|
|
451
|
+
catch (error) {
|
|
452
|
+
throw new middleware_1.OxyAccountEventError(error instanceof Error ? error.message.replace('Service token', 'Account event') : 'Signing key is unavailable');
|
|
453
|
+
}
|
|
454
|
+
const signature = Buffer.from(signatureB64, 'base64url');
|
|
455
|
+
if (signature.toString('base64url') !== signatureB64 || signature.length !== 64) {
|
|
456
|
+
throw new middleware_1.OxyAccountEventError('Account event token signature is malformed');
|
|
457
|
+
}
|
|
458
|
+
let verified = false;
|
|
459
|
+
try {
|
|
460
|
+
const publicKey = nodeCrypto.createPublicKey({ key: jwk, format: 'jwk' });
|
|
461
|
+
verified = nodeCrypto.verify(null, Buffer.from(`${headerB64}.${payloadB64}`), publicKey, signature);
|
|
462
|
+
}
|
|
463
|
+
catch {
|
|
464
|
+
verified = false;
|
|
465
|
+
}
|
|
466
|
+
if (!verified)
|
|
467
|
+
throw new middleware_1.OxyAccountEventError('Account event token signature is invalid');
|
|
468
|
+
if (payload.iss !== middleware_1.OXY_JWT_ISSUER) {
|
|
469
|
+
throw new middleware_1.OxyAccountEventError('Account event token issuer is not Oxy');
|
|
470
|
+
}
|
|
471
|
+
const audience = options.audience ?? await this.configuredServiceAppId();
|
|
472
|
+
if (typeof payload.aud !== 'string' || payload.aud !== audience) {
|
|
473
|
+
throw new middleware_1.OxyAccountEventError('Account event token is addressed to another application');
|
|
474
|
+
}
|
|
475
|
+
if (typeof payload.jti !== 'string' || payload.jti.length === 0 || payload.jti.length > 128) {
|
|
476
|
+
throw new middleware_1.OxyAccountEventError('Account event token has no event id');
|
|
477
|
+
}
|
|
478
|
+
if (typeof payload.iat !== 'number' || !Number.isFinite(payload.iat)) {
|
|
479
|
+
throw new middleware_1.OxyAccountEventError('Account event token has no issue time');
|
|
480
|
+
}
|
|
481
|
+
const events = payload.events;
|
|
482
|
+
if (typeof events !== 'object' || events === null || Array.isArray(events)) {
|
|
483
|
+
throw new middleware_1.OxyAccountEventError('Account event token carries no events');
|
|
484
|
+
}
|
|
485
|
+
const entries = Object.entries(events);
|
|
486
|
+
const deleted = events[middleware_1.OXY_ACCOUNT_DELETED_EVENT_URI];
|
|
487
|
+
if (entries.length !== 1 || typeof deleted !== 'object' || deleted === null || Array.isArray(deleted)) {
|
|
488
|
+
throw new middleware_1.OxyAccountEventError('Account event token carries an unknown event');
|
|
489
|
+
}
|
|
490
|
+
const body = deleted;
|
|
491
|
+
if (typeof body.userId !== 'string' || body.userId.length === 0 || body.userId.length > 128) {
|
|
492
|
+
throw new middleware_1.OxyAccountEventError('Account event names no account');
|
|
493
|
+
}
|
|
494
|
+
if (typeof body.occurredAt !== 'string' || Number.isNaN(Date.parse(body.occurredAt))) {
|
|
495
|
+
throw new middleware_1.OxyAccountEventError('Account event has no occurrence time');
|
|
496
|
+
}
|
|
497
|
+
if (body.username !== undefined && body.username !== null && typeof body.username !== 'string') {
|
|
498
|
+
throw new middleware_1.OxyAccountEventError('Account event username is malformed');
|
|
499
|
+
}
|
|
500
|
+
return {
|
|
501
|
+
eventId: payload.jti,
|
|
502
|
+
type: 'account.deleted',
|
|
503
|
+
userId: body.userId,
|
|
504
|
+
username: typeof body.username === 'string' ? body.username : null,
|
|
505
|
+
occurredAt: body.occurredAt,
|
|
506
|
+
retained: body.retained === true,
|
|
507
|
+
applicationId: payload.aud,
|
|
508
|
+
issuedAt: payload.iat,
|
|
509
|
+
};
|
|
510
|
+
}
|
|
511
|
+
/** The `appId` claim of this service's own token. */
|
|
512
|
+
async configuredServiceAppId() {
|
|
513
|
+
const serviceToken = await this.serviceToken();
|
|
514
|
+
const appId = (0, jwt_decode_1.jwtDecode)(serviceToken).appId;
|
|
515
|
+
if (typeof appId !== 'string' || appId.length === 0) {
|
|
516
|
+
throw new middleware_1.OxyAccountEventError('No audience given and the service credential names no application');
|
|
517
|
+
}
|
|
518
|
+
return appId;
|
|
519
|
+
}
|
|
520
|
+
}
|
|
521
|
+
exports.OxyServer = OxyServer;
|
package/dist/cjs/server/auth.js
CHANGED
|
@@ -125,7 +125,7 @@ function getRequiredOxyUserId(req) {
|
|
|
125
125
|
* Why the credential on this request was refused, or `null` when none was
|
|
126
126
|
* presented (or it was accepted).
|
|
127
127
|
*
|
|
128
|
-
* Set by `
|
|
128
|
+
* Set by `server.middleware.auth()` — including the `optional: true` mount the composed
|
|
129
129
|
* helpers use, where a refusal otherwise leaves no trace: the request simply
|
|
130
130
|
* arrives unauthenticated and the host answers its own generic 401. Hosts log
|
|
131
131
|
* this beside their own 401; it is diagnostic and **must not be put into a
|
|
@@ -163,7 +163,7 @@ function requireOxyAuth(req, res, next) {
|
|
|
163
163
|
next();
|
|
164
164
|
}
|
|
165
165
|
function createOptionalOxyAuth(oxy, options = {}) {
|
|
166
|
-
const resolveSession = oxy.auth({ ...options.auth, optional: true });
|
|
166
|
+
const resolveSession = oxy.middleware.auth({ ...options.auth, optional: true });
|
|
167
167
|
return (req, res, next) => {
|
|
168
168
|
if (getOxyUserId(req)) {
|
|
169
169
|
next();
|
package/dist/cjs/server/index.js
CHANGED
|
@@ -7,17 +7,32 @@
|
|
|
7
7
|
*
|
|
8
8
|
* @example
|
|
9
9
|
* ```ts
|
|
10
|
-
* import { createOxyRateLimit } from '@oxy.so/core/server';
|
|
11
|
-
* import { oxyClient } from '@oxy.so/core';
|
|
10
|
+
* import { OxyServer, createOxyAuthMiddleware, createOxyRateLimit } from '@oxy.so/core/server';
|
|
12
11
|
*
|
|
13
|
-
* const oxy =
|
|
12
|
+
* const oxy = new OxyServer({ baseURL: 'https://api.oxy.so', serviceAuth: { apiKey, apiSecret } });
|
|
14
13
|
*
|
|
15
14
|
* app.use(createOxyRateLimit(oxy, { store: redisStore }));
|
|
15
|
+
* app.use('/api', createOxyAuthMiddleware(oxy));
|
|
16
16
|
* ```
|
|
17
17
|
*/
|
|
18
18
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
19
|
-
exports.
|
|
20
|
-
exports.requestWorkloadServiceToken = exports.canAttestWorkloadIdentity = exports.withoutNodeHttpObservation = exports.observeNodeHttp = exports.createEcosystemTraffic = exports.isOfficialWebOrigin = exports.registrableApex = exports.OXY_IDENTITY_CACHE_PREFIXES = exports.oxyUserByIdCacheKey = exports.evictOxyIdentityCache = exports.publishOxyUserInvalidation = exports.createOxyUserInvalidationHandler = exports.verifySecret = exports.verifyOxyRequesterAssertion = void 0;
|
|
19
|
+
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.getOxyAuthRefusal = exports.createOxyAuthMiddleware = exports.createOptionalOxyAuth = exports.OXY_ACCOUNT_DELETED_EVENT_URI = exports.OxyAccountEventError = exports.ServerReputationApi = exports.ServerNotificationsApi = exports.ServerLinkedAccountsApi = exports.ServerAssetsApi = exports.ServerAgencyApi = exports.ANONYMOUS_SERVICE_TOKEN_RETRY_MS = exports.ServiceCredentialMismatchError = exports.OxyServer = void 0;
|
|
20
|
+
exports.requestWorkloadServiceToken = exports.canAttestWorkloadIdentity = exports.withoutNodeHttpObservation = exports.observeNodeHttp = exports.createEcosystemTraffic = exports.isAllowedDeviceJoinOrigin = exports.isOfficialWebOrigin = exports.isLoopbackOrigin = exports.registrableApex = exports.OXY_IDENTITY_CACHE_PREFIXES = exports.oxyUserByIdCacheKey = exports.evictOxyIdentityCache = exports.publishOxyUserInvalidation = exports.createOxyUserInvalidationHandler = exports.verifySecret = exports.verifyOxyRequesterAssertion = exports.signOxyRequesterAssertion = exports.readOxyRequesterAssertionKeyId = exports.oxyRequesterAssertionClaimsSchema = exports.OxyRequesterAssertionError = exports.OXY_REQUESTER_ASSERTION_TYPE = exports.OXY_REQUESTER_ASSERTION_MAX_TTL_SECONDS = exports.OXY_REQUESTER_ASSERTION_HEADER = exports.OXY_REQUESTER_ASSERTION_DEFAULT_ISSUER = exports.createOxyRequesterAssertionAuth = exports.createOxyJwksKeyResolver = void 0;
|
|
21
|
+
// The backend client: OxyServices plus the service-token lane, middleware,
|
|
22
|
+
// account events and the service-only namespace methods.
|
|
23
|
+
var OxyServer_1 = require("./OxyServer");
|
|
24
|
+
Object.defineProperty(exports, "OxyServer", { enumerable: true, get: function () { return OxyServer_1.OxyServer; } });
|
|
25
|
+
Object.defineProperty(exports, "ServiceCredentialMismatchError", { enumerable: true, get: function () { return OxyServer_1.ServiceCredentialMismatchError; } });
|
|
26
|
+
Object.defineProperty(exports, "ANONYMOUS_SERVICE_TOKEN_RETRY_MS", { enumerable: true, get: function () { return OxyServer_1.ANONYMOUS_SERVICE_TOKEN_RETRY_MS; } });
|
|
27
|
+
var namespaces_1 = require("./namespaces");
|
|
28
|
+
Object.defineProperty(exports, "ServerAgencyApi", { enumerable: true, get: function () { return namespaces_1.ServerAgencyApi; } });
|
|
29
|
+
Object.defineProperty(exports, "ServerAssetsApi", { enumerable: true, get: function () { return namespaces_1.ServerAssetsApi; } });
|
|
30
|
+
Object.defineProperty(exports, "ServerLinkedAccountsApi", { enumerable: true, get: function () { return namespaces_1.ServerLinkedAccountsApi; } });
|
|
31
|
+
Object.defineProperty(exports, "ServerNotificationsApi", { enumerable: true, get: function () { return namespaces_1.ServerNotificationsApi; } });
|
|
32
|
+
Object.defineProperty(exports, "ServerReputationApi", { enumerable: true, get: function () { return namespaces_1.ServerReputationApi; } });
|
|
33
|
+
var middleware_1 = require("./middleware");
|
|
34
|
+
Object.defineProperty(exports, "OxyAccountEventError", { enumerable: true, get: function () { return middleware_1.OxyAccountEventError; } });
|
|
35
|
+
Object.defineProperty(exports, "OXY_ACCOUNT_DELETED_EVENT_URI", { enumerable: true, get: function () { return middleware_1.OXY_ACCOUNT_DELETED_EVENT_URI; } });
|
|
21
36
|
var auth_1 = require("./auth");
|
|
22
37
|
Object.defineProperty(exports, "createOptionalOxyAuth", { enumerable: true, get: function () { return auth_1.createOptionalOxyAuth; } });
|
|
23
38
|
Object.defineProperty(exports, "createOxyAuthMiddleware", { enumerable: true, get: function () { return auth_1.createOxyAuthMiddleware; } });
|
|
@@ -97,7 +112,7 @@ var userInvalidation_1 = require("./userInvalidation");
|
|
|
97
112
|
Object.defineProperty(exports, "createOxyUserInvalidationHandler", { enumerable: true, get: function () { return userInvalidation_1.createOxyUserInvalidationHandler; } });
|
|
98
113
|
Object.defineProperty(exports, "publishOxyUserInvalidation", { enumerable: true, get: function () { return userInvalidation_1.publishOxyUserInvalidation; } });
|
|
99
114
|
// The identity-key enumeration itself is platform-neutral (`src/utils/`) so the
|
|
100
|
-
// client
|
|
115
|
+
// client namespaces and this Node-only subscriber sweep the SAME list — a second
|
|
101
116
|
// copy is what let `updateAccount` and `updateProfile` drift apart.
|
|
102
117
|
var identityCacheSweep_1 = require("../utils/identityCacheSweep");
|
|
103
118
|
Object.defineProperty(exports, "evictOxyIdentityCache", { enumerable: true, get: function () { return identityCacheSweep_1.evictOxyIdentityCache; } });
|
|
@@ -110,7 +125,9 @@ Object.defineProperty(exports, "OXY_IDENTITY_CACHE_PREFIXES", { enumerable: true
|
|
|
110
125
|
var registrableApex_1 = require("../utils/registrableApex");
|
|
111
126
|
Object.defineProperty(exports, "registrableApex", { enumerable: true, get: function () { return registrableApex_1.registrableApex; } });
|
|
112
127
|
var officialOrigins_1 = require("../utils/officialOrigins");
|
|
128
|
+
Object.defineProperty(exports, "isLoopbackOrigin", { enumerable: true, get: function () { return officialOrigins_1.isLoopbackOrigin; } });
|
|
113
129
|
Object.defineProperty(exports, "isOfficialWebOrigin", { enumerable: true, get: function () { return officialOrigins_1.isOfficialWebOrigin; } });
|
|
130
|
+
Object.defineProperty(exports, "isAllowedDeviceJoinOrigin", { enumerable: true, get: function () { return officialOrigins_1.isAllowedDeviceJoinOrigin; } });
|
|
114
131
|
var traffic_1 = require("./traffic");
|
|
115
132
|
Object.defineProperty(exports, "createEcosystemTraffic", { enumerable: true, get: function () { return traffic_1.createEcosystemTraffic; } });
|
|
116
133
|
var trafficNodeHttp_1 = require("./trafficNodeHttp");
|