@oxy.so/core 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +202 -0
- package/NOTICE +16 -0
- package/README.md +221 -0
- package/dist/cjs/.tsbuildinfo +1 -0
- package/dist/cjs/HttpService.js +1270 -0
- package/dist/cjs/OxyServices.base.js +390 -0
- package/dist/cjs/OxyServices.errors.js +95 -0
- package/dist/cjs/OxyServices.js +72 -0
- package/dist/cjs/boot/sessionColdBoot.js +395 -0
- package/dist/cjs/constants/version.js +16 -0
- package/dist/cjs/crypto/aead.js +79 -0
- package/dist/cjs/crypto/ecdh.js +35 -0
- package/dist/cjs/crypto/identityMarker.js +255 -0
- package/dist/cjs/crypto/kdf.js +39 -0
- package/dist/cjs/crypto/keyManager.js +2234 -0
- package/dist/cjs/crypto/polyfill.js +131 -0
- package/dist/cjs/crypto/recoveryPhrase.js +242 -0
- package/dist/cjs/crypto/signatureService.js +273 -0
- package/dist/cjs/i18n/accountCategoryLabels.js +44 -0
- package/dist/cjs/i18n/accountRoleLabels.js +27 -0
- package/dist/cjs/i18n/index.js +90 -0
- package/dist/cjs/i18n/locales/ar-SA.json +282 -0
- package/dist/cjs/i18n/locales/ca-ES.json +282 -0
- package/dist/cjs/i18n/locales/de-DE.json +282 -0
- package/dist/cjs/i18n/locales/en-US.json +2161 -0
- package/dist/cjs/i18n/locales/es-ES.json +2161 -0
- package/dist/cjs/i18n/locales/fr-FR.json +282 -0
- package/dist/cjs/i18n/locales/it-IT.json +282 -0
- package/dist/cjs/i18n/locales/ja-JP.json +282 -0
- package/dist/cjs/i18n/locales/ko-KR.json +282 -0
- package/dist/cjs/i18n/locales/locales/ar-SA.json +282 -0
- package/dist/cjs/i18n/locales/locales/ca-ES.json +282 -0
- package/dist/cjs/i18n/locales/locales/de-DE.json +282 -0
- package/dist/cjs/i18n/locales/locales/en-US.json +2161 -0
- package/dist/cjs/i18n/locales/locales/es-ES.json +2161 -0
- package/dist/cjs/i18n/locales/locales/fr-FR.json +282 -0
- package/dist/cjs/i18n/locales/locales/it-IT.json +282 -0
- package/dist/cjs/i18n/locales/locales/ja-JP.json +282 -0
- package/dist/cjs/i18n/locales/locales/ko-KR.json +282 -0
- package/dist/cjs/i18n/locales/locales/pt-PT.json +282 -0
- package/dist/cjs/i18n/locales/locales/zh-CN.json +282 -0
- package/dist/cjs/i18n/locales/pt-PT.json +282 -0
- package/dist/cjs/i18n/locales/zh-CN.json +282 -0
- package/dist/cjs/i18n/reputationCategoryLabels.js +20 -0
- package/dist/cjs/i18n/trustTierLabels.js +19 -0
- package/dist/cjs/index.js +498 -0
- package/dist/cjs/inference/OxyInferenceClient.js +544 -0
- package/dist/cjs/logger/index.js +149 -0
- package/dist/cjs/mixins/OxyServices.accounts.js +555 -0
- package/dist/cjs/mixins/OxyServices.analytics.js +49 -0
- package/dist/cjs/mixins/OxyServices.appData.js +108 -0
- package/dist/cjs/mixins/OxyServices.assets.js +764 -0
- package/dist/cjs/mixins/OxyServices.auth.js +1254 -0
- package/dist/cjs/mixins/OxyServices.chains.js +73 -0
- package/dist/cjs/mixins/OxyServices.civic.js +611 -0
- package/dist/cjs/mixins/OxyServices.connectedApps.js +78 -0
- package/dist/cjs/mixins/OxyServices.contacts.js +50 -0
- package/dist/cjs/mixins/OxyServices.deviceBoot.js +191 -0
- package/dist/cjs/mixins/OxyServices.deviceTransfer.js +314 -0
- package/dist/cjs/mixins/OxyServices.devices.js +116 -0
- package/dist/cjs/mixins/OxyServices.features.js +335 -0
- package/dist/cjs/mixins/OxyServices.followGraph.js +221 -0
- package/dist/cjs/mixins/OxyServices.identity.js +461 -0
- package/dist/cjs/mixins/OxyServices.identityBackup.js +172 -0
- package/dist/cjs/mixins/OxyServices.inference.js +59 -0
- package/dist/cjs/mixins/OxyServices.language.js +125 -0
- package/dist/cjs/mixins/OxyServices.links.js +72 -0
- package/dist/cjs/mixins/OxyServices.location.js +43 -0
- package/dist/cjs/mixins/OxyServices.nodes.js +175 -0
- package/dist/cjs/mixins/OxyServices.notifications.js +63 -0
- package/dist/cjs/mixins/OxyServices.payment.js +158 -0
- package/dist/cjs/mixins/OxyServices.privacy.js +199 -0
- package/dist/cjs/mixins/OxyServices.reputation.js +289 -0
- package/dist/cjs/mixins/OxyServices.security.js +89 -0
- package/dist/cjs/mixins/OxyServices.store.js +266 -0
- package/dist/cjs/mixins/OxyServices.topics.js +137 -0
- package/dist/cjs/mixins/OxyServices.user.js +902 -0
- package/dist/cjs/mixins/OxyServices.utility.js +1098 -0
- package/dist/cjs/mixins/index.js +135 -0
- package/dist/cjs/mixins/mixinHelpers.js +53 -0
- package/dist/cjs/models/Topic.js +16 -0
- package/dist/cjs/models/interfaces.js +20 -0
- package/dist/cjs/models/session.js +2 -0
- package/dist/cjs/server/auth.js +167 -0
- package/dist/cjs/server/capabilityTicket.js +192 -0
- package/dist/cjs/server/cors.js +225 -0
- package/dist/cjs/server/index.js +97 -0
- package/dist/cjs/server/rateLimit.js +207 -0
- package/dist/cjs/server/safeFetch.js +458 -0
- package/dist/cjs/server/securityHeaders.js +377 -0
- package/dist/cjs/server/userInvalidation.js +156 -0
- package/dist/cjs/server/verifySecret.js +50 -0
- package/dist/cjs/session/SessionClient.js +865 -0
- package/dist/cjs/session/accountDelegationAccess.js +48 -0
- package/dist/cjs/session/accountDialogController.js +1131 -0
- package/dist/cjs/session/accountSwitchTargets.js +81 -0
- package/dist/cjs/session/authStateStore.js +404 -0
- package/dist/cjs/session/createSessionClient.js +32 -0
- package/dist/cjs/session/deviceDirectory.js +143 -0
- package/dist/cjs/session/deviceSwitcherRows.js +76 -0
- package/dist/cjs/session/identityPin.js +256 -0
- package/dist/cjs/session/identitySession.js +135 -0
- package/dist/cjs/session/projectSessionState.js +121 -0
- package/dist/cjs/session/refresh.js +398 -0
- package/dist/cjs/session/sessionClientHost.js +34 -0
- package/dist/cjs/session/sharedDeviceCredential.js +247 -0
- package/dist/cjs/session/socketLoader.js +55 -0
- package/dist/cjs/shared/utils/colorUtils.js +153 -0
- package/dist/cjs/shared/utils/errorUtils.js +183 -0
- package/dist/cjs/shared/utils/index.js +49 -0
- package/dist/cjs/shared/utils/networkUtils.js +183 -0
- package/dist/cjs/shared/utils/themeUtils.js +106 -0
- package/dist/cjs/utils/accountCacheSweep.js +80 -0
- package/dist/cjs/utils/accountUtils.js +140 -0
- package/dist/cjs/utils/activityId.js +6 -0
- package/dist/cjs/utils/apiUtils.js +91 -0
- package/dist/cjs/utils/asyncUtils.js +222 -0
- package/dist/cjs/utils/authHelpers.js +120 -0
- package/dist/cjs/utils/authWebUrl.js +19 -0
- package/dist/cjs/utils/avatarUtils.js +29 -0
- package/dist/cjs/utils/cache.js +235 -0
- package/dist/cjs/utils/cacheKey.js +85 -0
- package/dist/cjs/utils/coldBoot.js +122 -0
- package/dist/cjs/utils/commonsApproval.js +31 -0
- package/dist/cjs/utils/commonsDelivery.js +59 -0
- package/dist/cjs/utils/deviceManager.js +174 -0
- package/dist/cjs/utils/displayNamePolicyRanges.generated.js +60 -0
- package/dist/cjs/utils/edgeRegion.js +6 -0
- package/dist/cjs/utils/errorUtils.js +243 -0
- package/dist/cjs/utils/identityCacheSweep.js +97 -0
- package/dist/cjs/utils/languageUtils.js +224 -0
- package/dist/cjs/utils/oauthPkce.js +311 -0
- package/dist/cjs/utils/officialOrigins.js +64 -0
- package/dist/cjs/utils/oxyServiceEnvironment.js +19 -0
- package/dist/cjs/utils/platform.js +119 -0
- package/dist/cjs/utils/profileLinks.js +63 -0
- package/dist/cjs/utils/redactUrl.js +29 -0
- package/dist/cjs/utils/registrableApex.js +45 -0
- package/dist/cjs/utils/requestUtils.js +209 -0
- package/dist/cjs/utils/sessionUtils.js +181 -0
- package/dist/cjs/utils/textNormalization.js +158 -0
- package/dist/cjs/utils/userHandle.js +37 -0
- package/dist/cjs/utils/userIdentity.js +50 -0
- package/dist/cjs/utils/validationUtils.js +370 -0
- package/dist/cjs/utils/webauthnOrigin.js +51 -0
- package/dist/esm/.tsbuildinfo +1 -0
- package/dist/esm/HttpService.js +1266 -0
- package/dist/esm/OxyServices.base.js +386 -0
- package/dist/esm/OxyServices.errors.js +88 -0
- package/dist/esm/OxyServices.js +66 -0
- package/dist/esm/boot/sessionColdBoot.js +392 -0
- package/dist/esm/constants/version.js +13 -0
- package/dist/esm/crypto/aead.js +74 -0
- package/dist/esm/crypto/ecdh.js +32 -0
- package/dist/esm/crypto/identityMarker.js +248 -0
- package/dist/esm/crypto/kdf.js +36 -0
- package/dist/esm/crypto/keyManager.js +2227 -0
- package/dist/esm/crypto/polyfill.js +129 -0
- package/dist/esm/crypto/recoveryPhrase.js +238 -0
- package/dist/esm/crypto/signatureService.js +269 -0
- package/dist/esm/i18n/accountCategoryLabels.js +37 -0
- package/dist/esm/i18n/accountRoleLabels.js +20 -0
- package/dist/esm/i18n/index.js +83 -0
- package/dist/esm/i18n/locales/ar-SA.json +282 -0
- package/dist/esm/i18n/locales/ca-ES.json +282 -0
- package/dist/esm/i18n/locales/de-DE.json +282 -0
- package/dist/esm/i18n/locales/en-US.json +2161 -0
- package/dist/esm/i18n/locales/es-ES.json +2161 -0
- package/dist/esm/i18n/locales/fr-FR.json +282 -0
- package/dist/esm/i18n/locales/it-IT.json +282 -0
- package/dist/esm/i18n/locales/ja-JP.json +282 -0
- package/dist/esm/i18n/locales/ko-KR.json +282 -0
- package/dist/esm/i18n/locales/locales/ar-SA.json +282 -0
- package/dist/esm/i18n/locales/locales/ca-ES.json +282 -0
- package/dist/esm/i18n/locales/locales/de-DE.json +282 -0
- package/dist/esm/i18n/locales/locales/en-US.json +2161 -0
- package/dist/esm/i18n/locales/locales/es-ES.json +2161 -0
- package/dist/esm/i18n/locales/locales/fr-FR.json +282 -0
- package/dist/esm/i18n/locales/locales/it-IT.json +282 -0
- package/dist/esm/i18n/locales/locales/ja-JP.json +282 -0
- package/dist/esm/i18n/locales/locales/ko-KR.json +282 -0
- package/dist/esm/i18n/locales/locales/pt-PT.json +282 -0
- package/dist/esm/i18n/locales/locales/zh-CN.json +282 -0
- package/dist/esm/i18n/locales/pt-PT.json +282 -0
- package/dist/esm/i18n/locales/zh-CN.json +282 -0
- package/dist/esm/i18n/reputationCategoryLabels.js +13 -0
- package/dist/esm/i18n/trustTierLabels.js +12 -0
- package/dist/esm/index.js +254 -0
- package/dist/esm/inference/OxyInferenceClient.js +538 -0
- package/dist/esm/logger/index.js +140 -0
- package/dist/esm/mixins/OxyServices.accounts.js +543 -0
- package/dist/esm/mixins/OxyServices.analytics.js +46 -0
- package/dist/esm/mixins/OxyServices.appData.js +103 -0
- package/dist/esm/mixins/OxyServices.assets.js +761 -0
- package/dist/esm/mixins/OxyServices.auth.js +1247 -0
- package/dist/esm/mixins/OxyServices.chains.js +70 -0
- package/dist/esm/mixins/OxyServices.civic.js +605 -0
- package/dist/esm/mixins/OxyServices.connectedApps.js +75 -0
- package/dist/esm/mixins/OxyServices.contacts.js +47 -0
- package/dist/esm/mixins/OxyServices.deviceBoot.js +186 -0
- package/dist/esm/mixins/OxyServices.deviceTransfer.js +311 -0
- package/dist/esm/mixins/OxyServices.devices.js +113 -0
- package/dist/esm/mixins/OxyServices.features.js +332 -0
- package/dist/esm/mixins/OxyServices.followGraph.js +218 -0
- package/dist/esm/mixins/OxyServices.identity.js +457 -0
- package/dist/esm/mixins/OxyServices.identityBackup.js +169 -0
- package/dist/esm/mixins/OxyServices.inference.js +56 -0
- package/dist/esm/mixins/OxyServices.language.js +122 -0
- package/dist/esm/mixins/OxyServices.links.js +69 -0
- package/dist/esm/mixins/OxyServices.location.js +40 -0
- package/dist/esm/mixins/OxyServices.nodes.js +172 -0
- package/dist/esm/mixins/OxyServices.notifications.js +60 -0
- package/dist/esm/mixins/OxyServices.payment.js +155 -0
- package/dist/esm/mixins/OxyServices.privacy.js +196 -0
- package/dist/esm/mixins/OxyServices.reputation.js +286 -0
- package/dist/esm/mixins/OxyServices.security.js +86 -0
- package/dist/esm/mixins/OxyServices.store.js +263 -0
- package/dist/esm/mixins/OxyServices.topics.js +134 -0
- package/dist/esm/mixins/OxyServices.user.js +899 -0
- package/dist/esm/mixins/OxyServices.utility.js +1095 -0
- package/dist/esm/mixins/index.js +132 -0
- package/dist/esm/mixins/mixinHelpers.js +48 -0
- package/dist/esm/models/Topic.js +13 -0
- package/dist/esm/models/interfaces.js +17 -0
- package/dist/esm/models/session.js +1 -0
- package/dist/esm/server/auth.js +154 -0
- package/dist/esm/server/capabilityTicket.js +183 -0
- package/dist/esm/server/cors.js +220 -0
- package/dist/esm/server/index.js +47 -0
- package/dist/esm/server/rateLimit.js +201 -0
- package/dist/esm/server/safeFetch.js +447 -0
- package/dist/esm/server/securityHeaders.js +364 -0
- package/dist/esm/server/userInvalidation.js +152 -0
- package/dist/esm/server/verifySecret.js +47 -0
- package/dist/esm/session/SessionClient.js +861 -0
- package/dist/esm/session/accountDelegationAccess.js +45 -0
- package/dist/esm/session/accountDialogController.js +1126 -0
- package/dist/esm/session/accountSwitchTargets.js +77 -0
- package/dist/esm/session/authStateStore.js +398 -0
- package/dist/esm/session/createSessionClient.js +29 -0
- package/dist/esm/session/deviceDirectory.js +135 -0
- package/dist/esm/session/deviceSwitcherRows.js +72 -0
- package/dist/esm/session/identityPin.js +249 -0
- package/dist/esm/session/identitySession.js +131 -0
- package/dist/esm/session/projectSessionState.js +114 -0
- package/dist/esm/session/refresh.js +390 -0
- package/dist/esm/session/sessionClientHost.js +31 -0
- package/dist/esm/session/sharedDeviceCredential.js +239 -0
- package/dist/esm/session/socketLoader.js +19 -0
- package/dist/esm/shared/utils/colorUtils.js +143 -0
- package/dist/esm/shared/utils/errorUtils.js +170 -0
- package/dist/esm/shared/utils/index.js +15 -0
- package/dist/esm/shared/utils/networkUtils.js +173 -0
- package/dist/esm/shared/utils/themeUtils.js +98 -0
- package/dist/esm/utils/accountCacheSweep.js +75 -0
- package/dist/esm/utils/accountUtils.js +131 -0
- package/dist/esm/utils/activityId.js +2 -0
- package/dist/esm/utils/apiUtils.js +84 -0
- package/dist/esm/utils/asyncUtils.js +207 -0
- package/dist/esm/utils/authHelpers.js +111 -0
- package/dist/esm/utils/authWebUrl.js +16 -0
- package/dist/esm/utils/avatarUtils.js +26 -0
- package/dist/esm/utils/cache.js +227 -0
- package/dist/esm/utils/cacheKey.js +80 -0
- package/dist/esm/utils/coldBoot.js +119 -0
- package/dist/esm/utils/commonsApproval.js +27 -0
- package/dist/esm/utils/commonsDelivery.js +54 -0
- package/dist/esm/utils/deviceManager.js +170 -0
- package/dist/esm/utils/displayNamePolicyRanges.generated.js +57 -0
- package/dist/esm/utils/edgeRegion.js +2 -0
- package/dist/esm/utils/errorUtils.js +232 -0
- package/dist/esm/utils/identityCacheSweep.js +92 -0
- package/dist/esm/utils/languageUtils.js +212 -0
- package/dist/esm/utils/oauthPkce.js +297 -0
- package/dist/esm/utils/officialOrigins.js +59 -0
- package/dist/esm/utils/oxyServiceEnvironment.js +16 -0
- package/dist/esm/utils/platform.js +110 -0
- package/dist/esm/utils/profileLinks.js +60 -0
- package/dist/esm/utils/redactUrl.js +26 -0
- package/dist/esm/utils/registrableApex.js +42 -0
- package/dist/esm/utils/requestUtils.js +203 -0
- package/dist/esm/utils/sessionUtils.js +171 -0
- package/dist/esm/utils/textNormalization.js +154 -0
- package/dist/esm/utils/userHandle.js +33 -0
- package/dist/esm/utils/userIdentity.js +45 -0
- package/dist/esm/utils/validationUtils.js +350 -0
- package/dist/esm/utils/webauthnOrigin.js +48 -0
- package/dist/types/.tsbuildinfo +1 -0
- package/dist/types/HttpService.d.ts +413 -0
- package/dist/types/OxyServices.base.d.ts +187 -0
- package/dist/types/OxyServices.d.ts +139 -0
- package/dist/types/OxyServices.errors.d.ts +84 -0
- package/dist/types/boot/sessionColdBoot.d.ts +140 -0
- package/dist/types/constants/version.d.ts +13 -0
- package/dist/types/crypto/aead.d.ts +56 -0
- package/dist/types/crypto/ecdh.d.ts +29 -0
- package/dist/types/crypto/identityMarker.d.ts +94 -0
- package/dist/types/crypto/kdf.d.ts +25 -0
- package/dist/types/crypto/keyManager.d.ts +582 -0
- package/dist/types/crypto/polyfill.d.ts +25 -0
- package/dist/types/crypto/recoveryPhrase.d.ts +173 -0
- package/dist/types/crypto/signatureService.d.ts +136 -0
- package/dist/types/i18n/accountCategoryLabels.d.ts +34 -0
- package/dist/types/i18n/accountRoleLabels.d.ts +10 -0
- package/dist/types/i18n/index.d.ts +3 -0
- package/dist/types/i18n/reputationCategoryLabels.d.ts +10 -0
- package/dist/types/i18n/trustTierLabels.d.ts +9 -0
- package/dist/types/index.d.ts +145 -0
- package/dist/types/inference/OxyInferenceClient.d.ts +342 -0
- package/dist/types/logger/index.d.ts +104 -0
- package/dist/types/mixins/OxyServices.accounts.d.ts +868 -0
- package/dist/types/mixins/OxyServices.analytics.d.ts +72 -0
- package/dist/types/mixins/OxyServices.appData.d.ts +108 -0
- package/dist/types/mixins/OxyServices.assets.d.ts +329 -0
- package/dist/types/mixins/OxyServices.auth.d.ts +908 -0
- package/dist/types/mixins/OxyServices.chains.d.ts +156 -0
- package/dist/types/mixins/OxyServices.civic.d.ts +510 -0
- package/dist/types/mixins/OxyServices.connectedApps.d.ts +169 -0
- package/dist/types/mixins/OxyServices.contacts.d.ts +100 -0
- package/dist/types/mixins/OxyServices.deviceBoot.d.ts +185 -0
- package/dist/types/mixins/OxyServices.deviceTransfer.d.ts +149 -0
- package/dist/types/mixins/OxyServices.devices.d.ts +103 -0
- package/dist/types/mixins/OxyServices.features.d.ts +250 -0
- package/dist/types/mixins/OxyServices.followGraph.d.ts +223 -0
- package/dist/types/mixins/OxyServices.identity.d.ts +351 -0
- package/dist/types/mixins/OxyServices.identityBackup.d.ts +129 -0
- package/dist/types/mixins/OxyServices.inference.d.ts +95 -0
- package/dist/types/mixins/OxyServices.language.d.ts +87 -0
- package/dist/types/mixins/OxyServices.links.d.ts +104 -0
- package/dist/types/mixins/OxyServices.location.d.ts +70 -0
- package/dist/types/mixins/OxyServices.nodes.d.ts +198 -0
- package/dist/types/mixins/OxyServices.notifications.d.ts +143 -0
- package/dist/types/mixins/OxyServices.payment.d.ts +117 -0
- package/dist/types/mixins/OxyServices.privacy.d.ts +146 -0
- package/dist/types/mixins/OxyServices.reputation.d.ts +202 -0
- package/dist/types/mixins/OxyServices.security.d.ts +84 -0
- package/dist/types/mixins/OxyServices.store.d.ts +334 -0
- package/dist/types/mixins/OxyServices.topics.d.ts +110 -0
- package/dist/types/mixins/OxyServices.user.d.ts +558 -0
- package/dist/types/mixins/OxyServices.utility.d.ts +393 -0
- package/dist/types/mixins/index.d.ts +87 -0
- package/dist/types/mixins/mixinHelpers.d.ts +31 -0
- package/dist/types/models/Topic.d.ts +42 -0
- package/dist/types/models/interfaces.d.ts +675 -0
- package/dist/types/models/session.d.ts +51 -0
- package/dist/types/server/auth.d.ts +130 -0
- package/dist/types/server/capabilityTicket.d.ts +41 -0
- package/dist/types/server/cors.d.ts +98 -0
- package/dist/types/server/index.d.ts +35 -0
- package/dist/types/server/rateLimit.d.ts +40 -0
- package/dist/types/server/safeFetch.d.ts +137 -0
- package/dist/types/server/securityHeaders.d.ts +221 -0
- package/dist/types/server/userInvalidation.d.ts +114 -0
- package/dist/types/server/verifySecret.d.ts +29 -0
- package/dist/types/session/SessionClient.d.ts +418 -0
- package/dist/types/session/accountDelegationAccess.d.ts +40 -0
- package/dist/types/session/accountDialogController.d.ts +648 -0
- package/dist/types/session/accountSwitchTargets.d.ts +70 -0
- package/dist/types/session/authStateStore.d.ts +153 -0
- package/dist/types/session/createSessionClient.d.ts +30 -0
- package/dist/types/session/deviceDirectory.d.ts +182 -0
- package/dist/types/session/deviceSwitcherRows.d.ts +92 -0
- package/dist/types/session/identityPin.d.ts +87 -0
- package/dist/types/session/identitySession.d.ts +105 -0
- package/dist/types/session/projectSessionState.d.ts +74 -0
- package/dist/types/session/refresh.d.ts +179 -0
- package/dist/types/session/sessionClientHost.d.ts +18 -0
- package/dist/types/session/sharedDeviceCredential.d.ts +202 -0
- package/dist/types/session/socketLoader.d.ts +11 -0
- package/dist/types/shared/utils/colorUtils.d.ts +104 -0
- package/dist/types/shared/utils/errorUtils.d.ts +97 -0
- package/dist/types/shared/utils/index.d.ts +13 -0
- package/dist/types/shared/utils/networkUtils.d.ts +139 -0
- package/dist/types/shared/utils/themeUtils.d.ts +90 -0
- package/dist/types/utils/accountCacheSweep.d.ts +75 -0
- package/dist/types/utils/accountUtils.d.ts +100 -0
- package/dist/types/utils/activityId.d.ts +2 -0
- package/dist/types/utils/apiUtils.d.ts +95 -0
- package/dist/types/utils/asyncUtils.d.ts +62 -0
- package/dist/types/utils/authHelpers.d.ts +58 -0
- package/dist/types/utils/authWebUrl.d.ts +16 -0
- package/dist/types/utils/avatarUtils.d.ts +16 -0
- package/dist/types/utils/cache.d.ts +130 -0
- package/dist/types/utils/cacheKey.d.ts +66 -0
- package/dist/types/utils/coldBoot.d.ts +131 -0
- package/dist/types/utils/commonsApproval.d.ts +13 -0
- package/dist/types/utils/commonsDelivery.d.ts +105 -0
- package/dist/types/utils/deviceManager.d.ts +65 -0
- package/dist/types/utils/displayNamePolicyRanges.generated.d.ts +57 -0
- package/dist/types/utils/edgeRegion.d.ts +2 -0
- package/dist/types/utils/errorUtils.d.ts +125 -0
- package/dist/types/utils/identityCacheSweep.d.ts +80 -0
- package/dist/types/utils/languageUtils.d.ts +100 -0
- package/dist/types/utils/oauthPkce.d.ts +157 -0
- package/dist/types/utils/officialOrigins.d.ts +13 -0
- package/dist/types/utils/oxyServiceEnvironment.d.ts +17 -0
- package/dist/types/utils/platform.d.ts +49 -0
- package/dist/types/utils/profileLinks.d.ts +44 -0
- package/dist/types/utils/redactUrl.d.ts +17 -0
- package/dist/types/utils/registrableApex.d.ts +27 -0
- package/dist/types/utils/requestUtils.d.ts +123 -0
- package/dist/types/utils/sessionUtils.d.ts +54 -0
- package/dist/types/utils/textNormalization.d.ts +103 -0
- package/dist/types/utils/userHandle.d.ts +26 -0
- package/dist/types/utils/userIdentity.d.ts +21 -0
- package/dist/types/utils/validationUtils.d.ts +268 -0
- package/dist/types/utils/webauthnOrigin.d.ts +32 -0
- package/package.json +168 -0
- package/src/HttpService.ts +1553 -0
- package/src/OxyServices.base.ts +478 -0
- package/src/OxyServices.errors.ts +122 -0
- package/src/OxyServices.ts +172 -0
- package/src/__tests__/authSocket.test.ts +96 -0
- package/src/__tests__/httpServiceActivityId.test.ts +49 -0
- package/src/__tests__/httpServiceAuthSelfAwait.test.ts +108 -0
- package/src/__tests__/httpServiceCache.test.ts +318 -0
- package/src/__tests__/httpServiceCsrf.test.ts +235 -0
- package/src/__tests__/httpServiceFormEncoded.test.ts +142 -0
- package/src/__tests__/httpServiceQueueDeadlock.test.ts +128 -0
- package/src/__tests__/httpServiceUnwrapEnvelope.test.ts +115 -0
- package/src/__tests__/inSessionRefresh.test.ts +260 -0
- package/src/__tests__/linkedClient.test.ts +370 -0
- package/src/__tests__/parseHttpErrorBody.test.ts +116 -0
- package/src/__tests__/serverValueImportsDeclared.test.ts +120 -0
- package/src/__tests__/userIdentity.test.ts +143 -0
- package/src/boot/__tests__/sessionColdBoot.identity.test.ts +393 -0
- package/src/boot/__tests__/sessionColdBoot.sharedDevice.test.ts +325 -0
- package/src/boot/__tests__/sessionColdBoot.test.ts +570 -0
- package/src/boot/sessionColdBoot.ts +529 -0
- package/src/constants/version.ts +15 -0
- package/src/crypto/__tests__/backupMaterial.test.ts +86 -0
- package/src/crypto/__tests__/cryptoPrimitives.test.ts +226 -0
- package/src/crypto/__tests__/identityMocks.ts +125 -0
- package/src/crypto/__tests__/keyManager.atomicity.test.ts +272 -0
- package/src/crypto/__tests__/keyManager.cacheSafety.test.ts +175 -0
- package/src/crypto/__tests__/keyManager.identityStatus.test.ts +217 -0
- package/src/crypto/__tests__/keyManager.recoveryLadder.test.ts +179 -0
- package/src/crypto/__tests__/keyManager.recoveryMnemonic.test.ts +138 -0
- package/src/crypto/__tests__/keyManager.storageMigration.test.ts +227 -0
- package/src/crypto/__tests__/keyManager.test.ts +329 -0
- package/src/crypto/__tests__/polyfill.test.ts +109 -0
- package/src/crypto/__tests__/recoveryPhrase.test.ts +61 -0
- package/src/crypto/__tests__/scopedSeed.test.ts +126 -0
- package/src/crypto/__tests__/signChallengeShared.test.ts +63 -0
- package/src/crypto/__tests__/signedRecord.test.ts +230 -0
- package/src/crypto/aead.ts +97 -0
- package/src/crypto/ecdh.ts +37 -0
- package/src/crypto/identityMarker.ts +291 -0
- package/src/crypto/kdf.ts +43 -0
- package/src/crypto/keyManager.ts +2607 -0
- package/src/crypto/polyfill.ts +143 -0
- package/src/crypto/recoveryPhrase.ts +337 -0
- package/src/crypto/signatureService.ts +350 -0
- package/src/i18n/__tests__/accountCategoryLabels.test.ts +62 -0
- package/src/i18n/__tests__/accountRoleLabels.test.ts +54 -0
- package/src/i18n/__tests__/reputationCategoryLabels.test.ts +56 -0
- package/src/i18n/__tests__/trustTierLabels.test.ts +47 -0
- package/src/i18n/accountCategoryLabels.ts +44 -0
- package/src/i18n/accountRoleLabels.ts +26 -0
- package/src/i18n/index.ts +88 -0
- package/src/i18n/locales/ar-SA.json +282 -0
- package/src/i18n/locales/ca-ES.json +282 -0
- package/src/i18n/locales/de-DE.json +282 -0
- package/src/i18n/locales/en-US.json +2161 -0
- package/src/i18n/locales/es-ES.json +2161 -0
- package/src/i18n/locales/fr-FR.json +282 -0
- package/src/i18n/locales/it-IT.json +282 -0
- package/src/i18n/locales/ja-JP.json +282 -0
- package/src/i18n/locales/ko-KR.json +282 -0
- package/src/i18n/locales/pt-PT.json +282 -0
- package/src/i18n/locales/zh-CN.json +282 -0
- package/src/i18n/reputationCategoryLabels.ts +20 -0
- package/src/i18n/trustTierLabels.ts +18 -0
- package/src/index.ts +881 -0
- package/src/inference/OxyInferenceClient.ts +888 -0
- package/src/inference/__tests__/OxyInferenceClient.test.ts +834 -0
- package/src/logger/__tests__/logger.test.ts +207 -0
- package/src/logger/index.ts +217 -0
- package/src/mixins/OxyServices.accounts.ts +1330 -0
- package/src/mixins/OxyServices.analytics.ts +53 -0
- package/src/mixins/OxyServices.appData.ts +158 -0
- package/src/mixins/OxyServices.assets.ts +861 -0
- package/src/mixins/OxyServices.auth.ts +1858 -0
- package/src/mixins/OxyServices.chains.ts +134 -0
- package/src/mixins/OxyServices.civic.ts +945 -0
- package/src/mixins/OxyServices.connectedApps.ts +174 -0
- package/src/mixins/OxyServices.contacts.ts +73 -0
- package/src/mixins/OxyServices.deviceBoot.ts +210 -0
- package/src/mixins/OxyServices.deviceTransfer.ts +393 -0
- package/src/mixins/OxyServices.devices.ts +120 -0
- package/src/mixins/OxyServices.features.ts +454 -0
- package/src/mixins/OxyServices.followGraph.ts +293 -0
- package/src/mixins/OxyServices.identity.ts +705 -0
- package/src/mixins/OxyServices.identityBackup.ts +250 -0
- package/src/mixins/OxyServices.inference.ts +57 -0
- package/src/mixins/OxyServices.language.ts +144 -0
- package/src/mixins/OxyServices.links.ts +107 -0
- package/src/mixins/OxyServices.location.ts +46 -0
- package/src/mixins/OxyServices.nodes.ts +337 -0
- package/src/mixins/OxyServices.notifications.ts +142 -0
- package/src/mixins/OxyServices.payment.ts +163 -0
- package/src/mixins/OxyServices.privacy.ts +219 -0
- package/src/mixins/OxyServices.reputation.ts +436 -0
- package/src/mixins/OxyServices.security.ts +110 -0
- package/src/mixins/OxyServices.store.ts +585 -0
- package/src/mixins/OxyServices.topics.ts +169 -0
- package/src/mixins/OxyServices.user.ts +1137 -0
- package/src/mixins/OxyServices.utility.ts +1370 -0
- package/src/mixins/__tests__/OxyServices.civic.test.ts +1095 -0
- package/src/mixins/__tests__/OxyServices.deviceBoot.test.ts +124 -0
- package/src/mixins/__tests__/OxyServices.deviceTransfer.test.ts +271 -0
- package/src/mixins/__tests__/OxyServices.identity.test.ts +376 -0
- package/src/mixins/__tests__/OxyServices.links.test.ts +154 -0
- package/src/mixins/__tests__/OxyServices.nodes.test.ts +341 -0
- package/src/mixins/__tests__/OxyServices.rotateKey.test.ts +276 -0
- package/src/mixins/__tests__/OxyServices.serviceAssetMetadata.test.ts +192 -0
- package/src/mixins/__tests__/OxyServices.serviceAssetMetadataBySha.test.ts +135 -0
- package/src/mixins/__tests__/accounts.test.ts +727 -0
- package/src/mixins/__tests__/appData.test.ts +203 -0
- package/src/mixins/__tests__/assetCredentials.test.ts +47 -0
- package/src/mixins/__tests__/assetUpload.test.ts +191 -0
- package/src/mixins/__tests__/backgroundCredential.httpIntegration.test.ts +135 -0
- package/src/mixins/__tests__/chains.test.ts +113 -0
- package/src/mixins/__tests__/commonsSignIn.test.ts +1144 -0
- package/src/mixins/__tests__/connectedApps.test.ts +123 -0
- package/src/mixins/__tests__/deviceTokenMintPinned.test.ts +113 -0
- package/src/mixins/__tests__/discoveryErrorHandling.test.ts +266 -0
- package/src/mixins/__tests__/followCacheInvalidation.test.ts +173 -0
- package/src/mixins/__tests__/followGraph.test.ts +147 -0
- package/src/mixins/__tests__/followGraphPagination.test.ts +271 -0
- package/src/mixins/__tests__/getFileDownloadUrl.test.ts +346 -0
- package/src/mixins/__tests__/getFollowStatuses.test.ts +95 -0
- package/src/mixins/__tests__/getUsersByIds.test.ts +149 -0
- package/src/mixins/__tests__/identityBackup.test.ts +315 -0
- package/src/mixins/__tests__/identityWriteCacheInvalidation.test.ts +407 -0
- package/src/mixins/__tests__/inferenceFactory.test.ts +58 -0
- package/src/mixins/__tests__/onTokensChanged.test.ts +129 -0
- package/src/mixins/__tests__/preSessionSkipAuth.test.ts +284 -0
- package/src/mixins/__tests__/privacyCacheInvalidation.test.ts +155 -0
- package/src/mixins/__tests__/reputation.test.ts +522 -0
- package/src/mixins/__tests__/serviceAuth.test.ts +832 -0
- package/src/mixins/__tests__/serviceTokenJwks.test.ts +208 -0
- package/src/mixins/__tests__/store.test.ts +304 -0
- package/src/mixins/__tests__/topics.test.ts +156 -0
- package/src/mixins/__tests__/userReadCacheBypass.test.ts +129 -0
- package/src/mixins/__tests__/userTokenAuth.test.ts +746 -0
- package/src/mixins/__tests__/verifyChallenge.test.ts +130 -0
- package/src/mixins/__tests__/verifyServiceActingAs.test.ts +167 -0
- package/src/mixins/__tests__/webauthnAuth.test.ts +205 -0
- package/src/mixins/index.ts +201 -0
- package/src/mixins/mixinHelpers.ts +69 -0
- package/src/models/Topic.ts +46 -0
- package/src/models/interfaces.ts +786 -0
- package/src/models/session.ts +55 -0
- package/src/server/__tests__/auth.test.ts +78 -0
- package/src/server/__tests__/capabilityTicket.test.ts +111 -0
- package/src/server/__tests__/cors.socket.test.ts +225 -0
- package/src/server/__tests__/cors.test.ts +158 -0
- package/src/server/__tests__/rateLimit.test.ts +257 -0
- package/src/server/__tests__/safeFetch.test.ts +232 -0
- package/src/server/__tests__/securityHeaders.test.ts +348 -0
- package/src/server/__tests__/serviceTokenAttribution.test.ts +396 -0
- package/src/server/__tests__/userInvalidation.test.ts +203 -0
- package/src/server/__tests__/verifySecret.test.ts +40 -0
- package/src/server/auth.ts +271 -0
- package/src/server/capabilityTicket.ts +258 -0
- package/src/server/cors.ts +277 -0
- package/src/server/index.ts +136 -0
- package/src/server/rateLimit.ts +313 -0
- package/src/server/safeFetch.ts +586 -0
- package/src/server/securityHeaders.ts +467 -0
- package/src/server/userInvalidation.ts +199 -0
- package/src/server/verifySecret.ts +52 -0
- package/src/session/SessionClient.ts +1001 -0
- package/src/session/__tests__/SessionClient.additive.test.ts +153 -0
- package/src/session/__tests__/SessionClient.broadcastChannel.test.ts +114 -0
- package/src/session/__tests__/SessionClient.diagnostics.test.ts +91 -0
- package/src/session/__tests__/SessionClient.directory.test.ts +688 -0
- package/src/session/__tests__/SessionClient.httpIntegration.test.ts +65 -0
- package/src/session/__tests__/SessionClient.identityPin.test.ts +175 -0
- package/src/session/__tests__/SessionClient.rest.test.ts +119 -0
- package/src/session/__tests__/SessionClient.serverEvents.test.ts +72 -0
- package/src/session/__tests__/SessionClient.socket.test.ts +202 -0
- package/src/session/__tests__/SessionClient.socketFactory.test.ts +81 -0
- package/src/session/__tests__/SessionClient.state.test.ts +78 -0
- package/src/session/__tests__/SessionClient.switchTokenOrder.test.ts +170 -0
- package/src/session/__tests__/accountDelegationAccess.test.ts +104 -0
- package/src/session/__tests__/accountDialogController.test.ts +1969 -0
- package/src/session/__tests__/accountDialogShape.test.ts +118 -0
- package/src/session/__tests__/accountSwitchTargets.test.ts +137 -0
- package/src/session/__tests__/authStateStore.test.ts +451 -0
- package/src/session/__tests__/deviceDirectory.test.ts +422 -0
- package/src/session/__tests__/deviceSwitcherRows.test.ts +223 -0
- package/src/session/__tests__/identityPin.test.ts +131 -0
- package/src/session/__tests__/identitySession.test.ts +194 -0
- package/src/session/__tests__/projectSessionState.test.ts +105 -0
- package/src/session/__tests__/refresh.identityPin.test.ts +307 -0
- package/src/session/__tests__/refresh.test.ts +443 -0
- package/src/session/__tests__/sessionIntegration.test.ts +209 -0
- package/src/session/__tests__/sharedDeviceCredential.test.ts +300 -0
- package/src/session/accountDelegationAccess.ts +72 -0
- package/src/session/accountDialogController.ts +1494 -0
- package/src/session/accountSwitchTargets.ts +93 -0
- package/src/session/authStateStore.ts +502 -0
- package/src/session/createSessionClient.ts +39 -0
- package/src/session/deviceDirectory.ts +269 -0
- package/src/session/deviceSwitcherRows.ts +145 -0
- package/src/session/identityPin.ts +310 -0
- package/src/session/identitySession.ts +206 -0
- package/src/session/projectSessionState.ts +137 -0
- package/src/session/refresh.ts +517 -0
- package/src/session/sessionClientHost.ts +39 -0
- package/src/session/sharedDeviceCredential.ts +349 -0
- package/src/session/socketLoader.ts +30 -0
- package/src/shared/utils/colorUtils.ts +155 -0
- package/src/shared/utils/errorUtils.ts +181 -0
- package/src/shared/utils/index.ts +59 -0
- package/src/shared/utils/networkUtils.ts +248 -0
- package/src/shared/utils/themeUtils.ts +115 -0
- package/src/types/buffer.d.ts +97 -0
- package/src/types/expo-crypto.d.ts +16 -0
- package/src/types/expo-secure-store.d.ts +17 -0
- package/src/utils/__tests__/accountUtils.test.ts +151 -0
- package/src/utils/__tests__/activityId.test.ts +45 -0
- package/src/utils/__tests__/asyncUtils.test.ts +187 -0
- package/src/utils/__tests__/authWebUrl.test.ts +15 -0
- package/src/utils/__tests__/cacheKey.test.ts +0 -0
- package/src/utils/__tests__/coldBoot.test.ts +496 -0
- package/src/utils/__tests__/commonsApproval.test.ts +60 -0
- package/src/utils/__tests__/identityCacheSweep.test.ts +151 -0
- package/src/utils/__tests__/languageUtils.test.ts +219 -0
- package/src/utils/__tests__/oauthPkce.test.ts +272 -0
- package/src/utils/__tests__/officialOrigins.test.ts +31 -0
- package/src/utils/__tests__/oxyServiceEnvironment.test.ts +7 -0
- package/src/utils/__tests__/profileLinks.test.ts +180 -0
- package/src/utils/__tests__/redactUrl.test.ts +33 -0
- package/src/utils/__tests__/registrableApex.test.ts +62 -0
- package/src/utils/__tests__/textNormalization.test.ts +205 -0
- package/src/utils/__tests__/validationUtils.test.ts +703 -0
- package/src/utils/__tests__/webauthnOrigin.test.ts +83 -0
- package/src/utils/accountCacheSweep.ts +93 -0
- package/src/utils/accountUtils.ts +194 -0
- package/src/utils/activityId.ts +2 -0
- package/src/utils/apiUtils.ts +137 -0
- package/src/utils/asyncUtils.ts +280 -0
- package/src/utils/authHelpers.ts +148 -0
- package/src/utils/authWebUrl.ts +17 -0
- package/src/utils/avatarUtils.ts +39 -0
- package/src/utils/cache.ts +273 -0
- package/src/utils/cacheKey.ts +93 -0
- package/src/utils/coldBoot.ts +218 -0
- package/src/utils/commonsApproval.ts +39 -0
- package/src/utils/commonsDelivery.ts +132 -0
- package/src/utils/deviceManager.ts +203 -0
- package/src/utils/displayNamePolicyRanges.generated.ts +69 -0
- package/src/utils/edgeRegion.ts +2 -0
- package/src/utils/errorUtils.ts +352 -0
- package/src/utils/identityCacheSweep.ts +104 -0
- package/src/utils/languageUtils.ts +256 -0
- package/src/utils/oauthPkce.ts +392 -0
- package/src/utils/officialOrigins.ts +62 -0
- package/src/utils/oxyServiceEnvironment.ts +17 -0
- package/src/utils/platform.ts +139 -0
- package/src/utils/profileLinks.ts +91 -0
- package/src/utils/redactUrl.ts +28 -0
- package/src/utils/registrableApex.ts +41 -0
- package/src/utils/requestUtils.ts +237 -0
- package/src/utils/sessionUtils.ts +206 -0
- package/src/utils/textNormalization.ts +162 -0
- package/src/utils/userHandle.ts +49 -0
- package/src/utils/userIdentity.ts +60 -0
- package/src/utils/validationUtils.ts +390 -0
- package/src/utils/webauthnOrigin.ts +52 -0
|
@@ -0,0 +1,271 @@
|
|
|
1
|
+
import type { NextFunction, Request, RequestHandler, Response } from 'express';
|
|
2
|
+
import type { OxyServices } from '../OxyServices';
|
|
3
|
+
import { OXY_SERVICE_ENVIRONMENTS, type OxyServiceEnvironment } from '../utils/oxyServiceEnvironment';
|
|
4
|
+
|
|
5
|
+
export { OXY_SERVICE_ENVIRONMENTS };
|
|
6
|
+
export type { OxyServiceEnvironment };
|
|
7
|
+
|
|
8
|
+
export interface OxyRequestUser {
|
|
9
|
+
id: string;
|
|
10
|
+
_id?: string;
|
|
11
|
+
username?: string;
|
|
12
|
+
email?: string;
|
|
13
|
+
avatar?: string;
|
|
14
|
+
[key: string]: unknown;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export interface OxyServiceAppContext {
|
|
18
|
+
appId: string;
|
|
19
|
+
appName: string;
|
|
20
|
+
scopes: string[];
|
|
21
|
+
credentialId: string;
|
|
22
|
+
/**
|
|
23
|
+
* The Oxy account that owns `appId` and is financially responsible for it.
|
|
24
|
+
* Read off the VERIFIED service-token claim set — never a user id, and never
|
|
25
|
+
* the delegated `X-Oxy-User-Id` (ADR 0007).
|
|
26
|
+
*/
|
|
27
|
+
ownerAccountId: string;
|
|
28
|
+
environment: OxyServiceEnvironment;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export interface OxyServiceActingAsContext {
|
|
32
|
+
userId: string;
|
|
33
|
+
scopes: string[];
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export interface OxyAuthRequest extends Request {
|
|
37
|
+
userId?: string | null;
|
|
38
|
+
user?: OxyRequestUser | null;
|
|
39
|
+
accessToken?: string;
|
|
40
|
+
sessionId?: string | null;
|
|
41
|
+
serviceApp?: OxyServiceAppContext;
|
|
42
|
+
serviceActingAs?: OxyServiceActingAsContext;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export interface OxyAuthenticatedRequest extends OxyAuthRequest {
|
|
46
|
+
userId: string;
|
|
47
|
+
user: OxyRequestUser;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export interface OxyAuthMiddlewareOptions {
|
|
51
|
+
/**
|
|
52
|
+
* Options forwarded to `oxy.auth()`.
|
|
53
|
+
* `optional` is forced to `true` by the composed helpers so route guards can
|
|
54
|
+
* produce one consistent 401 shape.
|
|
55
|
+
*/
|
|
56
|
+
auth?: Parameters<OxyServices['auth']>[0];
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
function normalizeId(value: string | null | undefined): string | null {
|
|
60
|
+
const normalized = value?.trim();
|
|
61
|
+
return normalized && normalized.length > 0 ? normalized : null;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
function ensureUser(req: OxyAuthRequest, userId: string): OxyRequestUser {
|
|
65
|
+
const existing = req.user;
|
|
66
|
+
if (existing) {
|
|
67
|
+
const user = {
|
|
68
|
+
...existing,
|
|
69
|
+
id: normalizeId(existing.id) ?? normalizeId(existing._id) ?? userId,
|
|
70
|
+
};
|
|
71
|
+
req.user = user;
|
|
72
|
+
return user;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
const user = { id: userId };
|
|
76
|
+
req.user = user;
|
|
77
|
+
return user;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
export function getOxyUserId(req: Request): string | null {
|
|
81
|
+
const authReq = req as OxyAuthRequest;
|
|
82
|
+
return (
|
|
83
|
+
normalizeId(authReq.userId) ??
|
|
84
|
+
normalizeId(authReq.user?.id) ??
|
|
85
|
+
normalizeId(authReq.user?._id)
|
|
86
|
+
);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
export function isOxyAuthenticated(req: Request): req is OxyAuthenticatedRequest {
|
|
90
|
+
return getOxyUserId(req) !== null;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* The principal a request is CHARGED to, and the identifiers a receipt needs.
|
|
95
|
+
*
|
|
96
|
+
* Every field is read from the verified service-token claim set. It is an
|
|
97
|
+
* OBJECT, not a string, and that is the point: `getOxyUserId` returns a
|
|
98
|
+
* `string | null`, so a delegated end-user id cannot be passed anywhere an
|
|
99
|
+
* `OxyBillingPrincipal` is expected. The confusion ADR 0007 forbids —
|
|
100
|
+
* attributing spend to the person a service is acting for rather than to the
|
|
101
|
+
* service's own account — stops being a code-review question and becomes a
|
|
102
|
+
* compile error.
|
|
103
|
+
*
|
|
104
|
+
* `scopes` are the effective scopes minted into the token (credential ∩
|
|
105
|
+
* application). Nothing re-intersects them here.
|
|
106
|
+
*/
|
|
107
|
+
export interface OxyBillingPrincipal {
|
|
108
|
+
/** `applications.owner_account_id` — the financially responsible account. */
|
|
109
|
+
readonly accountId: string;
|
|
110
|
+
readonly applicationId: string;
|
|
111
|
+
readonly credentialId: string;
|
|
112
|
+
readonly environment: OxyServiceEnvironment;
|
|
113
|
+
readonly scopes: readonly string[];
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* The full canonical attribution of ADR 0007 for a request: the billing
|
|
118
|
+
* principal PLUS the optional delegated end user.
|
|
119
|
+
*
|
|
120
|
+
* `delegatedUserId` is named for what it is. It answers "on whose behalf" and
|
|
121
|
+
* is absent for a machine credential acting for itself — its absence is normal,
|
|
122
|
+
* and nothing may synthesize one. If removing it would change what any account
|
|
123
|
+
* is charged, the code reading it is wrong.
|
|
124
|
+
*/
|
|
125
|
+
export interface OxyRequestAttribution extends OxyBillingPrincipal {
|
|
126
|
+
readonly delegatedUserId: string | null;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* The billing principal of a request, or `null` when the request carries no
|
|
131
|
+
* verified service principal (an ordinary user session is not a billable
|
|
132
|
+
* machine principal — its account is resolved from the account graph, not from
|
|
133
|
+
* a token claim).
|
|
134
|
+
*
|
|
135
|
+
* Reads `req.serviceApp` and NOTHING else: not `req.userId`, not `req.user`,
|
|
136
|
+
* not `req.serviceActingAs`. That exclusivity is the invariant this function
|
|
137
|
+
* exists to hold, and `serviceTokenAttribution.test.ts` mutation-tests it.
|
|
138
|
+
*
|
|
139
|
+
* **It answers for the SERVICE-TOKEN lane only.** The API's machine-credential
|
|
140
|
+
* lane (`oxy_sk_*`, issue #972 §2.3) resolves the same five facts into its own
|
|
141
|
+
* `req.machineCredential`, deliberately never `req.serviceApp` — populating the
|
|
142
|
+
* latter would hand a self-serve third-party credential the lane that only
|
|
143
|
+
* platform-trusted applications may enter. So a machine-credential request has
|
|
144
|
+
* no billing principal HERE and resolves `null`, which fails closed: the caller
|
|
145
|
+
* must handle it, and `getRequiredOxyBillingPrincipal` throws rather than
|
|
146
|
+
* charging anyone. One accessor answering for both lanes belongs to the public
|
|
147
|
+
* inference edge that has to admit both, and it needs the machine principal's
|
|
148
|
+
* shape to move into this package first.
|
|
149
|
+
*/
|
|
150
|
+
export function getOxyBillingPrincipal(req: Request): OxyBillingPrincipal | null {
|
|
151
|
+
const serviceApp = (req as OxyAuthRequest).serviceApp;
|
|
152
|
+
if (!serviceApp) {
|
|
153
|
+
return null;
|
|
154
|
+
}
|
|
155
|
+
const accountId = normalizeId(serviceApp.ownerAccountId);
|
|
156
|
+
const applicationId = normalizeId(serviceApp.appId);
|
|
157
|
+
const credentialId = normalizeId(serviceApp.credentialId);
|
|
158
|
+
if (!accountId || !applicationId || !credentialId) {
|
|
159
|
+
return null;
|
|
160
|
+
}
|
|
161
|
+
return {
|
|
162
|
+
accountId,
|
|
163
|
+
applicationId,
|
|
164
|
+
credentialId,
|
|
165
|
+
environment: serviceApp.environment,
|
|
166
|
+
scopes: serviceApp.scopes,
|
|
167
|
+
};
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
/**
|
|
171
|
+
* {@link getOxyBillingPrincipal}, throwing when the request has none. Use on
|
|
172
|
+
* routes that have already required a service token.
|
|
173
|
+
*/
|
|
174
|
+
export function getRequiredOxyBillingPrincipal(req: Request): OxyBillingPrincipal {
|
|
175
|
+
const principal = getOxyBillingPrincipal(req);
|
|
176
|
+
if (!principal) {
|
|
177
|
+
throw new Error('Request has no verified Oxy service principal');
|
|
178
|
+
}
|
|
179
|
+
return principal;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
/**
|
|
183
|
+
* The delegated end user of a service request, or `null`.
|
|
184
|
+
*
|
|
185
|
+
* Deliberately reads `req.serviceActingAs` — the grant-verified delegation —
|
|
186
|
+
* and not `req.userId`, which on a non-service request is the caller's own
|
|
187
|
+
* session identity and is not a delegation at all.
|
|
188
|
+
*/
|
|
189
|
+
export function getOxyDelegatedUserId(req: Request): string | null {
|
|
190
|
+
return normalizeId((req as OxyAuthRequest).serviceActingAs?.userId);
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
/**
|
|
194
|
+
* The whole attribution tuple for a service request: who pays, which
|
|
195
|
+
* application and credential, and optionally on whose behalf.
|
|
196
|
+
*/
|
|
197
|
+
export function getOxyRequestAttribution(req: Request): OxyRequestAttribution | null {
|
|
198
|
+
const principal = getOxyBillingPrincipal(req);
|
|
199
|
+
if (!principal) {
|
|
200
|
+
return null;
|
|
201
|
+
}
|
|
202
|
+
return { ...principal, delegatedUserId: getOxyDelegatedUserId(req) };
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
export function getRequiredOxyUserId(req: Request): string {
|
|
206
|
+
const userId = getOxyUserId(req);
|
|
207
|
+
if (!userId) {
|
|
208
|
+
throw new Error('User not authenticated');
|
|
209
|
+
}
|
|
210
|
+
return userId;
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
export function requireOxyAuth(req: Request, res: Response, next: NextFunction): void {
|
|
214
|
+
const userId = getOxyUserId(req);
|
|
215
|
+
if (!userId) {
|
|
216
|
+
res.status(401).json({
|
|
217
|
+
error: 'Unauthorized',
|
|
218
|
+
message: 'Authentication required',
|
|
219
|
+
});
|
|
220
|
+
return;
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
const authReq = req as OxyAuthRequest;
|
|
224
|
+
authReq.userId = userId;
|
|
225
|
+
ensureUser(authReq, userId);
|
|
226
|
+
next();
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
export function createOptionalOxyAuth(
|
|
230
|
+
oxy: OxyServices,
|
|
231
|
+
options: OxyAuthMiddlewareOptions = {},
|
|
232
|
+
): RequestHandler {
|
|
233
|
+
const resolveSession = oxy.auth({ ...options.auth, optional: true });
|
|
234
|
+
|
|
235
|
+
return (req, res, next) => {
|
|
236
|
+
if (getOxyUserId(req)) {
|
|
237
|
+
next();
|
|
238
|
+
return;
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
resolveSession(req, res, (error?: unknown) => {
|
|
242
|
+
if (error) {
|
|
243
|
+
next(error);
|
|
244
|
+
return;
|
|
245
|
+
}
|
|
246
|
+
next();
|
|
247
|
+
});
|
|
248
|
+
};
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
export function createOxyAuthMiddleware(
|
|
252
|
+
oxy: OxyServices,
|
|
253
|
+
options: OxyAuthMiddlewareOptions = {},
|
|
254
|
+
): RequestHandler {
|
|
255
|
+
const resolveSession = createOptionalOxyAuth(oxy, options);
|
|
256
|
+
|
|
257
|
+
return (req, res, next) => {
|
|
258
|
+
if (getOxyUserId(req)) {
|
|
259
|
+
requireOxyAuth(req, res, next);
|
|
260
|
+
return;
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
resolveSession(req, res, (error?: unknown) => {
|
|
264
|
+
if (error) {
|
|
265
|
+
next(error);
|
|
266
|
+
return;
|
|
267
|
+
}
|
|
268
|
+
requireOxyAuth(req, res, next);
|
|
269
|
+
});
|
|
270
|
+
};
|
|
271
|
+
}
|
|
@@ -0,0 +1,258 @@
|
|
|
1
|
+
import {
|
|
2
|
+
randomUUID,
|
|
3
|
+
sign as signBytes,
|
|
4
|
+
verify as verifyBytes,
|
|
5
|
+
type KeyObject,
|
|
6
|
+
} from 'node:crypto';
|
|
7
|
+
import {
|
|
8
|
+
capabilityTicketClaimsSchema,
|
|
9
|
+
type CapabilityTicketClaims,
|
|
10
|
+
type GrantLimit,
|
|
11
|
+
type PolicyDecision,
|
|
12
|
+
} from '@oxy.so/contracts';
|
|
13
|
+
import type { NextFunction, Request, RequestHandler, Response } from 'express';
|
|
14
|
+
|
|
15
|
+
const ALGORITHM = 'EdDSA';
|
|
16
|
+
const TOKEN_TYPE = 'OXY-CAPABILITY+JWT';
|
|
17
|
+
const DEFAULT_MAX_TTL_SECONDS = 300;
|
|
18
|
+
|
|
19
|
+
type UnsignedCapabilityTicketClaims = Omit<CapabilityTicketClaims, 'iss' | 'iat' | 'exp' | 'jti'>;
|
|
20
|
+
|
|
21
|
+
export interface CapabilityTicketSigningOptions {
|
|
22
|
+
privateKey: KeyObject;
|
|
23
|
+
keyId: string;
|
|
24
|
+
issuer: string;
|
|
25
|
+
ttlSeconds?: number;
|
|
26
|
+
now?: Date;
|
|
27
|
+
jti?: string;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export interface CapabilityTicketVerificationOptions {
|
|
31
|
+
resolvePublicKey: (keyId: string) => KeyObject | undefined;
|
|
32
|
+
audience: string;
|
|
33
|
+
issuer?: string;
|
|
34
|
+
now?: Date;
|
|
35
|
+
maximumTtlSeconds?: number;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export interface CapabilityTicketRequest extends Request {
|
|
39
|
+
capabilityTicket?: CapabilityTicketClaims;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export interface CapabilityTicketMiddlewareOptions extends CapabilityTicketVerificationOptions {
|
|
43
|
+
authorize: (claims: CapabilityTicketClaims) => Promise<PolicyDecision>;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export class CapabilityTicketError extends Error {
|
|
47
|
+
constructor(
|
|
48
|
+
public readonly code:
|
|
49
|
+
| 'malformed'
|
|
50
|
+
| 'invalid_signature'
|
|
51
|
+
| 'unknown_key'
|
|
52
|
+
| 'invalid_claims'
|
|
53
|
+
| 'expired'
|
|
54
|
+
| 'not_yet_valid'
|
|
55
|
+
| 'wrong_audience'
|
|
56
|
+
| 'wrong_issuer'
|
|
57
|
+
| 'ttl_exceeded',
|
|
58
|
+
message: string,
|
|
59
|
+
) {
|
|
60
|
+
super(message);
|
|
61
|
+
this.name = 'CapabilityTicketError';
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
function base64UrlEncode(value: string | Uint8Array): string {
|
|
66
|
+
return Buffer.from(value).toString('base64url');
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
function decodeJsonSegment(segment: string): unknown {
|
|
70
|
+
try {
|
|
71
|
+
return JSON.parse(Buffer.from(segment, 'base64url').toString('utf8')) as unknown;
|
|
72
|
+
} catch {
|
|
73
|
+
throw new CapabilityTicketError('malformed', 'Capability ticket is not valid base64url JSON');
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
function valuesAtPath(input: Record<string, unknown>, path: string): unknown[] {
|
|
78
|
+
let current: unknown[] = [input];
|
|
79
|
+
for (const segment of path.split('.')) {
|
|
80
|
+
const next: unknown[] = [];
|
|
81
|
+
for (const value of current) {
|
|
82
|
+
const records = Array.isArray(value) ? value : [value];
|
|
83
|
+
for (const record of records) {
|
|
84
|
+
if (typeof record !== 'object' || record === null || Array.isArray(record)) continue;
|
|
85
|
+
if (Object.prototype.hasOwnProperty.call(record, segment)) {
|
|
86
|
+
next.push((record as Record<string, unknown>)[segment]);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
if (next.length === 0) return [];
|
|
91
|
+
current = next;
|
|
92
|
+
}
|
|
93
|
+
return current.flatMap((value) => Array.isArray(value) ? value : [value]);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/** Enforces the signed per-action bounds before a domain handler runs. */
|
|
97
|
+
export function inputSatisfiesCapabilityLimits(
|
|
98
|
+
tool: string,
|
|
99
|
+
input: Record<string, unknown>,
|
|
100
|
+
limits: readonly GrantLimit[],
|
|
101
|
+
): boolean {
|
|
102
|
+
for (const limit of limits) {
|
|
103
|
+
if (limit.tool !== tool) return false;
|
|
104
|
+
const actualValues = valuesAtPath(input, limit.key);
|
|
105
|
+
if (actualValues.length === 0) return false;
|
|
106
|
+
if (typeof limit.value === 'number') {
|
|
107
|
+
const maximum = limit.value;
|
|
108
|
+
if (!actualValues.every((actual) => (
|
|
109
|
+
typeof actual === 'number' && Number.isFinite(actual) && actual <= maximum
|
|
110
|
+
))) return false;
|
|
111
|
+
continue;
|
|
112
|
+
}
|
|
113
|
+
if (!actualValues.every((actual) => actual === limit.value)) return false;
|
|
114
|
+
}
|
|
115
|
+
return true;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
export function issueCapabilityTicket(
|
|
119
|
+
claims: UnsignedCapabilityTicketClaims,
|
|
120
|
+
options: CapabilityTicketSigningOptions,
|
|
121
|
+
): string {
|
|
122
|
+
const ttlSeconds = options.ttlSeconds ?? 60;
|
|
123
|
+
if (!Number.isInteger(ttlSeconds) || ttlSeconds < 1 || ttlSeconds > DEFAULT_MAX_TTL_SECONDS) {
|
|
124
|
+
throw new CapabilityTicketError('ttl_exceeded', `Capability ticket TTL must be between 1 and ${DEFAULT_MAX_TTL_SECONDS} seconds`);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
const issuedAt = Math.floor((options.now ?? new Date()).getTime() / 1_000);
|
|
128
|
+
const payload = capabilityTicketClaimsSchema.parse({
|
|
129
|
+
...claims,
|
|
130
|
+
iss: options.issuer,
|
|
131
|
+
iat: issuedAt,
|
|
132
|
+
exp: issuedAt + ttlSeconds,
|
|
133
|
+
jti: options.jti ?? randomUUID(),
|
|
134
|
+
});
|
|
135
|
+
if (options.privateKey.asymmetricKeyType !== 'ed25519') {
|
|
136
|
+
throw new CapabilityTicketError('invalid_claims', 'Capability tickets require an Ed25519 private key');
|
|
137
|
+
}
|
|
138
|
+
const header = { alg: ALGORITHM, typ: TOKEN_TYPE, kid: options.keyId } as const;
|
|
139
|
+
const signingInput = `${base64UrlEncode(JSON.stringify(header))}.${base64UrlEncode(JSON.stringify(payload))}`;
|
|
140
|
+
return `${signingInput}.${base64UrlEncode(signBytes(null, Buffer.from(signingInput), options.privateKey))}`;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
export function verifyCapabilityTicket(
|
|
144
|
+
token: string,
|
|
145
|
+
options: CapabilityTicketVerificationOptions,
|
|
146
|
+
): CapabilityTicketClaims {
|
|
147
|
+
const segments = token.split('.');
|
|
148
|
+
if (segments.length !== 3) {
|
|
149
|
+
throw new CapabilityTicketError('malformed', 'Capability ticket must have three segments');
|
|
150
|
+
}
|
|
151
|
+
const [encodedHeader, encodedPayload, encodedSignature] = segments;
|
|
152
|
+
if (!encodedHeader || !encodedPayload || !encodedSignature) {
|
|
153
|
+
throw new CapabilityTicketError('malformed', 'Capability ticket contains an empty segment');
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
const header = decodeJsonSegment(encodedHeader);
|
|
157
|
+
if (typeof header !== 'object' || header === null || Array.isArray(header)) {
|
|
158
|
+
throw new CapabilityTicketError('malformed', 'Capability ticket header is not supported');
|
|
159
|
+
}
|
|
160
|
+
const headerRecord = header as Record<string, unknown>;
|
|
161
|
+
if (
|
|
162
|
+
Object.keys(headerRecord).length !== 3
|
|
163
|
+
|| headerRecord.alg !== ALGORITHM
|
|
164
|
+
|| headerRecord.typ !== TOKEN_TYPE
|
|
165
|
+
|| typeof headerRecord.kid !== 'string'
|
|
166
|
+
|| headerRecord.kid.length === 0
|
|
167
|
+
) {
|
|
168
|
+
throw new CapabilityTicketError('malformed', 'Capability ticket header is not supported');
|
|
169
|
+
}
|
|
170
|
+
const publicKey = options.resolvePublicKey(headerRecord.kid);
|
|
171
|
+
if (!publicKey || publicKey.asymmetricKeyType !== 'ed25519') {
|
|
172
|
+
throw new CapabilityTicketError('unknown_key', 'Capability ticket signing key is not trusted');
|
|
173
|
+
}
|
|
174
|
+
let providedSignature: Buffer;
|
|
175
|
+
try {
|
|
176
|
+
providedSignature = Buffer.from(encodedSignature, 'base64url');
|
|
177
|
+
} catch {
|
|
178
|
+
throw new CapabilityTicketError('malformed', 'Capability ticket signature is malformed');
|
|
179
|
+
}
|
|
180
|
+
if (!verifyBytes(
|
|
181
|
+
null,
|
|
182
|
+
Buffer.from(`${encodedHeader}.${encodedPayload}`),
|
|
183
|
+
publicKey,
|
|
184
|
+
providedSignature,
|
|
185
|
+
)) {
|
|
186
|
+
throw new CapabilityTicketError('invalid_signature', 'Capability ticket signature is invalid');
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
const parsed = capabilityTicketClaimsSchema.safeParse(decodeJsonSegment(encodedPayload));
|
|
190
|
+
if (!parsed.success) {
|
|
191
|
+
throw new CapabilityTicketError('invalid_claims', 'Capability ticket claims are invalid');
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
const claims = parsed.data;
|
|
195
|
+
const now = Math.floor((options.now ?? new Date()).getTime() / 1_000);
|
|
196
|
+
if (claims.iat > now + 5) {
|
|
197
|
+
throw new CapabilityTicketError('not_yet_valid', 'Capability ticket is not yet valid');
|
|
198
|
+
}
|
|
199
|
+
if (claims.exp <= now) {
|
|
200
|
+
throw new CapabilityTicketError('expired', 'Capability ticket has expired');
|
|
201
|
+
}
|
|
202
|
+
if (claims.exp - claims.iat > (options.maximumTtlSeconds ?? DEFAULT_MAX_TTL_SECONDS)) {
|
|
203
|
+
throw new CapabilityTicketError('ttl_exceeded', 'Capability ticket lifetime exceeds the accepted maximum');
|
|
204
|
+
}
|
|
205
|
+
if (claims.aud !== options.audience) {
|
|
206
|
+
throw new CapabilityTicketError('wrong_audience', 'Capability ticket audience does not match this app');
|
|
207
|
+
}
|
|
208
|
+
if (options.issuer && claims.iss !== options.issuer) {
|
|
209
|
+
throw new CapabilityTicketError('wrong_issuer', 'Capability ticket issuer is not trusted');
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
return claims;
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
export function readCapabilityAuthorization(authorization: string | undefined): string | null {
|
|
216
|
+
if (!authorization) return null;
|
|
217
|
+
const [scheme, token, extra] = authorization.trim().split(/\s+/);
|
|
218
|
+
if (scheme?.toLowerCase() !== 'capability' || !token || extra) return null;
|
|
219
|
+
return token;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
/**
|
|
223
|
+
* Verifies cryptographic scope first, then asks the authority service for a
|
|
224
|
+
* live decision. This second check is what makes revocation effective between
|
|
225
|
+
* planning and execution.
|
|
226
|
+
*/
|
|
227
|
+
export function createCapabilityTicketMiddleware(
|
|
228
|
+
options: CapabilityTicketMiddlewareOptions,
|
|
229
|
+
): RequestHandler {
|
|
230
|
+
return async (request: Request, response: Response, next: NextFunction): Promise<void> => {
|
|
231
|
+
const token = readCapabilityAuthorization(request.header('authorization'));
|
|
232
|
+
if (!token) {
|
|
233
|
+
response.status(401).json({ error: 'capability_ticket_required' });
|
|
234
|
+
return;
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
let claims: CapabilityTicketClaims;
|
|
238
|
+
try {
|
|
239
|
+
claims = verifyCapabilityTicket(token, options);
|
|
240
|
+
} catch (error) {
|
|
241
|
+
const code = error instanceof CapabilityTicketError ? error.code : 'invalid_claims';
|
|
242
|
+
response.status(401).json({ error: 'invalid_capability_ticket', code });
|
|
243
|
+
return;
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
try {
|
|
247
|
+
const decision = await options.authorize(claims);
|
|
248
|
+
if (!decision.allowed) {
|
|
249
|
+
response.status(403).json({ error: 'capability_denied', reason: decision.reason });
|
|
250
|
+
return;
|
|
251
|
+
}
|
|
252
|
+
(request as CapabilityTicketRequest).capabilityTicket = claims;
|
|
253
|
+
next();
|
|
254
|
+
} catch {
|
|
255
|
+
response.status(503).json({ error: 'capability_authority_unavailable' });
|
|
256
|
+
}
|
|
257
|
+
};
|
|
258
|
+
}
|