@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,97 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* THE enumeration of `OxyServices` GET-cache keys that can carry a single
|
|
4
|
+
* account's identity, and the one sweep that clears them.
|
|
5
|
+
*
|
|
6
|
+
* WHY THIS IS ONE LIST
|
|
7
|
+
* --------------------
|
|
8
|
+
* An Oxy account is readable under SEVERAL cache keys, and a write that only
|
|
9
|
+
* busts the key it happens to know about leaves every other one serving the
|
|
10
|
+
* pre-write snapshot for up to its TTL — from the caller's OWN in-memory cache,
|
|
11
|
+
* with a perfectly healthy server. That failure has already shipped twice with
|
|
12
|
+
* two different sets of keys:
|
|
13
|
+
*
|
|
14
|
+
* - `updateAccount` busted `GET:/accounts/<id>` and the account lists, but a
|
|
15
|
+
* profile screen reads `GET:/profiles/username/<name>` and
|
|
16
|
+
* `GET:/users/<id>`, so a channel's new picture stayed invisible for the
|
|
17
|
+
* full 5-minute profile TTL.
|
|
18
|
+
* - `updateProfile` busted four of the six keys below, missing
|
|
19
|
+
* `GET:/auth/lookup/` (the login-flow avatar/display-name lookup) and
|
|
20
|
+
* `GET:/profiles/resolve` (handle resolution) — two independently-drifted
|
|
21
|
+
* copies of a list that has to agree.
|
|
22
|
+
*
|
|
23
|
+
* So the list lives here, once, and every writer calls
|
|
24
|
+
* {@link evictOxyIdentityCache}. Adding a new identity read means adding its key
|
|
25
|
+
* HERE and every writer inherits it.
|
|
26
|
+
*
|
|
27
|
+
* WHERE THE LINE IS DRAWN
|
|
28
|
+
* -----------------------
|
|
29
|
+
* These are the SINGLE-PROFILE reads — the account is the subject of the
|
|
30
|
+
* response and is addressable by id, handle, or session. Reads that merely
|
|
31
|
+
* CONTAIN an account among many (`GET:/profiles/search`,
|
|
32
|
+
* `GET:/users/<other>/followers`, `GET:/profiles/<other>/similar`) are
|
|
33
|
+
* deliberately NOT swept: an account cannot be located in them without the very
|
|
34
|
+
* lookup being invalidated, so sweeping them means sweeping the whole namespace
|
|
35
|
+
* on every identity change — a real cost on a backend consuming the
|
|
36
|
+
* cross-service invalidation signal, for a surface where a stale thumbnail
|
|
37
|
+
* expires on its own in ~2 minutes.
|
|
38
|
+
*
|
|
39
|
+
* WHY PREFIXES RATHER THAN EXACT KEYS
|
|
40
|
+
* -----------------------------------
|
|
41
|
+
* Only the by-id key can be built from a user id. The handle-keyed and
|
|
42
|
+
* session-keyed entries cannot — deriving a handle from an id needs the lookup
|
|
43
|
+
* we are invalidating, and the SDK never tracks active session ids centrally.
|
|
44
|
+
* Prefix sweeping is also what makes a USERNAME CHANGE correct: the entry under
|
|
45
|
+
* the OLD handle is unreachable by construction (nothing in the write response
|
|
46
|
+
* carries it), and a sweep targeted at the new handle alone would leave the old
|
|
47
|
+
* one serving the pre-rename profile until its TTL. Over-eviction costs a
|
|
48
|
+
* refetch; under-eviction serves wrong data.
|
|
49
|
+
*
|
|
50
|
+
* Platform-neutral by construction (no imports, no `OxyServices` reference) so
|
|
51
|
+
* the client mixins and the Node-only `@oxy.so/core/server` invalidation
|
|
52
|
+
* subscriber can share it without either pulling in the other.
|
|
53
|
+
*/
|
|
54
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
55
|
+
exports.OXY_IDENTITY_CACHE_PREFIXES = void 0;
|
|
56
|
+
exports.oxyUserByIdCacheKey = oxyUserByIdCacheKey;
|
|
57
|
+
exports.evictOxyIdentityCache = evictOxyIdentityCache;
|
|
58
|
+
/**
|
|
59
|
+
* Cache-key PREFIXES under which an account's identity can be served, for the
|
|
60
|
+
* reads whose key cannot be derived from a user id. Swept wholesale.
|
|
61
|
+
*/
|
|
62
|
+
exports.OXY_IDENTITY_CACHE_PREFIXES = [
|
|
63
|
+
// `getUserBySession` — keyed by session id, which the SDK never enumerates.
|
|
64
|
+
'GET:/session/user/',
|
|
65
|
+
// `getCurrentUser` (and `GET:/users/me/graph`, harmlessly included).
|
|
66
|
+
'GET:/users/me',
|
|
67
|
+
// `lookupUsername` — the pre-session login lookup; carries avatar + display name.
|
|
68
|
+
'GET:/auth/lookup/',
|
|
69
|
+
// `getProfileByUsername` — keyed by handle, including the pre-rename handle.
|
|
70
|
+
'GET:/profiles/username/',
|
|
71
|
+
// `resolveProfile` — keyed by fediverse handle in the query payload.
|
|
72
|
+
'GET:/profiles/resolve',
|
|
73
|
+
];
|
|
74
|
+
/**
|
|
75
|
+
* Build the exact cache key `getUserById` reads under. The only identity key
|
|
76
|
+
* derivable from a user id, so the only one that does not need a prefix sweep.
|
|
77
|
+
*/
|
|
78
|
+
function oxyUserByIdCacheKey(userId) {
|
|
79
|
+
return `GET:/users/${userId}`;
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Sweep an `OxyServices` GET response cache of everything that could carry the
|
|
83
|
+
* given account's identity.
|
|
84
|
+
*
|
|
85
|
+
* @param oxy - Anything exposing the SDK's two eviction methods.
|
|
86
|
+
* @param userId - The account whose by-id entry to drop. Optional: a caller
|
|
87
|
+
* that does not know the id still clears every handle-, session-
|
|
88
|
+
* and self-keyed entry, which is the majority of the surface.
|
|
89
|
+
*/
|
|
90
|
+
function evictOxyIdentityCache(oxy, userId) {
|
|
91
|
+
for (const prefix of exports.OXY_IDENTITY_CACHE_PREFIXES) {
|
|
92
|
+
oxy.clearCacheByPrefix(prefix);
|
|
93
|
+
}
|
|
94
|
+
if (userId) {
|
|
95
|
+
oxy.clearCacheEntry(oxyUserByIdCacheKey(userId));
|
|
96
|
+
}
|
|
97
|
+
}
|
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Locale utilities for OxyServices.
|
|
4
|
+
*
|
|
5
|
+
* The Oxy platform models account languages as full BCP-47 locales
|
|
6
|
+
* (`language-REGION`, e.g. `es-ES`, `es-MX`, `pt-BR`). Region is significant:
|
|
7
|
+
* "Spanish (Spain)" is a different locale than "Spanish (Mexico)". A user's
|
|
8
|
+
* account locales live on `User.languages` as an ordered list with the PRIMARY
|
|
9
|
+
* (UI) locale first — there is no singular `language` field.
|
|
10
|
+
*
|
|
11
|
+
* This module is the single source of truth for the supported-locale catalog
|
|
12
|
+
* and every locale operation the SDK exposes: parsing base subtags, canonical
|
|
13
|
+
* normalization, validation, metadata lookup, and resolving a user's locales.
|
|
14
|
+
* It is pure and side-effect free.
|
|
15
|
+
*/
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
exports.FALLBACK_LOCALE = exports.SUPPORTED_LANGUAGES = void 0;
|
|
18
|
+
exports.getBaseLanguage = getBaseLanguage;
|
|
19
|
+
exports.normalizeLocale = normalizeLocale;
|
|
20
|
+
exports.isSupportedLocale = isSupportedLocale;
|
|
21
|
+
exports.getLanguageMetadata = getLanguageMetadata;
|
|
22
|
+
exports.getLanguageName = getLanguageName;
|
|
23
|
+
exports.getNativeLanguageName = getNativeLanguageName;
|
|
24
|
+
exports.isRTLLocale = isRTLLocale;
|
|
25
|
+
exports.getUserLanguages = getUserLanguages;
|
|
26
|
+
exports.getPrimaryLanguage = getPrimaryLanguage;
|
|
27
|
+
/**
|
|
28
|
+
* The supported-locale catalog. Ordered by prominence for display; the order
|
|
29
|
+
* is not otherwise significant. Every entry is a full `language-REGION` tag,
|
|
30
|
+
* with the base subtag lowercased and the region uppercased.
|
|
31
|
+
*/
|
|
32
|
+
exports.SUPPORTED_LANGUAGES = [
|
|
33
|
+
// English
|
|
34
|
+
{ code: 'en-US', language: 'en', region: 'US', name: 'English (United States)', nativeName: 'English (United States)' },
|
|
35
|
+
{ code: 'en-GB', language: 'en', region: 'GB', name: 'English (United Kingdom)', nativeName: 'English (United Kingdom)' },
|
|
36
|
+
{ code: 'en-AU', language: 'en', region: 'AU', name: 'English (Australia)', nativeName: 'English (Australia)' },
|
|
37
|
+
{ code: 'en-CA', language: 'en', region: 'CA', name: 'English (Canada)', nativeName: 'English (Canada)' },
|
|
38
|
+
{ code: 'en-IN', language: 'en', region: 'IN', name: 'English (India)', nativeName: 'English (India)' },
|
|
39
|
+
// Spanish
|
|
40
|
+
{ code: 'es-ES', language: 'es', region: 'ES', name: 'Spanish (Spain)', nativeName: 'Español (España)' },
|
|
41
|
+
{ code: 'es-MX', language: 'es', region: 'MX', name: 'Spanish (Mexico)', nativeName: 'Español (México)' },
|
|
42
|
+
{ code: 'es-US', language: 'es', region: 'US', name: 'Spanish (United States)', nativeName: 'Español (Estados Unidos)' },
|
|
43
|
+
{ code: 'es-AR', language: 'es', region: 'AR', name: 'Spanish (Argentina)', nativeName: 'Español (Argentina)' },
|
|
44
|
+
{ code: 'es-CO', language: 'es', region: 'CO', name: 'Spanish (Colombia)', nativeName: 'Español (Colombia)' },
|
|
45
|
+
// Portuguese
|
|
46
|
+
{ code: 'pt-BR', language: 'pt', region: 'BR', name: 'Portuguese (Brazil)', nativeName: 'Português (Brasil)' },
|
|
47
|
+
{ code: 'pt-PT', language: 'pt', region: 'PT', name: 'Portuguese (Portugal)', nativeName: 'Português (Portugal)' },
|
|
48
|
+
// French
|
|
49
|
+
{ code: 'fr-FR', language: 'fr', region: 'FR', name: 'French (France)', nativeName: 'Français (France)' },
|
|
50
|
+
{ code: 'fr-CA', language: 'fr', region: 'CA', name: 'French (Canada)', nativeName: 'Français (Canada)' },
|
|
51
|
+
// German
|
|
52
|
+
{ code: 'de-DE', language: 'de', region: 'DE', name: 'German (Germany)', nativeName: 'Deutsch (Deutschland)' },
|
|
53
|
+
{ code: 'de-AT', language: 'de', region: 'AT', name: 'German (Austria)', nativeName: 'Deutsch (Österreich)' },
|
|
54
|
+
{ code: 'de-CH', language: 'de', region: 'CH', name: 'German (Switzerland)', nativeName: 'Deutsch (Schweiz)' },
|
|
55
|
+
// Italian
|
|
56
|
+
{ code: 'it-IT', language: 'it', region: 'IT', name: 'Italian (Italy)', nativeName: 'Italiano (Italia)' },
|
|
57
|
+
// Dutch
|
|
58
|
+
{ code: 'nl-NL', language: 'nl', region: 'NL', name: 'Dutch (Netherlands)', nativeName: 'Nederlands (Nederland)' },
|
|
59
|
+
{ code: 'nl-BE', language: 'nl', region: 'BE', name: 'Dutch (Belgium)', nativeName: 'Nederlands (België)' },
|
|
60
|
+
// Nordic
|
|
61
|
+
{ code: 'sv-SE', language: 'sv', region: 'SE', name: 'Swedish (Sweden)', nativeName: 'Svenska (Sverige)' },
|
|
62
|
+
{ code: 'nb-NO', language: 'nb', region: 'NO', name: 'Norwegian Bokmål (Norway)', nativeName: 'Norsk bokmål (Norge)' },
|
|
63
|
+
{ code: 'da-DK', language: 'da', region: 'DK', name: 'Danish (Denmark)', nativeName: 'Dansk (Danmark)' },
|
|
64
|
+
{ code: 'fi-FI', language: 'fi', region: 'FI', name: 'Finnish (Finland)', nativeName: 'Suomi (Suomi)' },
|
|
65
|
+
// Central & Eastern Europe
|
|
66
|
+
{ code: 'pl-PL', language: 'pl', region: 'PL', name: 'Polish (Poland)', nativeName: 'Polski (Polska)' },
|
|
67
|
+
{ code: 'cs-CZ', language: 'cs', region: 'CZ', name: 'Czech (Czechia)', nativeName: 'Čeština (Česko)' },
|
|
68
|
+
{ code: 'sk-SK', language: 'sk', region: 'SK', name: 'Slovak (Slovakia)', nativeName: 'Slovenčina (Slovensko)' },
|
|
69
|
+
{ code: 'hu-HU', language: 'hu', region: 'HU', name: 'Hungarian (Hungary)', nativeName: 'Magyar (Magyarország)' },
|
|
70
|
+
{ code: 'ro-RO', language: 'ro', region: 'RO', name: 'Romanian (Romania)', nativeName: 'Română (România)' },
|
|
71
|
+
{ code: 'bg-BG', language: 'bg', region: 'BG', name: 'Bulgarian (Bulgaria)', nativeName: 'Български (България)' },
|
|
72
|
+
{ code: 'hr-HR', language: 'hr', region: 'HR', name: 'Croatian (Croatia)', nativeName: 'Hrvatski (Hrvatska)' },
|
|
73
|
+
{ code: 'sr-RS', language: 'sr', region: 'RS', name: 'Serbian (Serbia)', nativeName: 'Српски (Србија)' },
|
|
74
|
+
{ code: 'sl-SI', language: 'sl', region: 'SI', name: 'Slovenian (Slovenia)', nativeName: 'Slovenščina (Slovenija)' },
|
|
75
|
+
{ code: 'lt-LT', language: 'lt', region: 'LT', name: 'Lithuanian (Lithuania)', nativeName: 'Lietuvių (Lietuva)' },
|
|
76
|
+
{ code: 'lv-LV', language: 'lv', region: 'LV', name: 'Latvian (Latvia)', nativeName: 'Latviešu (Latvija)' },
|
|
77
|
+
{ code: 'et-EE', language: 'et', region: 'EE', name: 'Estonian (Estonia)', nativeName: 'Eesti (Eesti)' },
|
|
78
|
+
{ code: 'uk-UA', language: 'uk', region: 'UA', name: 'Ukrainian (Ukraine)', nativeName: 'Українська (Україна)' },
|
|
79
|
+
{ code: 'ru-RU', language: 'ru', region: 'RU', name: 'Russian (Russia)', nativeName: 'Русский (Россия)' },
|
|
80
|
+
{ code: 'el-GR', language: 'el', region: 'GR', name: 'Greek (Greece)', nativeName: 'Ελληνικά (Ελλάδα)' },
|
|
81
|
+
// Turkish
|
|
82
|
+
{ code: 'tr-TR', language: 'tr', region: 'TR', name: 'Turkish (Türkiye)', nativeName: 'Türkçe (Türkiye)' },
|
|
83
|
+
// Catalan
|
|
84
|
+
{ code: 'ca-ES', language: 'ca', region: 'ES', name: 'Catalan (Spain)', nativeName: 'Català (Espanya)' },
|
|
85
|
+
// East, South & Southeast Asia
|
|
86
|
+
{ code: 'ja-JP', language: 'ja', region: 'JP', name: 'Japanese (Japan)', nativeName: '日本語 (日本)' },
|
|
87
|
+
{ code: 'ko-KR', language: 'ko', region: 'KR', name: 'Korean (South Korea)', nativeName: '한국어 (대한민국)' },
|
|
88
|
+
{ code: 'zh-CN', language: 'zh', region: 'CN', name: 'Chinese (Simplified, China)', nativeName: '中文 (中国)' },
|
|
89
|
+
{ code: 'zh-TW', language: 'zh', region: 'TW', name: 'Chinese (Traditional, Taiwan)', nativeName: '中文 (台灣)' },
|
|
90
|
+
{ code: 'zh-HK', language: 'zh', region: 'HK', name: 'Chinese (Traditional, Hong Kong)', nativeName: '中文 (香港)' },
|
|
91
|
+
{ code: 'hi-IN', language: 'hi', region: 'IN', name: 'Hindi (India)', nativeName: 'हिन्दी (भारत)' },
|
|
92
|
+
{ code: 'bn-BD', language: 'bn', region: 'BD', name: 'Bengali (Bangladesh)', nativeName: 'বাংলা (বাংলাদেশ)' },
|
|
93
|
+
{ code: 'id-ID', language: 'id', region: 'ID', name: 'Indonesian (Indonesia)', nativeName: 'Bahasa Indonesia (Indonesia)' },
|
|
94
|
+
{ code: 'ms-MY', language: 'ms', region: 'MY', name: 'Malay (Malaysia)', nativeName: 'Bahasa Melayu (Malaysia)' },
|
|
95
|
+
{ code: 'th-TH', language: 'th', region: 'TH', name: 'Thai (Thailand)', nativeName: 'ไทย (ประเทศไทย)' },
|
|
96
|
+
{ code: 'vi-VN', language: 'vi', region: 'VN', name: 'Vietnamese (Vietnam)', nativeName: 'Tiếng Việt (Việt Nam)' },
|
|
97
|
+
// Right-to-left
|
|
98
|
+
{ code: 'ar-SA', language: 'ar', region: 'SA', name: 'Arabic (Saudi Arabia)', nativeName: 'العربية (السعودية)', rtl: true },
|
|
99
|
+
{ code: 'ar-EG', language: 'ar', region: 'EG', name: 'Arabic (Egypt)', nativeName: 'العربية (مصر)', rtl: true },
|
|
100
|
+
{ code: 'he-IL', language: 'he', region: 'IL', name: 'Hebrew (Israel)', nativeName: 'עברית (ישראל)', rtl: true },
|
|
101
|
+
{ code: 'fa-IR', language: 'fa', region: 'IR', name: 'Persian (Iran)', nativeName: 'فارسی (ایران)', rtl: true },
|
|
102
|
+
{ code: 'ur-PK', language: 'ur', region: 'PK', name: 'Urdu (Pakistan)', nativeName: 'اردو (پاکستان)', rtl: true },
|
|
103
|
+
];
|
|
104
|
+
/** Canonical fallback locale used when a display value cannot be resolved. */
|
|
105
|
+
exports.FALLBACK_LOCALE = 'en-US';
|
|
106
|
+
/** O(1) lookup of a catalog entry by its canonical code. */
|
|
107
|
+
const LOCALE_BY_CODE = new Map(exports.SUPPORTED_LANGUAGES.map((entry) => [entry.code, entry]));
|
|
108
|
+
/**
|
|
109
|
+
* Extract the base language subtag from a locale, lowercased.
|
|
110
|
+
*
|
|
111
|
+
* Tolerant of bare base subtags and of extra subtags (script/variant):
|
|
112
|
+
* `'es-ES'` → `'es'`, `'es'` → `'es'`, `'zh-Hant-TW'` → `'zh'`. Returns an
|
|
113
|
+
* empty string for empty input.
|
|
114
|
+
*/
|
|
115
|
+
function getBaseLanguage(locale) {
|
|
116
|
+
return locale.trim().toLowerCase().split('-')[0] ?? '';
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Normalize a locale string to its canonical `language-REGION` form when it is
|
|
120
|
+
* a supported locale, otherwise `undefined`.
|
|
121
|
+
*
|
|
122
|
+
* Canonicalization lowercases the base subtag and uppercases the region
|
|
123
|
+
* subtag (`'es-es'` → `'es-ES'`, `'EN-us'` → `'en-US'`) and validates the
|
|
124
|
+
* result against {@link SUPPORTED_LANGUAGES}. A bare base subtag (`'es'`) has
|
|
125
|
+
* no region and is therefore not a locale — it returns `undefined`.
|
|
126
|
+
*/
|
|
127
|
+
function normalizeLocale(input) {
|
|
128
|
+
const trimmed = input.trim();
|
|
129
|
+
if (!trimmed)
|
|
130
|
+
return undefined;
|
|
131
|
+
const parts = trimmed.split('-');
|
|
132
|
+
if (parts.length < 2)
|
|
133
|
+
return undefined;
|
|
134
|
+
const base = parts[0]?.toLowerCase();
|
|
135
|
+
const region = parts[parts.length - 1]?.toUpperCase();
|
|
136
|
+
if (!base || !region)
|
|
137
|
+
return undefined;
|
|
138
|
+
const canonical = `${base}-${region}`;
|
|
139
|
+
return LOCALE_BY_CODE.has(canonical) ? canonical : undefined;
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* Whether `input` resolves to a supported BCP-47 locale.
|
|
143
|
+
*/
|
|
144
|
+
function isSupportedLocale(input) {
|
|
145
|
+
return normalizeLocale(input) !== undefined;
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Resolve catalog metadata for a locale.
|
|
149
|
+
*
|
|
150
|
+
* @param code - A locale tag (any case; e.g. `'es-ES'`, `'es-es'`).
|
|
151
|
+
* @returns The {@link SupportedLanguage} entry, or `null` when the tag is empty
|
|
152
|
+
* or not a supported locale.
|
|
153
|
+
*/
|
|
154
|
+
function getLanguageMetadata(code) {
|
|
155
|
+
if (!code)
|
|
156
|
+
return null;
|
|
157
|
+
const canonical = normalizeLocale(code);
|
|
158
|
+
if (!canonical)
|
|
159
|
+
return null;
|
|
160
|
+
return LOCALE_BY_CODE.get(canonical) ?? null;
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* English display name for a locale (e.g. `'Spanish (Spain)'`).
|
|
164
|
+
* Falls back to the input tag, then {@link FALLBACK_LOCALE}.
|
|
165
|
+
*/
|
|
166
|
+
function getLanguageName(code) {
|
|
167
|
+
return getLanguageMetadata(code)?.name || code || exports.FALLBACK_LOCALE;
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* Native display name (endonym) for a locale (e.g. `'Español (España)'`).
|
|
171
|
+
* Falls back to the input tag, then {@link FALLBACK_LOCALE}.
|
|
172
|
+
*/
|
|
173
|
+
function getNativeLanguageName(code) {
|
|
174
|
+
return getLanguageMetadata(code)?.nativeName || code || exports.FALLBACK_LOCALE;
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* Base language subtags whose scripts are written right-to-left. Used to drive
|
|
178
|
+
* `I18nManager.forceRTL(...)` on React Native and `<html dir="rtl">` on web.
|
|
179
|
+
* Includes Arabic (`ar`), Hebrew (`he` / legacy `iw`), Persian (`fa`), and
|
|
180
|
+
* Urdu (`ur`).
|
|
181
|
+
*/
|
|
182
|
+
const RTL_LANGUAGE_BASES = new Set(['ar', 'he', 'iw', 'fa', 'ur']);
|
|
183
|
+
/**
|
|
184
|
+
* Whether a locale (or bare base subtag) is written right-to-left. Unknown
|
|
185
|
+
* tags are treated as left-to-right.
|
|
186
|
+
*/
|
|
187
|
+
function isRTLLocale(locale) {
|
|
188
|
+
if (!locale)
|
|
189
|
+
return false;
|
|
190
|
+
return RTL_LANGUAGE_BASES.has(getBaseLanguage(locale));
|
|
191
|
+
}
|
|
192
|
+
/**
|
|
193
|
+
* Resolve the ordered list of account locales for a user, primary first.
|
|
194
|
+
*
|
|
195
|
+
* Reads `user.languages` (the only source — there is no singular `language`
|
|
196
|
+
* field), then normalizes each entry to its canonical `language-REGION` form,
|
|
197
|
+
* drops non-string and unsupported entries, and de-duplicates while preserving
|
|
198
|
+
* first-seen order. Pure and side-effect free — never throws on bad input.
|
|
199
|
+
*/
|
|
200
|
+
function getUserLanguages(user) {
|
|
201
|
+
const source = user?.languages;
|
|
202
|
+
if (!Array.isArray(source))
|
|
203
|
+
return [];
|
|
204
|
+
const result = [];
|
|
205
|
+
const seen = new Set();
|
|
206
|
+
for (const entry of source) {
|
|
207
|
+
if (typeof entry !== 'string')
|
|
208
|
+
continue;
|
|
209
|
+
const canonical = normalizeLocale(entry);
|
|
210
|
+
if (!canonical || seen.has(canonical))
|
|
211
|
+
continue;
|
|
212
|
+
seen.add(canonical);
|
|
213
|
+
result.push(canonical);
|
|
214
|
+
}
|
|
215
|
+
return result;
|
|
216
|
+
}
|
|
217
|
+
/**
|
|
218
|
+
* Resolve the single PRIMARY locale for a user (the first entry from
|
|
219
|
+
* {@link getUserLanguages}), or `undefined` when the user has no supported
|
|
220
|
+
* locale.
|
|
221
|
+
*/
|
|
222
|
+
function getPrimaryLanguage(user) {
|
|
223
|
+
return getUserLanguages(user)[0];
|
|
224
|
+
}
|
|
@@ -0,0 +1,311 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* OAuth 2.0 Authorization Code + PKCE helpers for "Sign in with Oxy" third-party
|
|
4
|
+
* sign-in.
|
|
5
|
+
*
|
|
6
|
+
* Third-party Relying Parties (SPAs, static sites, and native apps that are NOT
|
|
7
|
+
* Oxy first-party) authenticate through the standard OAuth flow against
|
|
8
|
+
* `auth.oxy.so/authorize` — never FedCM, SSO bounces, or Oxy session cookies.
|
|
9
|
+
* Public clients (no secret) prove possession of the authorization code with
|
|
10
|
+
* PKCE (RFC 7636, S256): the RP generates a random `code_verifier`, sends its
|
|
11
|
+
* `code_challenge = BASE64URL(SHA-256(code_verifier))` on the authorize
|
|
12
|
+
* redirect, and later replays the raw verifier on the token exchange.
|
|
13
|
+
*
|
|
14
|
+
* All cross-platform crypto (random bytes, SHA-256) is delegated to the shared
|
|
15
|
+
* `@oxy.so/protocol` platform loaders — the exact primitives the rest of core's
|
|
16
|
+
* crypto already uses — so these helpers run identically on web, Node, and
|
|
17
|
+
* React Native. No `require()`, so the ESM build stays bundler-clean.
|
|
18
|
+
*/
|
|
19
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
20
|
+
exports.OXY_OAUTH_RETURN_PATH_STORAGE_KEY = exports.OXY_OAUTH_REDIRECT_URI_STORAGE_KEY = exports.OXY_OAUTH_CODE_VERIFIER_STORAGE_KEY = exports.OXY_OAUTH_STATE_STORAGE_KEY = exports.DEFAULT_OAUTH_SCOPE = exports.OXY_AUTHORIZE_URL = void 0;
|
|
21
|
+
exports.computeCodeChallenge = computeCodeChallenge;
|
|
22
|
+
exports.generatePkcePair = generatePkcePair;
|
|
23
|
+
exports.generateOAuthState = generateOAuthState;
|
|
24
|
+
exports.buildOAuthAuthorizeUrl = buildOAuthAuthorizeUrl;
|
|
25
|
+
exports.normalizeOAuthRedirectUri = normalizeOAuthRedirectUri;
|
|
26
|
+
exports.canonicalizeOAuthRedirectUri = canonicalizeOAuthRedirectUri;
|
|
27
|
+
exports.persistOAuthReturnPath = persistOAuthReturnPath;
|
|
28
|
+
exports.consumeOAuthReturnPath = consumeOAuthReturnPath;
|
|
29
|
+
exports.persistOAuthHandshake = persistOAuthHandshake;
|
|
30
|
+
exports.readOAuthHandshake = readOAuthHandshake;
|
|
31
|
+
exports.clearOAuthHandshake = clearOAuthHandshake;
|
|
32
|
+
const protocol_1 = require("@oxy.so/protocol");
|
|
33
|
+
const logger_1 = require("../logger");
|
|
34
|
+
/** The central Oxy IdP authorization endpoint used by default. */
|
|
35
|
+
exports.OXY_AUTHORIZE_URL = 'https://auth.oxy.so/authorize';
|
|
36
|
+
/** Default OAuth scope requested for a "Sign in with Oxy" third-party flow. */
|
|
37
|
+
exports.DEFAULT_OAUTH_SCOPE = 'openid profile';
|
|
38
|
+
/**
|
|
39
|
+
* Number of random bytes behind a PKCE `code_verifier`. 64 bytes → 86 base64url
|
|
40
|
+
* characters, comfortably inside RFC 7636 §4.1's required 43–128 range.
|
|
41
|
+
*/
|
|
42
|
+
const PKCE_VERIFIER_BYTES = 64;
|
|
43
|
+
/** Number of random bytes behind an OAuth `state` (CSRF) token. */
|
|
44
|
+
const OAUTH_STATE_BYTES = 32;
|
|
45
|
+
/** RFC 4648 §5 base64url alphabet (URL- and filename-safe, no padding). */
|
|
46
|
+
const BASE64URL_ALPHABET = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_';
|
|
47
|
+
/**
|
|
48
|
+
* Cryptographically-secure random bytes, cross-platform.
|
|
49
|
+
*
|
|
50
|
+
* Mirrors the platform gating the rest of core's crypto already uses:
|
|
51
|
+
* `expo-crypto` on React Native, Node's built-in `crypto` on the server, and
|
|
52
|
+
* the Web Crypto API in the browser (also the fallback if Node's `crypto`
|
|
53
|
+
* fails to load in an unusual bundled-Node environment).
|
|
54
|
+
*/
|
|
55
|
+
async function getSecureRandomBytes(byteLength) {
|
|
56
|
+
if ((0, protocol_1.isReactNative)()) {
|
|
57
|
+
const crypto = await (0, protocol_1.loadExpoCrypto)();
|
|
58
|
+
return Uint8Array.from(await crypto.getRandomBytesAsync(byteLength));
|
|
59
|
+
}
|
|
60
|
+
if ((0, protocol_1.isNodeJS)()) {
|
|
61
|
+
try {
|
|
62
|
+
const nodeCrypto = await (0, protocol_1.loadNodeCrypto)();
|
|
63
|
+
return Uint8Array.from(nodeCrypto.randomBytes(byteLength));
|
|
64
|
+
}
|
|
65
|
+
catch (error) {
|
|
66
|
+
logger_1.logger.warn('[oxy.oauth] Node crypto unavailable for PKCE random bytes, falling back to Web Crypto', { component: 'oauthPkce' }, error);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
const bytes = new Uint8Array(byteLength);
|
|
70
|
+
globalThis.crypto.getRandomValues(bytes);
|
|
71
|
+
return bytes;
|
|
72
|
+
}
|
|
73
|
+
/** Encode raw bytes as unpadded base64url (RFC 4648 §5). */
|
|
74
|
+
function bytesToBase64Url(bytes) {
|
|
75
|
+
let output = '';
|
|
76
|
+
for (let i = 0; i < bytes.length; i += 3) {
|
|
77
|
+
const byte0 = bytes[i];
|
|
78
|
+
const hasByte1 = i + 1 < bytes.length;
|
|
79
|
+
const hasByte2 = i + 2 < bytes.length;
|
|
80
|
+
const byte1 = hasByte1 ? bytes[i + 1] : 0;
|
|
81
|
+
const byte2 = hasByte2 ? bytes[i + 2] : 0;
|
|
82
|
+
output += BASE64URL_ALPHABET[byte0 >> 2];
|
|
83
|
+
output += BASE64URL_ALPHABET[((byte0 & 0x03) << 4) | (byte1 >> 4)];
|
|
84
|
+
if (hasByte1) {
|
|
85
|
+
output += BASE64URL_ALPHABET[((byte1 & 0x0f) << 2) | (byte2 >> 6)];
|
|
86
|
+
}
|
|
87
|
+
if (hasByte2) {
|
|
88
|
+
output += BASE64URL_ALPHABET[byte2 & 0x3f];
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
return output;
|
|
92
|
+
}
|
|
93
|
+
/** Decode a lowercase-hex string into its raw bytes. */
|
|
94
|
+
function hexToBytes(hex) {
|
|
95
|
+
const bytes = new Uint8Array(hex.length / 2);
|
|
96
|
+
for (let i = 0; i < bytes.length; i += 1) {
|
|
97
|
+
bytes[i] = Number.parseInt(hex.slice(i * 2, i * 2 + 2), 16);
|
|
98
|
+
}
|
|
99
|
+
return bytes;
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Compute the PKCE S256 `code_challenge` for a given verifier:
|
|
103
|
+
* `BASE64URL(SHA-256(ASCII(codeVerifier)))` (RFC 7636 §4.2). The verifier is
|
|
104
|
+
* base64url (ASCII), so its UTF-8 and ASCII byte encodings are identical.
|
|
105
|
+
*
|
|
106
|
+
* Reuses `@oxy.so/protocol`'s cross-platform {@link sha256} (which returns
|
|
107
|
+
* lowercase hex); the digest bytes are recovered and re-encoded as base64url.
|
|
108
|
+
*/
|
|
109
|
+
async function computeCodeChallenge(codeVerifier) {
|
|
110
|
+
const digestHex = await (0, protocol_1.sha256)(codeVerifier);
|
|
111
|
+
return bytesToBase64Url(hexToBytes(digestHex));
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Generate a fresh PKCE verifier/challenge pair for an OAuth authorization-code
|
|
115
|
+
* flow. The verifier is 64 random bytes as base64url (86 chars, within RFC 7636
|
|
116
|
+
* §4.1's 43–128 range and drawn only from the unreserved set); the challenge is
|
|
117
|
+
* its S256 transform.
|
|
118
|
+
*/
|
|
119
|
+
async function generatePkcePair() {
|
|
120
|
+
const codeVerifier = bytesToBase64Url(await getSecureRandomBytes(PKCE_VERIFIER_BYTES));
|
|
121
|
+
const codeChallenge = await computeCodeChallenge(codeVerifier);
|
|
122
|
+
return { codeVerifier, codeChallenge, method: 'S256' };
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Generate an opaque, single-use OAuth `state` token (32 random bytes as
|
|
126
|
+
* base64url) for CSRF protection across the authorize redirect.
|
|
127
|
+
*/
|
|
128
|
+
async function generateOAuthState() {
|
|
129
|
+
return bytesToBase64Url(await getSecureRandomBytes(OAUTH_STATE_BYTES));
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Build the `auth.oxy.so/authorize` redirect URL for an OAuth authorization-code
|
|
133
|
+
* + PKCE (S256) flow. Built via the WHATWG `URL` API so a custom
|
|
134
|
+
* `authorizeBaseUrl` that already carries a query string keeps its existing
|
|
135
|
+
* params (the OAuth params are merged in, not clobbered by a naive `?` concat).
|
|
136
|
+
* All values are percent-encoded by `URL.searchParams`.
|
|
137
|
+
*/
|
|
138
|
+
function buildOAuthAuthorizeUrl(params) {
|
|
139
|
+
const { authorizeBaseUrl = exports.OXY_AUTHORIZE_URL, clientId, redirectUri, scope = exports.DEFAULT_OAUTH_SCOPE, state, codeChallenge, } = params;
|
|
140
|
+
const url = new URL(authorizeBaseUrl);
|
|
141
|
+
url.searchParams.set('client_id', clientId);
|
|
142
|
+
url.searchParams.set('redirect_uri', redirectUri);
|
|
143
|
+
url.searchParams.set('response_type', 'code');
|
|
144
|
+
url.searchParams.set('state', state);
|
|
145
|
+
url.searchParams.set('scope', scope);
|
|
146
|
+
url.searchParams.set('code_challenge', codeChallenge);
|
|
147
|
+
url.searchParams.set('code_challenge_method', 'S256');
|
|
148
|
+
if (params.prompt) {
|
|
149
|
+
url.searchParams.set('prompt', params.prompt);
|
|
150
|
+
}
|
|
151
|
+
if (params.responseMode) {
|
|
152
|
+
url.searchParams.set('response_mode', params.responseMode);
|
|
153
|
+
}
|
|
154
|
+
return url.toString();
|
|
155
|
+
}
|
|
156
|
+
/** `sessionStorage` key for the OAuth CSRF `state` across an authorize redirect. */
|
|
157
|
+
exports.OXY_OAUTH_STATE_STORAGE_KEY = 'oxy_oauth_state';
|
|
158
|
+
/** `sessionStorage` key for the PKCE `code_verifier` across an authorize redirect. */
|
|
159
|
+
exports.OXY_OAUTH_CODE_VERIFIER_STORAGE_KEY = 'oxy_oauth_code_verifier';
|
|
160
|
+
/** `sessionStorage` key — the exact `redirect_uri` sent on the authorize request. */
|
|
161
|
+
exports.OXY_OAUTH_REDIRECT_URI_STORAGE_KEY = 'oxy.oauth_redirect_uri';
|
|
162
|
+
/**
|
|
163
|
+
* `sessionStorage` key for the in-app path to return to after an authorize
|
|
164
|
+
* round trip. See {@link persistOAuthReturnPath}.
|
|
165
|
+
*/
|
|
166
|
+
exports.OXY_OAUTH_RETURN_PATH_STORAGE_KEY = 'oxy.oauth_return_path';
|
|
167
|
+
/**
|
|
168
|
+
* Normalize a redirect URI to its origin. Official Oxy apps register apex
|
|
169
|
+
* origins (`https://inbox.oxy.so`) — never path-qualified URLs.
|
|
170
|
+
*
|
|
171
|
+
* This is why the path cannot ride along in `redirect_uri`, and why
|
|
172
|
+
* {@link persistOAuthReturnPath} exists: the authorize round trip always lands
|
|
173
|
+
* back on the bare origin, so the page the user was on has to be carried
|
|
174
|
+
* out-of-band and restored on return.
|
|
175
|
+
*/
|
|
176
|
+
function normalizeOAuthRedirectUri(input) {
|
|
177
|
+
try {
|
|
178
|
+
return new URL(input).origin;
|
|
179
|
+
}
|
|
180
|
+
catch {
|
|
181
|
+
return input;
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
/**
|
|
185
|
+
* Collapse `https://app.example/` → `https://app.example` for OAuth binding.
|
|
186
|
+
* Path-qualified redirect URIs are preserved — matches the API token exchange.
|
|
187
|
+
*/
|
|
188
|
+
function canonicalizeOAuthRedirectUri(redirectUri) {
|
|
189
|
+
try {
|
|
190
|
+
const parsed = new URL(redirectUri);
|
|
191
|
+
if (parsed.protocol !== 'https:' && parsed.protocol !== 'http:') {
|
|
192
|
+
return redirectUri;
|
|
193
|
+
}
|
|
194
|
+
if (parsed.pathname === '/' && !parsed.search && !parsed.hash) {
|
|
195
|
+
return parsed.origin;
|
|
196
|
+
}
|
|
197
|
+
return redirectUri;
|
|
198
|
+
}
|
|
199
|
+
catch {
|
|
200
|
+
return redirectUri;
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
/**
|
|
204
|
+
* Is this a safe same-origin path to restore into the address bar?
|
|
205
|
+
*
|
|
206
|
+
* Only site-relative paths are accepted. `//evil.com` and `/\evil.com` are
|
|
207
|
+
* rejected because browsers resolve both as protocol-relative *absolute* URLs —
|
|
208
|
+
* without this check, anything able to write one key of `sessionStorage` could
|
|
209
|
+
* turn the post-authorize restore into an open redirect.
|
|
210
|
+
*/
|
|
211
|
+
function isSafeReturnPath(value) {
|
|
212
|
+
if (!value.startsWith('/'))
|
|
213
|
+
return false;
|
|
214
|
+
if (value.startsWith('//') || value.startsWith('/\\'))
|
|
215
|
+
return false;
|
|
216
|
+
if (value.length > 2048)
|
|
217
|
+
return false;
|
|
218
|
+
return true;
|
|
219
|
+
}
|
|
220
|
+
/**
|
|
221
|
+
* Remember the page the user was on before a full-page authorize redirect.
|
|
222
|
+
*
|
|
223
|
+
* Silent cross-origin restore navigates the whole tab to the IdP and back, and
|
|
224
|
+
* `redirect_uri` must be a registered apex origin, so the browser returns to
|
|
225
|
+
* `/` no matter which page the visit started on. Without this, every deep link
|
|
226
|
+
* — a shared URL, a search result, an ad landing page — silently became the
|
|
227
|
+
* home page for signed-out visitors on their first navigation in a tab.
|
|
228
|
+
*
|
|
229
|
+
* Stored next to the PKCE handshake it belongs to, and cleared by
|
|
230
|
+
* {@link clearOAuthHandshake} so a stale entry can never be applied to an
|
|
231
|
+
* unrelated later navigation.
|
|
232
|
+
*/
|
|
233
|
+
function persistOAuthReturnPath(path) {
|
|
234
|
+
const store = globalThis.sessionStorage;
|
|
235
|
+
if (!store || !isSafeReturnPath(path))
|
|
236
|
+
return;
|
|
237
|
+
try {
|
|
238
|
+
store.setItem(exports.OXY_OAUTH_RETURN_PATH_STORAGE_KEY, path);
|
|
239
|
+
}
|
|
240
|
+
catch (error) {
|
|
241
|
+
// Non-fatal: the round trip still completes, it just lands on the origin.
|
|
242
|
+
logger_1.logger.warn('Could not persist OAuth return path to sessionStorage', { component: 'oauthPkce' }, error);
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
/**
|
|
246
|
+
* Read and remove the persisted return path, or `null` when there is none or
|
|
247
|
+
* it failed validation.
|
|
248
|
+
*
|
|
249
|
+
* Single-use by design: it is consumed on the first return so a leftover value
|
|
250
|
+
* cannot redirect a later navigation in the same tab.
|
|
251
|
+
*/
|
|
252
|
+
function consumeOAuthReturnPath() {
|
|
253
|
+
const store = globalThis.sessionStorage;
|
|
254
|
+
if (!store)
|
|
255
|
+
return null;
|
|
256
|
+
try {
|
|
257
|
+
const value = store.getItem(exports.OXY_OAUTH_RETURN_PATH_STORAGE_KEY);
|
|
258
|
+
store.removeItem(exports.OXY_OAUTH_RETURN_PATH_STORAGE_KEY);
|
|
259
|
+
if (!value || !isSafeReturnPath(value))
|
|
260
|
+
return null;
|
|
261
|
+
return value;
|
|
262
|
+
}
|
|
263
|
+
catch {
|
|
264
|
+
return null;
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
/** Persist the OAuth handshake for a full-page redirect return (web only). */
|
|
268
|
+
function persistOAuthHandshake(state, codeVerifier, redirectUri) {
|
|
269
|
+
const store = globalThis.sessionStorage;
|
|
270
|
+
try {
|
|
271
|
+
if (!store)
|
|
272
|
+
throw new Error('sessionStorage is unavailable');
|
|
273
|
+
store.setItem(exports.OXY_OAUTH_STATE_STORAGE_KEY, state);
|
|
274
|
+
store.setItem(exports.OXY_OAUTH_CODE_VERIFIER_STORAGE_KEY, codeVerifier);
|
|
275
|
+
if (redirectUri) {
|
|
276
|
+
store.setItem(exports.OXY_OAUTH_REDIRECT_URI_STORAGE_KEY, canonicalizeOAuthRedirectUri(redirectUri));
|
|
277
|
+
}
|
|
278
|
+
return true;
|
|
279
|
+
}
|
|
280
|
+
catch (error) {
|
|
281
|
+
logger_1.logger.warn('Could not persist OAuth handshake to sessionStorage', { component: 'oauthPkce' }, error);
|
|
282
|
+
return false;
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
/** Read the persisted OAuth handshake, or `null` when absent. */
|
|
286
|
+
function readOAuthHandshake() {
|
|
287
|
+
const store = globalThis.sessionStorage;
|
|
288
|
+
if (!store)
|
|
289
|
+
return null;
|
|
290
|
+
const state = store.getItem(exports.OXY_OAUTH_STATE_STORAGE_KEY);
|
|
291
|
+
const codeVerifier = store.getItem(exports.OXY_OAUTH_CODE_VERIFIER_STORAGE_KEY);
|
|
292
|
+
if (!state || !codeVerifier)
|
|
293
|
+
return null;
|
|
294
|
+
const redirectUri = store.getItem(exports.OXY_OAUTH_REDIRECT_URI_STORAGE_KEY) ?? undefined;
|
|
295
|
+
return redirectUri ? { state, codeVerifier, redirectUri } : { state, codeVerifier };
|
|
296
|
+
}
|
|
297
|
+
/** Drop persisted OAuth handshake keys after a successful or aborted return. */
|
|
298
|
+
function clearOAuthHandshake() {
|
|
299
|
+
const store = globalThis.sessionStorage;
|
|
300
|
+
try {
|
|
301
|
+
store?.removeItem(exports.OXY_OAUTH_STATE_STORAGE_KEY);
|
|
302
|
+
store?.removeItem(exports.OXY_OAUTH_CODE_VERIFIER_STORAGE_KEY);
|
|
303
|
+
store?.removeItem(exports.OXY_OAUTH_REDIRECT_URI_STORAGE_KEY);
|
|
304
|
+
// The return path belongs to this handshake. Leaving it behind would let a
|
|
305
|
+
// later, unrelated navigation in the same tab be redirected by it.
|
|
306
|
+
store?.removeItem(exports.OXY_OAUTH_RETURN_PATH_STORAGE_KEY);
|
|
307
|
+
}
|
|
308
|
+
catch {
|
|
309
|
+
// Best-effort cleanup only.
|
|
310
|
+
}
|
|
311
|
+
}
|