@seams/wallet-server 0.27.0 → 0.29.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +19 -4
- package/artifact-manifest.json +28 -13
- package/cloudflare-router-ab/build/deriver-a/build-stamp.json +1 -1
- package/cloudflare-router-ab/build/deriver-b/build-stamp.json +1 -1
- package/cloudflare-router-ab/build/router/build-stamp.json +1 -1
- package/cloudflare-router-ab/build/signing-worker/build-stamp.json +1 -1
- package/cloudflare-router-ab/build/tenant-root-control-plane/build-stamp.json +1 -1
- package/dist/esm/application-auth.js +2 -0
- package/dist/esm/auth/applicationAuth.js +85 -0
- package/dist/esm/auth/externalAuthService.js +149 -0
- package/dist/esm/auth/externalAuthStore.js +353 -0
- package/dist/esm/auth/externalOwnerOperations.js +82 -0
- package/dist/esm/authorization/domain.js +2 -2
- package/dist/esm/authorization/factorEvidence.js +1 -1
- package/dist/esm/authorization/service.js +2 -2
- package/dist/esm/authorization/vaultProxyUse.js +1 -1
- package/dist/esm/cloud-host.js +12 -11
- package/dist/esm/core/ThresholdService/validation.js +1 -1
- package/dist/esm/core/WebAuthnCredentialBindingStore.js +1 -1
- package/dist/esm/core/authService/webauthn.js +1 -1
- package/dist/esm/core/d1EcdsaSignerRead.js +1 -1
- package/dist/esm/core/d1WalletAuthMethodStore.js +2 -2
- package/dist/esm/core/d1WalletStore.js +1 -1
- package/dist/esm/core/deviceLinking/linkedDeviceEmailOtpGrant.js +1 -1
- package/dist/esm/core/deviceLinking/linkedDeviceManagement.js +1 -1
- package/dist/esm/core/deviceLinking/linkedDeviceSessionRecord.js +2 -2
- package/dist/esm/core/nearRelayerAccountProvisioning.js +2 -2
- package/dist/esm/hosted-wallet-gateway.js +3 -3
- package/dist/esm/index.js +1 -1
- package/dist/esm/router/auth/webAuthnCredentialCodecs.js +1 -1
- package/dist/esm/router/cloudflare/d1/auth/d1AuthorizedOperationRouteService.js +2 -0
- package/dist/esm/router/cloudflare/d1/auth/d1RecordedOwnerOperation.js +43 -0
- package/dist/esm/router/cloudflare/d1/auth/d1RouterApiAuthService.js +27 -3
- package/dist/esm/router/cloudflare/d1/authorization/d1AuthorizationStore.js +2 -2
- package/dist/esm/router/cloudflare/d1/authorization/d1VaultProxyStore.js +2 -2
- package/dist/esm/router/cloudflare/d1/deviceLinking/d1LinkedDeviceAuthorityInstallService.js +3 -3
- package/dist/esm/router/cloudflare/d1/deviceLinking/d1LinkedDeviceEd25519ExportRootStore.js +1 -1
- package/dist/esm/router/cloudflare/d1/deviceLinking/d1LinkedDeviceOwnerAuthorizationProvider.js +2 -2
- package/dist/esm/router/cloudflare/d1/deviceLinking/d1LinkedDeviceSessionStore.js +1 -1
- package/dist/esm/router/cloudflare/d1/deviceLinking/d1LinkedDeviceSourceContributionPreparationPlanner.js +1 -1
- package/dist/esm/router/cloudflare/d1/deviceLinking/d1LinkedDeviceTargetAuthenticatorStore.js +1 -1
- package/dist/esm/router/cloudflare/d1/deviceLinking/d1LinkedDeviceTargetCredentialProvider.js +1 -1
- package/dist/esm/router/cloudflare/d1/deviceLinking/d1LinkedDeviceTargetPlanner.js +1 -1
- package/dist/esm/router/cloudflare/d1/deviceLinking/d1LinkedDeviceVerifiedLinkBuilder.js +2 -2
- package/dist/esm/router/cloudflare/d1/deviceLinking/d1LinkedDeviceVerifiedLinkSourceReader.js +1 -1
- package/dist/esm/router/cloudflare/d1/ed25519Yao/d1Ed25519YaoCapabilityPersistence.js +1 -1
- package/dist/esm/router/cloudflare/d1/emailOtp/d1EmailOtpChallengeIssuer.js +1 -1
- package/dist/esm/router/cloudflare/d1/emailOtp/d1EmailOtpChallengeService.js +1 -1
- package/dist/esm/router/cloudflare/d1/emailOtp/d1EmailOtpChallengeStore.js +1 -1
- package/dist/esm/router/cloudflare/d1/emailOtp/d1EmailOtpRecords.js +2 -2
- package/dist/esm/router/cloudflare/d1/emailOtp/d1EmailOtpRecoveryService.js +3 -3
- package/dist/esm/router/cloudflare/d1/emailOtp/d1EmailOtpRegistrationEnrollmentFinalizer.js +1 -1
- package/dist/esm/router/cloudflare/d1/emailOtp/d1GoogleEmailOtpRegistrationAttemptStore.js +1 -1
- package/dist/esm/router/cloudflare/d1/emailOtp/d1GoogleEmailOtpSessionResolver.js +3 -3
- package/dist/esm/router/cloudflare/d1/oidc/d1OidcBoundary.js +7 -1
- package/dist/esm/router/cloudflare/d1/oidc/d1OidcVerificationService.js +1 -1
- package/dist/esm/router/cloudflare/d1/passkeyCustody/d1PasskeyCustodyRouteService.js +4 -4
- package/dist/esm/router/cloudflare/d1/passkeyCustody/d1WalletCustodyCommitStore.js +4 -4
- package/dist/esm/router/cloudflare/d1/passkeyCustody/d1WalletRecoveryGoogleEmailOtpRecords.js +1 -1
- package/dist/esm/router/cloudflare/d1/passkeyCustody/d1WalletRecoveryGoogleEmailOtpService.js +3 -3
- package/dist/esm/router/cloudflare/d1/registration/d1EvmFamilyEcdsaRegistrationBranch.js +1 -1
- package/dist/esm/router/cloudflare/d1/registration/d1RegistrationCeremonyRecords.js +11 -2
- package/dist/esm/router/cloudflare/d1/registration/d1RegistrationIntentService.js +1 -1
- package/dist/esm/router/cloudflare/d1/registration/d1WalletExecutionAuthority.js +9 -16
- package/dist/esm/router/cloudflare/d1/registration/d1WalletRegistrationCommitStore.js +1 -1
- package/dist/esm/router/cloudflare/d1/registration/d1WalletRegistrationService.js +46 -4
- package/dist/esm/router/cloudflare/d1/registration/d1WalletRegistrationSetup.js +12 -0
- package/dist/esm/router/cloudflare/d1/registration/d1WalletRegistrationSetupExecution.js +1 -0
- package/dist/esm/router/cloudflare/d1/registration/registrationCompletionWrite.js +1 -0
- package/dist/esm/router/cloudflare/d1/registration/walletRegistrationEstablishedSessionIssuer.js +1 -1
- package/dist/esm/router/cloudflare/d1/registration/walletRegistrationSessionCommitReceipt.js +36 -1
- package/dist/esm/router/cloudflare/d1/signingAdmission/d1RouterAbNormalSigningAdmissionStore.js +1 -1
- package/dist/esm/router/cloudflare/d1/wallet/authorizationSnapshotLayout.js +1 -0
- package/dist/esm/router/cloudflare/d1/wallet/d1VoiceIdWalletSessionChallenges.js +2 -2
- package/dist/esm/router/cloudflare/d1/wallet/d1WalletAuthMethodBoundary.js +1 -1
- package/dist/esm/router/cloudflare/d1/wallet/d1WalletAuthMethodRevocationReplayStore.js +1 -1
- package/dist/esm/router/cloudflare/d1/wallet/d1WalletAuthMethodService.js +6 -5
- package/dist/esm/router/cloudflare/d1/wallet/d1WalletAuthorityStore.js +2 -2
- package/dist/esm/router/cloudflare/d1/wallet/d1WalletAuthorizationCleanup.js +2 -1
- package/dist/esm/router/cloudflare/d1/wallet/d1WalletAuthorizationIntake.js +1 -1
- package/dist/esm/router/cloudflare/d1/wallet/d1WalletAuthorizationSnapshot.js +1 -1
- package/dist/esm/router/cloudflare/d1/wallet/d1WalletRelocationChallenges.js +1 -1
- package/dist/esm/router/cloudflare/d1/wallet/d1WalletRelocationOwnerRequest.js +2 -2
- package/dist/esm/router/cloudflare/d1/webauthn/d1WebAuthnAuthService.js +2 -2
- package/dist/esm/router/cloudflare/d1/webauthn/d1WebAuthnRecords.js +2 -2
- package/dist/esm/router/cloudflare/runtime/staticWalletConsoleBinding.js +9 -0
- package/dist/esm/router/cloudflare/runtime/walletConsoleOpsClient.js +6 -0
- package/dist/esm/router/cloudflare-adaptor.js +1 -1
- package/dist/esm/router/cloudflare.js +6139 -5567
- package/dist/esm/router/domains/ecdsa/routerAbEcdsaStrictRegistration.js +1 -1
- package/dist/esm/router/domains/ed25519Yao/export/routerAbEd25519YaoExport.js +5 -5
- package/dist/esm/router/domains/ed25519Yao/recovery/routerAbEd25519YaoRecovery.js +2 -2
- package/dist/esm/router/domains/ed25519Yao/recovery/routerAbEd25519YaoRecoveryWalletSessionAuthorization.js +1 -1
- package/dist/esm/router/domains/ed25519Yao/registration/routerAbEd25519YaoHttpRegistrationBackend.js +1 -1
- package/dist/esm/router/domains/ed25519Yao/registration/routerAbEd25519YaoRegistration.js +1 -1
- package/dist/esm/router/domains/ed25519Yao/registration/routerAbEd25519YaoRegistrationIntentAuthorization.js +1 -1
- package/dist/esm/router/domains/emailOtp/emailOtpRouteHandlers.js +2 -2
- package/dist/esm/router/domains/passkeyCustody/walletCustodyRegistrationCommit.js +1 -1
- package/dist/esm/router/domains/signingOperations/routerAbEcdsaDerivationNormalSigningRoute.js +2 -2
- package/dist/esm/router/domains/signingOperations/routerAbEd25519NormalSigningRoute.js +37 -3
- package/dist/esm/router/domains/signingOperations/routerAbOperationStepUp.js +1 -1
- package/dist/esm/router/domains/tenantRoot/tenantRootIdentityResolution.js +1 -1
- package/dist/esm/router/domains/walletRegistration/walletRegistrationReservation.js +18 -3
- package/dist/esm/router/domains/walletRegistration/walletRegistrationRoutes.js +12 -4
- package/dist/esm/router/domains/walletUnlock/walletUnlockRouteHandlers.js +3 -3
- package/dist/esm/router/framework/http.js +1 -1
- package/dist/esm/router/framework/routeDefinitions.js +2 -1
- package/dist/esm/router/transport/fetch/createFetchRouter.js +5 -3
- package/dist/esm/router/transport/fetch/routes/auth.js +1 -1
- package/dist/esm/router/transport/fetch/routes/deviceLinking.js +3 -3
- package/dist/esm/router/transport/fetch/routes/deviceLinkingOwnerAuthorization.js +1 -1
- package/dist/esm/router/transport/fetch/routes/ecdsaOperationStepUpFactor.js +3 -3
- package/dist/esm/router/transport/fetch/routes/externalAuth.js +351 -0
- package/dist/esm/router/transport/fetch/routes/normalSigningRouterProxy.js +1 -1
- package/dist/esm/router/transport/fetch/routes/passkeyCustody.js +46 -306
- package/dist/esm/router/transport/fetch/routes/sessions.js +4 -4
- package/dist/esm/router/transport/fetch/routes/syncAccount.js +2 -2
- package/dist/esm/router/transport/fetch/routes/syncAccountBootstrap.js +1 -1
- package/dist/esm/router/transport/fetch/routes/thresholdEcdsa.js +4 -4
- package/dist/esm/router/transport/fetch/routes/thresholdEd25519.js +6 -6
- package/dist/esm/router/transport/fetch/routes/walletExecutionLanePreflight.js +2 -2
- package/dist/esm/router/transport/fetch/routes/walletRegistration.js +4 -4
- package/dist/esm/router/transport/fetch/walletOwnerOperationAuthorization.js +306 -0
- package/dist/esm/shared-ts/src/auth/externalAuth.js +118 -0
- package/dist/esm/shared-ts/src/authorization/index.js +1 -1
- package/dist/esm/shared-ts/src/authorization/voiceIdDeviceAssertion.js +1 -1
- package/dist/esm/shared-ts/src/authorization/walletAuthority.js +2 -2
- package/dist/esm/shared-ts/src/authorization/{walletCustodyOperation.js → walletOwnerOperation.js} +4 -4
- package/dist/esm/shared-ts/src/device-linking/delegatedActivationPlan.js +1 -1
- package/dist/esm/shared-ts/src/device-linking/digests.js +1 -1
- package/dist/esm/shared-ts/src/device-linking/ed25519ExportRoot.js +1 -1
- package/dist/esm/shared-ts/src/device-linking/parsers.js +2 -2
- package/dist/esm/shared-ts/src/device-linking/sourceContribution.js +1 -1
- package/dist/esm/shared-ts/src/device-linking/walletSessionCredentialDelivery.js +1 -1
- package/dist/esm/shared-ts/src/device-linking/wireFields.js +2 -2
- package/dist/esm/shared-ts/src/passkey-custody/custodyEnvelope.js +1 -1
- package/dist/esm/shared-ts/src/passkey-custody/custodySecretBinding.js +1 -1
- package/dist/esm/shared-ts/src/signing-lanes/ownerContinuity.js +1 -1
- package/dist/esm/shared-ts/src/utils/routerAbEcdsaDerivation.js +1 -1
- package/dist/esm/shared-ts/src/utils/walletAuthAuthority.js +1 -1
- package/dist/esm/shared-ts/src/wallet-recovery/index.js +3 -3
- package/dist/esm/shared-ts/src/wallet-recovery/walletRecoveryCommittedProjection.js +1 -1
- package/dist/esm/shared-ts/src/wallet-recovery/walletRecoveryEnvelopeSet.js +1 -1
- package/dist/esm/threshold/session/signingSessionSeal/crypto/cipher.js +1 -1
- package/dist/esm/threshold/session/signingSessionSeal/service.js +1 -1
- package/dist/esm/threshold/session/signingSessionSeal/transport/fetch.js +1 -1
- package/dist/esm/threshold/session/signingSessionSeal/transport/shared.js +1 -1
- package/dist/types/shared-ts/src/auth/externalAuth.d.ts +127 -0
- package/dist/types/shared-ts/src/authorization/index.d.ts +1 -1
- package/dist/types/shared-ts/src/authorization/walletOwnerOperation.d.ts +10 -0
- package/dist/types/shared-ts/src/utils/registrationEstablishedSession.d.ts +4 -0
- package/dist/types/shared-ts/src/utils/registrationIntent.d.ts +2 -0
- package/dist/types/shared-ts/src/utils/walletManagementProtocol.d.ts +1 -1
- package/dist/types/wallet-server/src/application-auth.d.ts +3 -0
- package/dist/types/wallet-server/src/auth/applicationAuth.d.ts +29 -0
- package/dist/types/wallet-server/src/auth/externalAuthService.d.ts +55 -0
- package/dist/types/wallet-server/src/auth/externalAuthStore.d.ts +115 -0
- package/dist/types/wallet-server/src/auth/externalOwnerOperations.d.ts +18 -0
- package/dist/types/wallet-server/src/cloud-host.d.ts +2 -1
- package/dist/types/wallet-server/src/core/threeRouteRegistrationContracts.d.ts +12 -0
- package/dist/types/wallet-server/src/router/cloudflare/d1/auth/d1AuthorizedOperationRouteService.d.ts +5 -1
- package/dist/types/wallet-server/src/router/cloudflare/d1/auth/d1RecordedOwnerOperation.d.ts +16 -0
- package/dist/types/wallet-server/src/router/cloudflare/d1/oidc/d1OidcBoundary.d.ts +5 -0
- package/dist/types/wallet-server/src/router/cloudflare/d1/registration/d1RegistrationCeremonyRecords.d.ts +1 -0
- package/dist/types/wallet-server/src/router/cloudflare/d1/registration/d1WalletRegistrationSetup.d.ts +2 -0
- package/dist/types/wallet-server/src/router/cloudflare/d1/registration/walletRegistrationSessionCommitReceipt.d.ts +7 -1
- package/dist/types/wallet-server/src/router/cloudflare/d1/wallet/authorizationSnapshotLayout.d.ts +1 -1
- package/dist/types/wallet-server/src/router/cloudflare/d1/wallet/d1WalletAuthMethodService.d.ts +1 -0
- package/dist/types/wallet-server/src/router/cloudflare/runtime/staticWalletConsoleBinding.d.ts +2 -0
- package/dist/types/wallet-server/src/router/domains/signingOperations/routerAbEd25519NormalSigningRoute.d.ts +2 -2
- package/dist/types/wallet-server/src/router/domains/signingOperations/routerAbOperationStepUp.d.ts +1 -1
- package/dist/types/wallet-server/src/router/domains/walletRegistration/walletRegistrationInputs.d.ts +1 -0
- package/dist/types/wallet-server/src/router/domains/walletRegistration/walletRegistrationReservation.d.ts +11 -6
- package/dist/types/wallet-server/src/router/framework/apiCredentialPorts.d.ts +1 -0
- package/dist/types/wallet-server/src/router/framework/authServicePort.d.ts +12 -0
- package/dist/types/wallet-server/src/router/transport/fetch/routes/externalAuth.d.ts +5 -0
- package/dist/types/wallet-server/src/router/transport/fetch/walletOwnerOperationAuthorization.d.ts +23 -0
- package/migrations/d1-signer/0085_external_wallet_auth.sql +158 -0
- package/migrations/d1-signer/0086_application_auth.sql +67 -0
- package/migrations/d1-signer/0087_registration_without_session.sql +43 -0
- package/package.json +7 -2
- package/dist/types/shared-ts/src/authorization/walletCustodyOperation.d.ts +0 -10
|
@@ -1,22 +1,22 @@
|
|
|
1
1
|
import { parseEmailOtpChallengeId, parseOrgId, parseProviderSubject, parseWalletId, parseWebAuthnCredentialIdB64u } from "../../../../shared-ts/src/utils/domainIds.js";
|
|
2
|
-
import { buildAuthorizationGrantRef, parseAuthFactorId, parseAuthorizationAuditEventId, parseAuthorizationEvidenceId, parseAuthorizationEvidenceSetId, parseAuthorizedOperationId, parseCapabilityId, parseCapabilityOperationId, parsePrincipalId } from "../../../../shared-ts/src/authorization/capabilityKinds.js";
|
|
3
2
|
import { isPlainObject } from "../../../../shared-ts/src/utils/validation.js";
|
|
4
3
|
import { base64UrlEncode } from "../../../../shared-ts/src/utils/base64.js";
|
|
5
4
|
import { alphabetizeStringify, sha256BytesUtf8 } from "../../../../shared-ts/src/utils/digests.js";
|
|
6
5
|
import { parseDigestB64u } from "../../../../shared-ts/src/utils/canonicalPrimitives.js";
|
|
7
|
-
import { buildCapabilityOperationEnvelope, computeCapabilityOperationFingerprintDigest, parseCapabilityOperationFingerprintDigest, parseSigningOperationFingerprintDigest } from "../../../../shared-ts/src/authorization/operationFingerprint.js";
|
|
8
6
|
import "../../../../shared-ts/src/utils/encoders.js";
|
|
7
|
+
import { buildAuthorizationGrantRef, parseAuthFactorId, parseAuthorizationAuditEventId, parseAuthorizationEvidenceId, parseAuthorizationEvidenceSetId, parseAuthorizedOperationId, parseCapabilityId, parseCapabilityOperationId, parsePrincipalId } from "../../../../shared-ts/src/authorization/capabilityKinds.js";
|
|
8
|
+
import { buildCapabilityOperationEnvelope, computeCapabilityOperationFingerprintDigest, parseCapabilityOperationFingerprintDigest, parseSigningOperationFingerprintDigest } from "../../../../shared-ts/src/authorization/operationFingerprint.js";
|
|
9
9
|
import { sameRouterAbMpcMaterialActivationRef } from "../../../../shared-ts/src/utils/routerAbNormalSigningIdentity.js";
|
|
10
10
|
import { isPasskeyWalletAuthAuthority, walletAuthAuthorityRef } from "../../../../shared-ts/src/utils/walletAuthAuthority.js";
|
|
11
11
|
import { authorizedOperationReplayBodyInit, parseSessionOrigin, parseVerifiedOwnerProofId } from "../../../../authorization/domain.js";
|
|
12
12
|
import { buildVerifiedWalletOperationEmailOtpFactorResult, buildVerifiedWalletOperationPasskeyFactorResult, buildVerifiedWalletSessionPasskeyFactorResult } from "../../../../authorization/factorEvidence.js";
|
|
13
|
-
import {
|
|
13
|
+
import { EMAIL_OTP_CHANNEL, WALLET_EMAIL_OTP_TRANSACTION_SIGN_OPERATION } from "../../../../shared-ts/src/utils/emailOtpDomain.js";
|
|
14
|
+
import { emailOtpStatusCode, hashEmailOtpOperationBinding } from "../../../domains/emailOtp/emailOtpSessionRouteHelpers.js";
|
|
14
15
|
import { normalizeCorsOrigin } from "../../../../core/SessionService.js";
|
|
16
|
+
import { json, readJson } from "../../../framework/http.js";
|
|
17
|
+
import { ROUTER_AB_ED25519_NORMAL_SIGNING_PATH, ROUTER_AB_ED25519_NORMAL_SIGNING_PREPARE_PATH, ROUTER_AB_ED25519_WALLET_SESSION_PATH } from "../../../../shared-ts/src/utils/signingSessionSeal.js";
|
|
15
18
|
import { walletIdFromString } from "../../../../shared-ts/src/utils/registrationIds.js";
|
|
16
19
|
import { resolveThresholdRuntimePolicyScope } from "../../../auth/commonRouterUtils.js";
|
|
17
|
-
import { json, readJson } from "../../../framework/http.js";
|
|
18
|
-
import { emailOtpStatusCode, hashEmailOtpOperationBinding } from "../../../domains/emailOtp/emailOtpSessionRouteHelpers.js";
|
|
19
|
-
import { EMAIL_OTP_CHANNEL, WALLET_EMAIL_OTP_TRANSACTION_SIGN_OPERATION } from "../../../../shared-ts/src/utils/emailOtpDomain.js";
|
|
20
20
|
import { thresholdEd25519StatusCode } from "../../../../threshold/statusCodes.js";
|
|
21
21
|
import { signingPrepareSessionResponse } from "../../../domains/signingOperations/signingPrepareSession.js";
|
|
22
22
|
import { authenticateRouterAbWalletOperationStepUpIdentity } from "../../../domains/signingOperations/routerAbOperationStepUp.js";
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { parseMpcMaterialActivationRef } from "../../../../shared-ts/src/utils/domainIds.js";
|
|
2
|
-
import { EVM_ECDSA_MPC_OPERATION_KINDS } from "../../../../shared-ts/src/authorization/capabilityKinds.js";
|
|
3
2
|
import { isPlainObject } from "../../../../shared-ts/src/utils/validation.js";
|
|
3
|
+
import { EVM_ECDSA_MPC_OPERATION_KINDS } from "../../../../shared-ts/src/authorization/capabilityKinds.js";
|
|
4
4
|
import { routerAbMpcMaterialActivationRefToWire } from "../../../../shared-ts/src/utils/routerAbNormalSigningIdentity.js";
|
|
5
|
+
import { json, readJson } from "../../../framework/http.js";
|
|
5
6
|
import { walletSessionFailure, walletSessionFailureStatus } from "../../../auth/walletSessionFailure.js";
|
|
6
7
|
import { validateRouterAbEcdsaDerivationWalletSessionInputs } from "../../../auth/commonRouterUtils.js";
|
|
7
|
-
import { json, readJson } from "../../../framework/http.js";
|
|
8
8
|
//#region src/router/transport/fetch/routes/walletExecutionLanePreflight.ts
|
|
9
9
|
const OWNER_WALLET_EXECUTION_LANE_PREFLIGHT_PATH = "/wallet/execution-lane/owner";
|
|
10
10
|
function parsePreflightRequest(raw) {
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { findRouteDefinitionById, matchesRouteDefinitionRequest } from "../../../framework/routeDefinitions.js";
|
|
2
|
-
import { resolveSourceIpFromFetchHeaders } from "../../../auth/routerApiKeyAuth.js";
|
|
3
1
|
import { toFetchRouteResponse } from "../../../framework/routeResponses.js";
|
|
4
|
-
import {
|
|
2
|
+
import { resolveSourceIpFromFetchHeaders } from "../../../auth/routerApiKeyAuth.js";
|
|
5
3
|
import "../../../../shared-ts/src/utils/walletManagementProtocol.js";
|
|
6
4
|
import { jsonFailure, readJson } from "../../../framework/http.js";
|
|
5
|
+
import { findRouteDefinitionById, matchesRouteDefinitionRequest } from "../../../framework/routeDefinitions.js";
|
|
6
|
+
import { handleRouterApiWalletAddAuthMethodEmailOtpChallenge, handleRouterApiWalletAddAuthMethodFinalize, handleRouterApiWalletAddAuthMethodIntent, handleRouterApiWalletAddAuthMethodStart, handleRouterApiWalletAddSignerEcdsaActivation, handleRouterApiWalletAddSignerEcdsaDerivationRespond, handleRouterApiWalletAddSignerFinalize, handleRouterApiWalletAddSignerIntent, handleRouterApiWalletAddSignerStart, handleRouterApiWalletEcdsaKeyFactsInventory, handleRouterApiWalletNearImplicitAccountFund, handleRouterApiWalletRegistrationActivate, handleRouterApiWalletRegistrationNearAdmission, handleRouterApiWalletRegistrationNearProvisioning, handleRouterApiWalletRegistrationRespond, handleRouterApiWalletRegistrationSetup, handleRouterApiWalletRevokeAuthMethod } from "../../../domains/walletRegistration/walletRegistrationRoutes.js";
|
|
7
7
|
import { routerApiWalletRegistrationRouteService } from "../../../framework/authServicePort.js";
|
|
8
8
|
//#region src/router/transport/fetch/routes/walletRegistration.ts
|
|
9
9
|
const ROUTE_IDS = [
|
|
@@ -44,7 +44,7 @@ function resolveWalletRegistrationRoute(ctx) {
|
|
|
44
44
|
async function handleWalletRegistration(ctx) {
|
|
45
45
|
const route = resolveWalletRegistrationRoute(ctx);
|
|
46
46
|
if (!route) return null;
|
|
47
|
-
if (ctx.request.headers.get("X-Seams-Wallet-Protocol") !== "
|
|
47
|
+
if (ctx.request.headers.get("X-Seams-Wallet-Protocol") !== "5") return jsonFailure(409, "wallet_protocol_mismatch", "Your wallet application needs an update. Reload this page and try again. If the problem continues, ask the application developer to upgrade the Wallet SDK.");
|
|
48
48
|
const common = {
|
|
49
49
|
body: await readJson(ctx.request),
|
|
50
50
|
headers: Object.fromEntries(ctx.request.headers.entries()),
|
|
@@ -0,0 +1,306 @@
|
|
|
1
|
+
import { parseEmailOtpChallengeId, parseOrgId, parseProviderSubject, parseWalletId, parseWebAuthnCredentialIdB64u } from "../../../shared-ts/src/utils/domainIds.js";
|
|
2
|
+
import { normalizeOptionalTrimmedString } from "../../../shared-ts/src/utils/normalize.js";
|
|
3
|
+
import { alphabetizeStringify } from "../../../shared-ts/src/utils/digests.js";
|
|
4
|
+
import { sha256Utf8DigestB64u } from "../../../shared-ts/src/utils/canonicalPrimitives.js";
|
|
5
|
+
import { requireParsed } from "../../../shared-ts/src/passkey-custody/primitives.js";
|
|
6
|
+
import { computeWalletOwnerAdminChallengeDigest } from "../../../shared-ts/src/authorization/walletOwnerOperation.js";
|
|
7
|
+
import { buildVaultOperationRef, parseAuthFactorId, parseAuthorizationAuditEventId, parseAuthorizationEvidenceId, parseAuthorizationEvidenceSetId, parseAuthorizedOperationId, parseCapabilityId, parseCapabilityOperationId, parsePrincipalId, parseTenantId } from "../../../shared-ts/src/authorization/capabilityKinds.js";
|
|
8
|
+
import { buildDelegatedWalletAuthorityV1, buildFullOwnerPermissionsV1, sameDelegatedWalletAuthorityV1 } from "../../../shared-ts/src/authorization/delegatedAuthority.js";
|
|
9
|
+
import { buildCapabilityOperationEnvelope, computeCapabilityOperationFingerprintDigest } from "../../../shared-ts/src/authorization/operationFingerprint.js";
|
|
10
|
+
import { buildPasskeyWalletAuthAuthority, walletAuthAuthorityRef } from "../../../shared-ts/src/utils/walletAuthAuthority.js";
|
|
11
|
+
import { parseSessionOrigin, parseVerifiedOwnerProofId } from "../../../authorization/domain.js";
|
|
12
|
+
import { buildVerifiedWalletOperationEmailOtpFactorResult, buildVerifiedWalletOperationPasskeyFactorResult } from "../../../authorization/factorEvidence.js";
|
|
13
|
+
import { EMAIL_OTP_CHANNEL, WALLET_EMAIL_OTP_UNLOCK_OPERATION } from "../../../shared-ts/src/utils/emailOtpDomain.js";
|
|
14
|
+
import { parseWebAuthnAuthenticationCredential } from "../../auth/webAuthnCredentialCodecs.js";
|
|
15
|
+
import { emailOtpStatusCode, hashEmailOtpOperationBinding } from "../../domains/emailOtp/emailOtpSessionRouteHelpers.js";
|
|
16
|
+
import { toFetchRouteResponse } from "../../framework/routeResponses.js";
|
|
17
|
+
import { parseCustodyOwnerProof } from "./routes/walletCustodyRequestBoundary.js";
|
|
18
|
+
//#region src/router/transport/fetch/walletOwnerOperationAuthorization.ts
|
|
19
|
+
const CUSTODY_OPERATION_CAPABILITY_ID = "wallet-custody-admin";
|
|
20
|
+
const CUSTODY_PROOF_TTL_MS = 6e4;
|
|
21
|
+
function walletOwnerOperationAuthorizationId(operation, challenge) {
|
|
22
|
+
return requireParsed(parseAuthorizedOperationId(`wallet-custody:authorized:wallet-custody:${operation}:${challenge}`), "owner operation");
|
|
23
|
+
}
|
|
24
|
+
function hasFullOwnerAuthority(authority) {
|
|
25
|
+
return sameDelegatedWalletAuthorityV1(buildDelegatedWalletAuthorityV1({ permissions: authority.permissions }), buildDelegatedWalletAuthorityV1({ permissions: buildFullOwnerPermissionsV1() }));
|
|
26
|
+
}
|
|
27
|
+
async function custodyDigest(domain, value) {
|
|
28
|
+
return sha256Utf8DigestB64u(`${domain}|${alphabetizeStringify(value)}`);
|
|
29
|
+
}
|
|
30
|
+
async function buildWalletCustodyOperation(input) {
|
|
31
|
+
const tenantId = requireParsed(parseTenantId(input.tenantId), "authorization");
|
|
32
|
+
const principalId = requireParsed(parsePrincipalId(input.principalId), "authorization");
|
|
33
|
+
const capabilityId = requireParsed(parseCapabilityId(CUSTODY_OPERATION_CAPABILITY_ID), "authorization");
|
|
34
|
+
const operationRef = buildVaultOperationRef("vault.reveal");
|
|
35
|
+
const laneDigest = await custodyDigest("seams:wallet-custody:lane:v1", {
|
|
36
|
+
capabilityId,
|
|
37
|
+
operation: input.operation,
|
|
38
|
+
operationRef
|
|
39
|
+
});
|
|
40
|
+
const challengeDigest = await computeWalletOwnerAdminChallengeDigest({
|
|
41
|
+
walletId: input.walletId,
|
|
42
|
+
operation: input.operation,
|
|
43
|
+
payload: input.payload,
|
|
44
|
+
requestOrigin: input.requestOrigin
|
|
45
|
+
});
|
|
46
|
+
const intentDigest = challengeDigest;
|
|
47
|
+
const displayDigest = await custodyDigest("seams:wallet-custody:display:v1", {
|
|
48
|
+
walletId: input.walletId,
|
|
49
|
+
operation: input.operation
|
|
50
|
+
});
|
|
51
|
+
return {
|
|
52
|
+
operation: buildCapabilityOperationEnvelope({
|
|
53
|
+
tenantId,
|
|
54
|
+
principalId,
|
|
55
|
+
capabilityId,
|
|
56
|
+
operationId: requireParsed(parseCapabilityOperationId(`wallet-custody:${input.operation}:${intentDigest}`), "authorization"),
|
|
57
|
+
operation: operationRef,
|
|
58
|
+
digests: {
|
|
59
|
+
laneDigest,
|
|
60
|
+
intentDigest,
|
|
61
|
+
displayDigest
|
|
62
|
+
}
|
|
63
|
+
}),
|
|
64
|
+
challengeDigest
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
async function authorizeWalletOwnerOperation(input) {
|
|
68
|
+
const requestOrigin = normalizeOptionalTrimmedString(input.ctx.request.headers.get("origin"));
|
|
69
|
+
if (!requestOrigin) return toCustodyAuthorizationFailure(400, "invalid_origin", "request Origin is required");
|
|
70
|
+
let origin;
|
|
71
|
+
let proof;
|
|
72
|
+
let walletId;
|
|
73
|
+
try {
|
|
74
|
+
origin = parseSessionOrigin(requestOrigin);
|
|
75
|
+
walletId = requireParsed(parseWalletId(input.walletId), "authorization");
|
|
76
|
+
proof = parseCustodyOwnerProof(input.factorProof);
|
|
77
|
+
} catch (error) {
|
|
78
|
+
return toCustodyAuthorizationFailure(400, "invalid_owner_proof", error instanceof Error ? error.message : "owner proof is invalid");
|
|
79
|
+
}
|
|
80
|
+
if (proof.kind === "passkey" && proof.walletId !== input.walletId) return toCustodyAuthorizationFailure(403, "scope_mismatch", "owner proof wallet differs");
|
|
81
|
+
let principalId;
|
|
82
|
+
let factor;
|
|
83
|
+
let ownerAuthorityRef;
|
|
84
|
+
let ownerAuthority;
|
|
85
|
+
let operation;
|
|
86
|
+
let challengeDigest;
|
|
87
|
+
try {
|
|
88
|
+
principalId = proof.kind === "passkey" ? input.walletId : proof.provider_subject_id;
|
|
89
|
+
const built = await buildWalletCustodyOperation({
|
|
90
|
+
tenantId: input.ctx.service.authorizedOperations.tenantId,
|
|
91
|
+
principalId,
|
|
92
|
+
walletId: input.walletId,
|
|
93
|
+
operation: input.operation,
|
|
94
|
+
payload: input.payload,
|
|
95
|
+
requestOrigin
|
|
96
|
+
});
|
|
97
|
+
operation = built.operation;
|
|
98
|
+
challengeDigest = built.challengeDigest;
|
|
99
|
+
} catch (error) {
|
|
100
|
+
return toCustodyAuthorizationFailure(400, "invalid_owner_proof", error instanceof Error ? error.message : "owner proof binding is invalid");
|
|
101
|
+
}
|
|
102
|
+
const operationFingerprintDigest = await computeCapabilityOperationFingerprintDigest(operation);
|
|
103
|
+
const nowMs = Date.now();
|
|
104
|
+
if (proof.challenge_digest !== String(challengeDigest)) return toCustodyAuthorizationFailure(403, "scope_mismatch", "factor proof challenge does not match the requested operation");
|
|
105
|
+
if (proof.kind === "passkey") {
|
|
106
|
+
let authority;
|
|
107
|
+
try {
|
|
108
|
+
authority = buildPasskeyWalletAuthAuthority({
|
|
109
|
+
walletId,
|
|
110
|
+
rpId: proof.rpId,
|
|
111
|
+
credentialIdB64u: proof.credentialIdB64u
|
|
112
|
+
});
|
|
113
|
+
} catch (error) {
|
|
114
|
+
return toCustodyAuthorizationFailure(400, "invalid_owner_proof", error instanceof Error ? error.message : "passkey authority is invalid");
|
|
115
|
+
}
|
|
116
|
+
const active = await input.ctx.service.walletAuthMethods.resolveActivePasskeyAuthorityForVerifiedCredential({
|
|
117
|
+
walletId,
|
|
118
|
+
rpId: authority.verifier.rpId,
|
|
119
|
+
credentialIdB64u: authority.factor.credentialIdB64u
|
|
120
|
+
});
|
|
121
|
+
if (!active.ok) return toCustodyAuthorizationFailure(403, active.code, active.message);
|
|
122
|
+
if (!hasFullOwnerAuthority(active.walletAuthority)) return toCustodyAuthorizationFailure(403, "forbidden", "Full owner authority is required");
|
|
123
|
+
ownerAuthority = active.walletAuthority;
|
|
124
|
+
const credential = parseWebAuthnAuthenticationCredential(proof.webauthn_authentication);
|
|
125
|
+
if (!credential) return toCustodyAuthorizationFailure(400, "invalid_owner_proof", "passkey assertion is invalid");
|
|
126
|
+
if (String(credential.rawId || credential.id).trim() !== authority.factor.credentialIdB64u) return toCustodyAuthorizationFailure(401, "unauthorized", "passkey credential changed");
|
|
127
|
+
const verified = await input.ctx.service.webAuthn.verifyWebAuthnAuthenticationLite({
|
|
128
|
+
userId: input.walletId,
|
|
129
|
+
rpId: authority.verifier.rpId,
|
|
130
|
+
expectedChallenge: challengeDigest,
|
|
131
|
+
expected_origin: requestOrigin,
|
|
132
|
+
webauthn_authentication: credential
|
|
133
|
+
});
|
|
134
|
+
if (!verified.success || !verified.verified) return toCustodyAuthorizationFailure(401, verified.code || "not_verified", verified.message || "WebAuthn authentication verification failed");
|
|
135
|
+
ownerAuthorityRef = await walletAuthAuthorityRef({ authority: active.authority });
|
|
136
|
+
factor = buildVerifiedWalletOperationPasskeyFactorResult({
|
|
137
|
+
tenantId: operation.tenantId,
|
|
138
|
+
principalId: operation.principalId,
|
|
139
|
+
walletId,
|
|
140
|
+
authorityRef: ownerAuthorityRef,
|
|
141
|
+
requestOrigin: origin,
|
|
142
|
+
audience: origin,
|
|
143
|
+
factorId: requireParsed(parseAuthFactorId(`passkey:${authority.factor.credentialIdB64u}`), "authorization"),
|
|
144
|
+
credentialIdB64u: requireParsed(parseWebAuthnCredentialIdB64u(authority.factor.credentialIdB64u), "authorization"),
|
|
145
|
+
assertionDigest: await custodyDigest("seams:wallet-custody:assertion:v1", { credential }),
|
|
146
|
+
operation,
|
|
147
|
+
verifiedAtMs: nowMs,
|
|
148
|
+
expiresAtMs: nowMs + CUSTODY_PROOF_TTL_MS
|
|
149
|
+
});
|
|
150
|
+
} else {
|
|
151
|
+
const providerSubject = requireParsed(parseProviderSubject(proof.provider_subject_id), "authorization");
|
|
152
|
+
const orgId = requireParsed(parseOrgId(input.ctx.service.authorizedOperations.tenantId), "authorization");
|
|
153
|
+
const active = await input.ctx.service.walletAuthMethods.resolveActiveEmailOtpAuthorityForVerifiedSubject({
|
|
154
|
+
walletId: input.walletId,
|
|
155
|
+
providerUserId: proof.provider_subject_id
|
|
156
|
+
});
|
|
157
|
+
if (!active.ok) return toCustodyAuthorizationFailure(403, active.code, active.message);
|
|
158
|
+
const activeAuthorityRef = await walletAuthAuthorityRef({ authority: active.authority });
|
|
159
|
+
ownerAuthorityRef = activeAuthorityRef;
|
|
160
|
+
ownerAuthority = active.walletAuthority;
|
|
161
|
+
const ownerProofBindingDigest = await hashEmailOtpOperationBinding({
|
|
162
|
+
walletId: input.walletId,
|
|
163
|
+
providerUserId: proof.provider_subject_id,
|
|
164
|
+
orgId,
|
|
165
|
+
operation: `wallet_custody:${input.operation}`,
|
|
166
|
+
requestOrigin,
|
|
167
|
+
audience: requestOrigin,
|
|
168
|
+
authorityRef: activeAuthorityRef,
|
|
169
|
+
operationFingerprintDigest: challengeDigest
|
|
170
|
+
});
|
|
171
|
+
const verified = await input.ctx.service.emailOtp.verifyEmailOtpChallenge({
|
|
172
|
+
userId: proof.provider_subject_id,
|
|
173
|
+
walletId: input.walletId,
|
|
174
|
+
orgId,
|
|
175
|
+
challengeId: proof.challenge_id,
|
|
176
|
+
otpCode: proof.otp_code,
|
|
177
|
+
otpChannel: EMAIL_OTP_CHANNEL,
|
|
178
|
+
ownerProofBindingDigest,
|
|
179
|
+
operation: WALLET_EMAIL_OTP_UNLOCK_OPERATION
|
|
180
|
+
});
|
|
181
|
+
if (!verified.ok) return toCustodyAuthorizationFailure(verified.code === "invalid_body" ? 400 : 401, verified.code, verified.message);
|
|
182
|
+
const consumed = await input.ctx.service.emailOtp.consumeEmailOtpGrant({
|
|
183
|
+
subject: {
|
|
184
|
+
kind: "provider_identity",
|
|
185
|
+
orgId,
|
|
186
|
+
providerSubject,
|
|
187
|
+
walletId
|
|
188
|
+
},
|
|
189
|
+
loginGrant: verified.loginGrant,
|
|
190
|
+
otpChannel: EMAIL_OTP_CHANNEL
|
|
191
|
+
});
|
|
192
|
+
if (!consumed.ok) return toCustodyAuthorizationFailure(emailOtpStatusCode(consumed.code), consumed.code, consumed.message);
|
|
193
|
+
factor = buildVerifiedWalletOperationEmailOtpFactorResult({
|
|
194
|
+
tenantId: operation.tenantId,
|
|
195
|
+
principalId: operation.principalId,
|
|
196
|
+
walletId,
|
|
197
|
+
authorityRef: activeAuthorityRef,
|
|
198
|
+
requestOrigin: origin,
|
|
199
|
+
audience: origin,
|
|
200
|
+
factorId: requireParsed(parseAuthFactorId(`email_otp:${active.authority.factor.provider}:${proof.provider_subject_id}`), "authorization"),
|
|
201
|
+
operation,
|
|
202
|
+
challengeId: requireParsed(parseEmailOtpChallengeId(consumed.challengeId), "authorization"),
|
|
203
|
+
verificationReceiptDigest: await custodyDigest("seams:wallet-custody:otp-receipt:v1", {
|
|
204
|
+
challengeId: consumed.challengeId,
|
|
205
|
+
operationFingerprintDigest
|
|
206
|
+
}),
|
|
207
|
+
verifiedAtMs: nowMs,
|
|
208
|
+
expiresAtMs: Math.min(nowMs + CUSTODY_PROOF_TTL_MS, verified.grantExpiresAtMs)
|
|
209
|
+
});
|
|
210
|
+
}
|
|
211
|
+
const ownerProof = await input.ctx.service.authorizedOperations.buildVerifiedOwnerProof({
|
|
212
|
+
purpose: "operation",
|
|
213
|
+
proofId: parseVerifiedOwnerProofId(`wallet-custody:${operation.operationId}`),
|
|
214
|
+
factor
|
|
215
|
+
});
|
|
216
|
+
if (ownerProof.purpose !== "operation" || ownerProof.operation.operationFingerprintDigest !== operationFingerprintDigest) return toCustodyAuthorizationFailure(403, "owner_proof_rejected", "owner proof binding is invalid");
|
|
217
|
+
const existing = await input.ctx.service.authorizedOperations.readAuthorizedOperation({
|
|
218
|
+
tenantId: operation.tenantId,
|
|
219
|
+
operationFingerprintDigest
|
|
220
|
+
});
|
|
221
|
+
if (existing) {
|
|
222
|
+
if (existing.authorization.kind !== "verified_step_up" || existing.quota.kind !== "quota_neutral") return toCustodyAuthorizationFailure(403, "owner_proof_rejected", "Owner operation authorization differs");
|
|
223
|
+
return {
|
|
224
|
+
ok: false,
|
|
225
|
+
response: authorizedOperationReplay(existing)
|
|
226
|
+
};
|
|
227
|
+
}
|
|
228
|
+
const evidenceSet = await input.ctx.service.authorizedOperations.recordVerifiedWalletOperationFactorEvidenceSet({
|
|
229
|
+
operation,
|
|
230
|
+
evidenceId: requireParsed(parseAuthorizationEvidenceId(`wallet-custody:evidence:${operation.operationId}`), "authorization"),
|
|
231
|
+
evidenceSetId: requireParsed(parseAuthorizationEvidenceSetId(`wallet-custody:evidence-set:${operation.operationId}`), "authorization"),
|
|
232
|
+
factor
|
|
233
|
+
});
|
|
234
|
+
const admission = await input.ctx.service.authorizedOperations.admitAuthorizedOperation({ operation: {
|
|
235
|
+
tenantId: operation.tenantId,
|
|
236
|
+
authorizedOperationId: walletOwnerOperationAuthorizationId(input.operation, challengeDigest),
|
|
237
|
+
auditEventId: requireParsed(parseAuthorizationAuditEventId(`wallet-custody:audit:${operation.operationId}`), "authorization"),
|
|
238
|
+
operation,
|
|
239
|
+
authorization: {
|
|
240
|
+
kind: "verified_step_up",
|
|
241
|
+
evidenceSetDigest: evidenceSet.evidenceSetDigest
|
|
242
|
+
},
|
|
243
|
+
quota: { kind: "quota_neutral" },
|
|
244
|
+
claimedAtMs: nowMs
|
|
245
|
+
} });
|
|
246
|
+
switch (admission.kind) {
|
|
247
|
+
case "claimed": return {
|
|
248
|
+
ok: true,
|
|
249
|
+
operation: admission.operation,
|
|
250
|
+
ownerAuthority
|
|
251
|
+
};
|
|
252
|
+
case "replayed":
|
|
253
|
+
case "operation_in_progress": return {
|
|
254
|
+
ok: false,
|
|
255
|
+
response: authorizedOperationReplay(admission.operation)
|
|
256
|
+
};
|
|
257
|
+
case "authorization_grant_rejected":
|
|
258
|
+
case "verified_step_up_rejected":
|
|
259
|
+
case "wallet_session_quota_exhausted":
|
|
260
|
+
case "material_mismatch": return toCustodyAuthorizationFailure(403, "owner_proof_rejected", "owner proof was rejected");
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
function toCustodyAuthorizationFailure(status, code, message) {
|
|
264
|
+
return {
|
|
265
|
+
ok: false,
|
|
266
|
+
response: routeErrorResponse(status, code, message)
|
|
267
|
+
};
|
|
268
|
+
}
|
|
269
|
+
function routeErrorResponse(status, code, message) {
|
|
270
|
+
return toFetchRouteResponse({
|
|
271
|
+
status,
|
|
272
|
+
body: {
|
|
273
|
+
ok: false,
|
|
274
|
+
code,
|
|
275
|
+
message
|
|
276
|
+
}
|
|
277
|
+
});
|
|
278
|
+
}
|
|
279
|
+
function authorizedOperationReplay(operation) {
|
|
280
|
+
if (operation.lifecycle !== "completed") return routeErrorResponse(409, "recovery_in_progress", "wallet recovery is still in progress");
|
|
281
|
+
return new Response(operation.response.bodyText, {
|
|
282
|
+
status: operation.response.status,
|
|
283
|
+
headers: { "content-type": operation.response.contentType }
|
|
284
|
+
});
|
|
285
|
+
}
|
|
286
|
+
async function completeWalletOwnerOperation(ctx, operation, status, body, result = "succeeded") {
|
|
287
|
+
const bodyText = JSON.stringify(body);
|
|
288
|
+
await ctx.service.authorizedOperations.completeAuthorizedOperation({
|
|
289
|
+
operation,
|
|
290
|
+
result,
|
|
291
|
+
response: {
|
|
292
|
+
status,
|
|
293
|
+
contentType: "application/json",
|
|
294
|
+
bodyText
|
|
295
|
+
},
|
|
296
|
+
completedAtMs: Date.now()
|
|
297
|
+
});
|
|
298
|
+
return toFetchRouteResponse({
|
|
299
|
+
status,
|
|
300
|
+
body
|
|
301
|
+
});
|
|
302
|
+
}
|
|
303
|
+
//#endregion
|
|
304
|
+
export { authorizeWalletOwnerOperation, completeWalletOwnerOperation, walletOwnerOperationAuthorizationId };
|
|
305
|
+
|
|
306
|
+
//# sourceMappingURL=walletOwnerOperationAuthorization.js.map
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import { parseWalletId } from "../utils/domainIds.js";
|
|
2
|
+
import { requireCanonicalString, requireRecord } from "../utils/validation.js";
|
|
3
|
+
import { parseEd25519PublicKeyB64u, parseUnixMs } from "../passkey-custody/primitives.js";
|
|
4
|
+
//#region ../shared-ts/src/auth/externalAuth.ts
|
|
5
|
+
const EXTERNAL_AUTH_PATH = "/wallet/external-auth";
|
|
6
|
+
function parseExternalAuthProvider(raw) {
|
|
7
|
+
const value = requireRecord(raw, "external authentication provider");
|
|
8
|
+
switch (value.kind) {
|
|
9
|
+
case "disabled": return { kind: "disabled" };
|
|
10
|
+
case "google": return {
|
|
11
|
+
kind: "google",
|
|
12
|
+
clientId: requireCanonicalString(value.clientId, "clientId")
|
|
13
|
+
};
|
|
14
|
+
case "application": {
|
|
15
|
+
const issuer = requireCanonicalString(value.issuer, "issuer");
|
|
16
|
+
const url = new URL(issuer);
|
|
17
|
+
if (url.protocol !== "https:" || url.origin !== issuer) throw new Error("Application issuer must be a canonical HTTPS origin");
|
|
18
|
+
return {
|
|
19
|
+
kind: "application",
|
|
20
|
+
issuer,
|
|
21
|
+
publicKeyB64u: parseEd25519PublicKeyB64u(value.publicKeyB64u, "publicKeyB64u")
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
default: throw new Error("Unsupported external authentication provider");
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
function externalAuthConfiguration(provider, revision) {
|
|
28
|
+
switch (provider.kind) {
|
|
29
|
+
case "disabled": return {
|
|
30
|
+
kind: "disabled",
|
|
31
|
+
revision
|
|
32
|
+
};
|
|
33
|
+
case "google": return {
|
|
34
|
+
kind: "google",
|
|
35
|
+
revision,
|
|
36
|
+
clientId: provider.clientId
|
|
37
|
+
};
|
|
38
|
+
case "application": return {
|
|
39
|
+
kind: "application",
|
|
40
|
+
revision,
|
|
41
|
+
issuer: provider.issuer,
|
|
42
|
+
publicKeyB64u: provider.publicKeyB64u
|
|
43
|
+
};
|
|
44
|
+
default: return assertNever(provider);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
function parseExternalAuthConfiguration(raw) {
|
|
48
|
+
const value = requireRecord(raw, "external authentication configuration");
|
|
49
|
+
if (typeof value.revision !== "number" || !Number.isSafeInteger(value.revision) || value.revision < 0) throw new Error("Invalid external authentication revision");
|
|
50
|
+
return externalAuthConfiguration(parseExternalAuthProvider(value), value.revision);
|
|
51
|
+
}
|
|
52
|
+
function serializeExternalIdentity(identity) {
|
|
53
|
+
return JSON.stringify([
|
|
54
|
+
identity.provider,
|
|
55
|
+
identity.issuer,
|
|
56
|
+
identity.subject
|
|
57
|
+
]);
|
|
58
|
+
}
|
|
59
|
+
function parseStoredExternalIdentity(serialized) {
|
|
60
|
+
const raw = JSON.parse(serialized);
|
|
61
|
+
if (!Array.isArray(raw) || raw.length !== 3) throw new Error("Invalid external identity");
|
|
62
|
+
const [provider, issuer, subject] = raw;
|
|
63
|
+
return parseExternalIdentity({
|
|
64
|
+
provider,
|
|
65
|
+
issuer,
|
|
66
|
+
subject
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
function parseExternalIdentity(raw) {
|
|
70
|
+
const value = requireRecord(raw, "external identity");
|
|
71
|
+
const provider = value.provider;
|
|
72
|
+
const issuer = requireCanonicalString(value.issuer, "issuer");
|
|
73
|
+
const subject = requireCanonicalString(value.subject, "subject");
|
|
74
|
+
switch (provider) {
|
|
75
|
+
case "google":
|
|
76
|
+
if (issuer !== "https://accounts.google.com") throw new Error("Invalid Google issuer");
|
|
77
|
+
return {
|
|
78
|
+
provider,
|
|
79
|
+
issuer,
|
|
80
|
+
subject
|
|
81
|
+
};
|
|
82
|
+
case "application": return {
|
|
83
|
+
provider,
|
|
84
|
+
issuer,
|
|
85
|
+
subject
|
|
86
|
+
};
|
|
87
|
+
default: throw new Error("Invalid external identity provider");
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
function assertNever(value) {
|
|
91
|
+
throw new Error(`Unsupported external authentication provider: ${String(value)}`);
|
|
92
|
+
}
|
|
93
|
+
function parseExternalWalletAuthentication(value) {
|
|
94
|
+
const record = requireRecord(value, "external authentication");
|
|
95
|
+
const walletId = parseWalletId(record.walletId);
|
|
96
|
+
if (!walletId.ok || record.kind !== "external_authenticated" || record.provider !== "google" && record.provider !== "application" || record.permission !== "wallet_settings_read" || "authMethod" in record) throw new Error("External authentication is invalid");
|
|
97
|
+
return {
|
|
98
|
+
kind: "external_authenticated",
|
|
99
|
+
walletId: walletId.value,
|
|
100
|
+
sessionId: requireCanonicalString(record.sessionId, "sessionId"),
|
|
101
|
+
associationId: requireCanonicalString(record.associationId, "associationId"),
|
|
102
|
+
environmentId: requireCanonicalString(record.environmentId, "environmentId"),
|
|
103
|
+
provider: record.provider,
|
|
104
|
+
permission: "wallet_settings_read",
|
|
105
|
+
expiresAtMs: parseUnixMs(record.expiresAtMs, "expiresAtMs")
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
function externalAuthFailure(code) {
|
|
109
|
+
return {
|
|
110
|
+
ok: false,
|
|
111
|
+
code,
|
|
112
|
+
message: "Wallet authentication could not be completed."
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
//#endregion
|
|
116
|
+
export { EXTERNAL_AUTH_PATH, externalAuthFailure, parseExternalAuthConfiguration, parseExternalAuthProvider, parseExternalWalletAuthentication, parseStoredExternalIdentity, serializeExternalIdentity };
|
|
117
|
+
|
|
118
|
+
//# sourceMappingURL=externalAuth.js.map
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { parseWalletAuthMethodId, parseWalletAuthorityId, parseWalletId } from "../utils/domainIds.js";
|
|
2
|
-
import { parseWalletSessionMintId } from "./capabilityKinds.js";
|
|
3
2
|
import { isPlainObject } from "../utils/validation.js";
|
|
4
3
|
import { base64UrlDecode, base64UrlEncode } from "../utils/base64.js";
|
|
5
4
|
import { alphabetizeStringify } from "../utils/digests.js";
|
|
6
5
|
import { parseDigestB64u } from "../utils/canonicalPrimitives.js";
|
|
6
|
+
import { parseWalletSessionMintId } from "./capabilityKinds.js";
|
|
7
7
|
//#region ../shared-ts/src/authorization/voiceIdDeviceAssertion.ts
|
|
8
8
|
const CHALLENGE_DOMAIN = "seams:wallet-session:voiceid-device:v1";
|
|
9
9
|
const MAXIMUM_CHALLENGE_MS = 6e4;
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { parseLinkDeviceSessionId, parseLinkedDeviceEnrollmentId, parseMpcMaterialActivationRef, parseWalletAuthorityId, parseWalletId, parseWalletRecoveryOperationId } from "../utils/domainIds.js";
|
|
2
|
-
import { parseDeviceId } from "./capabilityKinds.js";
|
|
3
2
|
import { requireRecord } from "../utils/validation.js";
|
|
4
|
-
import { parseDelegatedWalletPermissionSetV1 } from "./delegatedAuthority.js";
|
|
5
3
|
import { base64UrlEncode } from "../utils/base64.js";
|
|
6
4
|
import { sha256Bytes } from "../utils/digests.js";
|
|
7
5
|
import { parseDigestB64u } from "../utils/canonicalPrimitives.js";
|
|
6
|
+
import { parseDeviceId } from "./capabilityKinds.js";
|
|
7
|
+
import { parseDelegatedWalletPermissionSetV1 } from "./delegatedAuthority.js";
|
|
8
8
|
import { buildExactAdministeredSignerManifestV1, parseExactAdministeredSignerManifestV1 } from "../device-linking/delegatedActivationPlan.js";
|
|
9
9
|
import { concat, lp32, rawDigest, rawPublicKey, text, u32, u64 } from "../utils/digestEncoding.js";
|
|
10
10
|
//#region ../shared-ts/src/authorization/walletAuthority.ts
|
package/dist/esm/shared-ts/src/authorization/{walletCustodyOperation.js → walletOwnerOperation.js}
RENAMED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { alphabetizeStringify } from "../utils/digests.js";
|
|
2
2
|
import { sha256Utf8DigestB64u } from "../utils/canonicalPrimitives.js";
|
|
3
|
-
//#region ../shared-ts/src/authorization/
|
|
3
|
+
//#region ../shared-ts/src/authorization/walletOwnerOperation.ts
|
|
4
4
|
/** Public challenge digest for a single wallet-administration factor proof. */
|
|
5
|
-
async function
|
|
5
|
+
async function computeWalletOwnerAdminChallengeDigest(input) {
|
|
6
6
|
return sha256Utf8DigestB64u(`seams:wallet-custody:challenge:v1|${alphabetizeStringify({
|
|
7
7
|
walletId: input.walletId,
|
|
8
8
|
operation: input.operation,
|
|
@@ -11,6 +11,6 @@ async function computeWalletCustodyAdminChallengeDigest(input) {
|
|
|
11
11
|
})}`);
|
|
12
12
|
}
|
|
13
13
|
//#endregion
|
|
14
|
-
export {
|
|
14
|
+
export { computeWalletOwnerAdminChallengeDigest };
|
|
15
15
|
|
|
16
|
-
//# sourceMappingURL=
|
|
16
|
+
//# sourceMappingURL=walletOwnerOperation.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { parseWalletId, parseWalletKeyId } from "../utils/domainIds.js";
|
|
2
2
|
import { requireRecord } from "../utils/validation.js";
|
|
3
|
-
import { rejectUnknownFields } from "../utils/exactRecord.js";
|
|
4
3
|
import { parseEd25519PublicKeyB64u, parseSecp256k1CompressedPublicKeyB64u, requireParsed } from "../passkey-custody/primitives.js";
|
|
4
|
+
import { rejectUnknownFields } from "../utils/exactRecord.js";
|
|
5
5
|
//#region ../shared-ts/src/device-linking/delegatedActivationPlan.ts
|
|
6
6
|
const MANIFEST_FIELDS = [
|
|
7
7
|
"kind",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { delegatedWalletPermissionNamesV1 } from "../authorization/delegatedAuthority.js";
|
|
2
1
|
import { alphabetizeStringify } from "../utils/digests.js";
|
|
3
2
|
import { sha256DigestB64u, sha256Utf8DigestB64u } from "../utils/canonicalPrimitives.js";
|
|
3
|
+
import { delegatedWalletPermissionNamesV1 } from "../authorization/delegatedAuthority.js";
|
|
4
4
|
import { concat, lp32, rawDigest, rawPublicKey, text, u32, u64 } from "../utils/digestEncoding.js";
|
|
5
5
|
import "./committedSignerPackages.js";
|
|
6
6
|
//#region ../shared-ts/src/device-linking/digests.ts
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { parseLinkDeviceSessionId, parseLinkedDeviceEnrollmentId, parseLinkedDeviceId, parseWalletId, parseWalletKeyId } from "../utils/domainIds.js";
|
|
2
2
|
import { requireRecord } from "../utils/validation.js";
|
|
3
|
-
import { rejectUnknownFields } from "../utils/exactRecord.js";
|
|
4
3
|
import { base64UrlDecode, base64UrlEncode } from "../utils/base64.js";
|
|
5
4
|
import { parseDigestField, parseEd25519PublicKeyB64u, parseEnvelopeCiphertextB64u, parseEnvelopeNonceB64u, requireParsed } from "../passkey-custody/primitives.js";
|
|
5
|
+
import { rejectUnknownFields } from "../utils/exactRecord.js";
|
|
6
6
|
//#region ../shared-ts/src/device-linking/ed25519ExportRoot.ts
|
|
7
7
|
/**
|
|
8
8
|
* Authenticated relay records for the cross-device Ed25519 Yao Client export
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { requireArray, requireRecord } from "../utils/validation.js";
|
|
2
|
+
import { base64UrlDecode, base64UrlEncode } from "../utils/base64.js";
|
|
3
|
+
import { parseEd25519PublicKeyB64u } from "../passkey-custody/primitives.js";
|
|
2
4
|
import { exactRecord } from "../utils/exactRecord.js";
|
|
3
5
|
import { wireLiteral, wireNullable, wireObject, wireUnion } from "../utils/wireSchema.js";
|
|
4
6
|
import "../authorization/delegatedAuthority.js";
|
|
5
|
-
import { base64UrlDecode, base64UrlEncode } from "../utils/base64.js";
|
|
6
|
-
import { parseEd25519PublicKeyB64u } from "../passkey-custody/primitives.js";
|
|
7
7
|
import { authorizationDeviceId, credentialId, digest, enrollmentId, linkedDeviceId, parseDelegatedWalletAuthority, parseNonEmptyToken, parseNonNegativeSafeInteger, parseTargetEmail, parseUnixTime, rpId, sessionId, walletAuthMethodId, walletAuthorityId, walletId, walletKeyId, walletSessionAuthorizationId, walletSessionId } from "./wireFields.js";
|
|
8
8
|
import { parseWalletAddAuthMethodRegistrationOptions } from "../utils/addAuthMethodRegistration.js";
|
|
9
9
|
import { requireRouterAbX25519PublicKey } from "../utils/routerAbPublicKeyset.js";
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { mpcMaterialActivationRefsEqual, parseLinkDeviceSessionId, parseLinkedDeviceEnrollmentId, parseMpcMaterialActivationRef, parseWalletAuthorityId, parseWalletKeyId } from "../utils/domainIds.js";
|
|
2
|
-
import { parseDeviceId } from "../authorization/capabilityKinds.js";
|
|
3
2
|
import { requireRecordCopy } from "../utils/validation.js";
|
|
4
3
|
import { base64UrlDecode, base64UrlEncode } from "../utils/base64.js";
|
|
5
4
|
import { parseDigestB64u } from "../utils/canonicalPrimitives.js";
|
|
6
5
|
import { parseEd25519PublicKeyB64u, parseEnvelopeCiphertextB64u, parseSecp256k1CompressedPublicKeyB64u } from "../passkey-custody/primitives.js";
|
|
6
|
+
import { parseDeviceId } from "../authorization/capabilityKinds.js";
|
|
7
7
|
import { routerAbMpcMaterialActivationRefFromWire } from "../utils/routerAbNormalSigningIdentity.js";
|
|
8
8
|
import { parseRouterAbEd25519YaoActivationBindingV1, parseRouterAbEd25519YaoActivationPublicReceiptV1, parseRouterAbEd25519YaoApplicationBindingFactsV1, parseRouterAbEd25519YaoEncryptedPackageV1, parseRouterAbEd25519YaoParticipantIdsV1, parseRouterAbEd25519YaoRegistrationActivationAdmissionReceiptV1, sameRouterAbEd25519YaoByteSequence } from "../utils/routerAbEd25519Yao.js";
|
|
9
9
|
import { parseSdkEcdsaDerivationThresholdKeyId } from "../threshold/ecdsaDerivationRoleLocalBootstrap.js";
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { parseLinkDeviceSessionId, parseWalletAuthMethodId, parseWalletAuthorityId, parseWalletId } from "../utils/domainIds.js";
|
|
2
|
-
import { parseMpcWalletSigningQuotaId, parsePrincipalId, parseTenantId, parseWalletSessionAuthorizationId, parseWalletSessionId } from "../authorization/capabilityKinds.js";
|
|
3
2
|
import { base64UrlDecode, base64UrlEncode } from "../utils/base64.js";
|
|
4
3
|
import { alphabetizeStringify } from "../utils/digests.js";
|
|
5
4
|
import { parseDigestB64u, sha256Utf8DigestB64u } from "../utils/canonicalPrimitives.js";
|
|
5
|
+
import { parseMpcWalletSigningQuotaId, parsePrincipalId, parseTenantId, parseWalletSessionAuthorizationId, parseWalletSessionId } from "../authorization/capabilityKinds.js";
|
|
6
6
|
import { parseLinkDevicePublicKeyB64u } from "./parsers.js";
|
|
7
7
|
//#region ../shared-ts/src/device-linking/walletSessionCredentialDelivery.ts
|
|
8
8
|
const DELIVERY_AAD_DOMAIN = "seams/linked-device/wallet-session-credential-delivery-aad/v1";
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { parseLinkDeviceSessionId, parseLinkedDeviceEnrollmentId, parseLinkedDeviceId, parseMpcMaterialActivationRef, parseVerifiedEmailAddress, parseWalletAuthMethodId, parseWalletAuthorityId, parseWalletId, parseWalletKeyId, parseWebAuthnCredentialIdB64u, parseWebAuthnRpId } from "../utils/domainIds.js";
|
|
2
|
+
import { parseDigestB64u } from "../utils/canonicalPrimitives.js";
|
|
3
|
+
import { parseUnixMs } from "../passkey-custody/primitives.js";
|
|
2
4
|
import { parseDeviceId, parseMpcWalletSigningQuotaId, parseWalletSessionAuthorizationId, parseWalletSessionId } from "../authorization/capabilityKinds.js";
|
|
3
5
|
import { wireLabeled, wireNullable, wireResult } from "../utils/wireSchema.js";
|
|
4
6
|
import { parseDelegatedWalletAuthorityV1 } from "../authorization/delegatedAuthority.js";
|
|
5
|
-
import { parseDigestB64u } from "../utils/canonicalPrimitives.js";
|
|
6
|
-
import { parseUnixMs } from "../passkey-custody/primitives.js";
|
|
7
7
|
//#region ../shared-ts/src/device-linking/wireFields.ts
|
|
8
8
|
const sessionId = /* @__PURE__ */ wireResult(parseLinkDeviceSessionId);
|
|
9
9
|
const walletId = /* @__PURE__ */ wireResult(parseWalletId);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { parsePasskeyEnvelopeId, parseWalletAuthMethodId, parseWalletId, parseWebAuthnCredentialIdB64u, parseWebAuthnRpId } from "../utils/domainIds.js";
|
|
2
2
|
import { requireRecord } from "../utils/validation.js";
|
|
3
|
-
import { rejectUnknownFields } from "../utils/exactRecord.js";
|
|
4
3
|
import { parseDigestField, parseEnvelopeCiphertextB64u, parseEnvelopeNonceB64u, parseEnvelopeRevision, parseUnixMs } from "./primitives.js";
|
|
4
|
+
import { rejectUnknownFields } from "../utils/exactRecord.js";
|
|
5
5
|
import { parsePasskeyCustodySecretBinding } from "./custodySecretBinding.js";
|
|
6
6
|
//#region ../shared-ts/src/passkey-custody/custodyEnvelope.ts
|
|
7
7
|
const WALLET_CUSTODY_ENVELOPE_VERSION_V2 = "wallet_custody_envelope_v2";
|