@oxy.so/contracts 1.1.0 → 1.2.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/dist/cjs/.tsbuildinfo +1 -1
- package/dist/cjs/identityMove.js +85 -0
- package/dist/cjs/index.js +37 -10
- package/dist/cjs/inference/catalogue.js +7 -6
- package/dist/cjs/inference/version.js +1 -1
- package/dist/cjs/userResponse.js +82 -1
- package/dist/cjs/webIdentityCarrier.js +122 -0
- package/dist/esm/.tsbuildinfo +1 -1
- package/dist/esm/identityMove.js +82 -0
- package/dist/esm/index.js +7 -1
- package/dist/esm/inference/catalogue.js +7 -6
- package/dist/esm/inference/version.js +1 -1
- package/dist/esm/userResponse.js +81 -0
- package/dist/esm/webIdentityCarrier.js +119 -0
- package/dist/types/.tsbuildinfo +1 -1
- package/dist/types/externalIdentity.d.ts +14 -0
- package/dist/types/identityMove.d.ts +109 -0
- package/dist/types/index.d.ts +5 -1
- package/dist/types/inference/catalogue.d.ts +21 -20
- package/dist/types/inference/embeddings.d.ts +12 -12
- package/dist/types/inference/errors.d.ts +4 -4
- package/dist/types/inference/inbox.d.ts +6 -6
- package/dist/types/inference/streamEvents.d.ts +12 -12
- package/dist/types/inference/usage.d.ts +8 -8
- package/dist/types/inference/version.d.ts +1 -1
- package/dist/types/userResponse.d.ts +368 -0
- package/dist/types/webIdentityCarrier.d.ts +522 -0
- package/package.json +1 -1
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.identityMoveStateSchema = exports.identityMoveReceiptRequestSchema = exports.identityMoveSealRequestSchema = exports.identityMoveJoinRequestSchema = exports.identityMoveCreateResponseSchema = exports.identityMoveCreateRequestSchema = exports.IDENTITY_MOVE_QR_PREFIX = exports.IDENTITY_MOVE_STATUSES = exports.identityMoveEphemeralKeySchema = exports.identityMoveIdSchema = exports.IDENTITY_MOVE_TTL_MS = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* Identity move contract — take a web identity INTO Commons (a MOVE, not a copy).
|
|
6
|
+
*
|
|
7
|
+
* Design: `docs/superpowers/specs/2026-09-15-one-identity-two-carriers-design.md` §5.
|
|
8
|
+
*
|
|
9
|
+
* Flow (the web — the OLD carrier — shows the QR; Commons — the NEW carrier —
|
|
10
|
+
* scans it):
|
|
11
|
+
* 1. `id.oxy.so` generates an ephemeral secp256k1 pair and calls
|
|
12
|
+
* `POST /identity/move { initiatorEphemeralPublicKey }` (bearer) →
|
|
13
|
+
* `{ moveId, expiresAt }`. The QR carries `moveId` only.
|
|
14
|
+
* 2. Commons scans, generates its own ephemeral pair, and calls
|
|
15
|
+
* `POST /identity/move/:moveId/join { responderEphemeralPublicKey }` (no
|
|
16
|
+
* bearer — Commons has no identity yet).
|
|
17
|
+
* 3. Both sides derive the same 6-digit SAS from the move id and BOTH ephemeral
|
|
18
|
+
* keys and show it. The person confirms on the web that they match. A relay
|
|
19
|
+
* that substituted either key produces two different codes.
|
|
20
|
+
* 4. The web seals the BIP-39 entropy under
|
|
21
|
+
* `HKDF(ECDH(initiatorEph, responderEph), moveId, 'oxy-identity-move-v1')` and
|
|
22
|
+
* calls `POST /identity/move/:moveId/seal` (bearer + identity-key proof).
|
|
23
|
+
* 5. Commons decrypts, imports the identity, and posts a RECEIPT: a signature by
|
|
24
|
+
* the identity key over `{ action:'identity_move_received', moveId, timestamp }`
|
|
25
|
+
* (`POST /identity/move/:moveId/receipt`). The server checks it against the
|
|
26
|
+
* account's key; the WEB verifies it again locally before destroying its copy,
|
|
27
|
+
* so not even the server can fake a completed move.
|
|
28
|
+
*
|
|
29
|
+
* The server holds two ephemeral public keys, an opaque ciphertext, and a
|
|
30
|
+
* receipt. It never holds anything that decrypts the ciphertext.
|
|
31
|
+
*
|
|
32
|
+
* Platform-agnostic — zod only, ESM-safe (no `require()`).
|
|
33
|
+
*/
|
|
34
|
+
const zod_1 = require("zod");
|
|
35
|
+
/** A move lives this long: one interactive handoff. */
|
|
36
|
+
exports.IDENTITY_MOVE_TTL_MS = 5 * 60 * 1000;
|
|
37
|
+
/** 128-bit move id, lowercase hex. */
|
|
38
|
+
exports.identityMoveIdSchema = zod_1.z
|
|
39
|
+
.string()
|
|
40
|
+
.trim()
|
|
41
|
+
.regex(/^[0-9a-f]{32}$/, 'moveId must be 32 lowercase hex characters');
|
|
42
|
+
/** An ephemeral secp256k1 public key, uncompressed lowercase hex. */
|
|
43
|
+
exports.identityMoveEphemeralKeySchema = zod_1.z
|
|
44
|
+
.string()
|
|
45
|
+
.trim()
|
|
46
|
+
.regex(/^04[0-9a-f]{128}$/, 'ephemeral public key must be uncompressed, lowercase hex');
|
|
47
|
+
exports.IDENTITY_MOVE_STATUSES = ['pending', 'joined', 'sealed', 'completed', 'cancelled', 'expired'];
|
|
48
|
+
/** The QR payload Commons scans. Carries the move id only. */
|
|
49
|
+
exports.IDENTITY_MOVE_QR_PREFIX = 'oxycommons://move?id=';
|
|
50
|
+
exports.identityMoveCreateRequestSchema = zod_1.z.object({
|
|
51
|
+
initiatorEphemeralPublicKey: exports.identityMoveEphemeralKeySchema,
|
|
52
|
+
});
|
|
53
|
+
exports.identityMoveCreateResponseSchema = zod_1.z.object({
|
|
54
|
+
moveId: exports.identityMoveIdSchema,
|
|
55
|
+
expiresAt: zod_1.z.string().datetime(),
|
|
56
|
+
});
|
|
57
|
+
exports.identityMoveJoinRequestSchema = zod_1.z.object({
|
|
58
|
+
responderEphemeralPublicKey: exports.identityMoveEphemeralKeySchema,
|
|
59
|
+
});
|
|
60
|
+
exports.identityMoveSealRequestSchema = zod_1.z.object({
|
|
61
|
+
/** 24-byte XChaCha20-Poly1305 nonce, hex. */
|
|
62
|
+
nonce: zod_1.z.string().trim().regex(/^[0-9a-f]{48}$/, 'nonce must be 48 lowercase hex characters'),
|
|
63
|
+
/** The 16-byte entropy, tag appended (32 bytes), hex. */
|
|
64
|
+
ciphertext: zod_1.z.string().trim().regex(/^[0-9a-f]{64}$/, 'ciphertext must be 64 lowercase hex characters'),
|
|
65
|
+
/** Identity-key proof over `{ action:'identity_move_seal', moveId, timestamp }`. */
|
|
66
|
+
signature: zod_1.z.string().trim().min(1).max(512),
|
|
67
|
+
timestamp: zod_1.z.number().int().positive(),
|
|
68
|
+
});
|
|
69
|
+
exports.identityMoveReceiptRequestSchema = zod_1.z.object({
|
|
70
|
+
/** Identity-key signature over `{ action:'identity_move_received', moveId, timestamp }`. */
|
|
71
|
+
signature: zod_1.z.string().trim().min(1).max(512),
|
|
72
|
+
timestamp: zod_1.z.number().int().positive(),
|
|
73
|
+
});
|
|
74
|
+
exports.identityMoveStateSchema = zod_1.z.object({
|
|
75
|
+
moveId: exports.identityMoveIdSchema,
|
|
76
|
+
status: zod_1.z.enum(exports.IDENTITY_MOVE_STATUSES),
|
|
77
|
+
publicKey: zod_1.z.string().regex(/^04[0-9a-f]{128}$/),
|
|
78
|
+
initiatorEphemeralPublicKey: exports.identityMoveEphemeralKeySchema,
|
|
79
|
+
responderEphemeralPublicKey: exports.identityMoveEphemeralKeySchema.nullable(),
|
|
80
|
+
nonce: zod_1.z.string().nullable(),
|
|
81
|
+
ciphertext: zod_1.z.string().nullable(),
|
|
82
|
+
receiptSignature: zod_1.z.string().nullable(),
|
|
83
|
+
receiptTimestamp: zod_1.z.number().int().nullable(),
|
|
84
|
+
expiresAt: zod_1.z.string().datetime(),
|
|
85
|
+
});
|
package/dist/cjs/index.js
CHANGED
|
@@ -25,16 +25,17 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
25
25
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
26
26
|
};
|
|
27
27
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
28
|
-
exports.
|
|
29
|
-
exports.
|
|
30
|
-
exports.
|
|
31
|
-
exports.
|
|
32
|
-
exports.
|
|
33
|
-
exports.
|
|
34
|
-
exports.
|
|
35
|
-
exports.
|
|
36
|
-
exports.
|
|
37
|
-
exports.
|
|
28
|
+
exports.OXY_PUBLISHED_USER_CHANGE_REASONS = exports.OXY_USER_CHANGE_REASONS = exports.OXY_USER_INVALIDATION_CHANNEL = exports.inboxEmailPushDataSchema = exports.INBOX_EMAIL_PUSH_TYPE = exports.INBOX_EMAIL_PUSH_CHANNEL = exports.IDENTITY_APPROVAL_PUSH_CHANNEL = exports.commonsDenyReasonSchema = exports.COMMONS_DENY_REASONS = exports.sessionStatusSchema = exports.publicApplicationSchema = exports.applicationTypeSchema = exports.safeParseContract = exports.resolveUserId = exports.deviceLinkedSessionsResponseSchema = exports.deviceLinkedSessionSchema = exports.currentUserResponseSchema = exports.userProfileUpdateSchema = exports.userResponseSchema = exports.dateOfBirthSchema = exports.themePreferenceSchema = exports.userRelationshipSchema = exports.userNameSchema = exports.BOT_USERNAME_INVALID_MESSAGE = exports.USERNAME_INVALID_MESSAGE = exports.USERNAME_MAX_LENGTH = exports.USERNAME_MIN_LENGTH = exports.applyBotUsernameSuffix = exports.stripDisallowedUsernameCharacters = exports.isValidUsername = exports.usernameSchemaForAccountKind = exports.usernameSchema = exports.createAccountRequestSchema = exports.SELECTABLE_ACCOUNT_CATEGORY_IDS = exports.RETIRED_ACCOUNT_CATEGORY_IDS = exports.newlyAddedRetiredCategories = exports.MAX_ACCOUNT_CATEGORIES = exports.kindAcceptsAccountCategories = exports.isSelectableAccountCategoryId = exports.accountCategoryIdSchema = exports.accountCategoriesSchema = exports.ACCOUNT_CATEGORY_KINDS = exports.ACCOUNT_CATEGORY_IDS = exports.isOperatorSwitchTargetKind = exports.isDelegatedActAsEligibleKind = exports.isAccountKind = exports.childAccountKindSchema = exports.CHILD_ACCOUNT_KINDS = exports.accountKindSchema = exports.ACCOUNT_KINDS = void 0;
|
|
29
|
+
exports.verifiableCredentialResponseSchema = exports.credentialRecordSchema = exports.vouchResultSchema = exports.personhoodStatusResultSchema = exports.personhoodBreakdownSchema = exports.personhoodVouchRecordSchema = exports.validationVoteResultSchema = exports.validationRequestSummarySchema = exports.validationOpenResultSchema = exports.validationOpenRequestSchema = exports.validationVerdictRecordSchema = exports.realLifeAttestationResultSchema = exports.realLifeAttestationRecordSchema = exports.signedPublicCardSchema = exports.publicCardSchema = exports.logPageResponseSchema = exports.chainHeadResponseSchema = exports.oxySignedRecordTypeSchema = exports.exportBundleSchema = exports.exportFinancialSectionSchema = exports.exportUsageReservationSchema = exports.exportLedgerEntrySchema = exports.exportUsageReceiptSchema = exports.exportAttestationSchema = exports.authMethodsResponseSchema = exports.authMethodEntrySchema = exports.domainVerificationInstructionsSchema = exports.resourceDomainOwnershipResponseSchema = exports.resourceDomainOwnershipRequestSchema = exports.domainVerificationRequestSchema = exports.verifiedDomainSchema = exports.signedRecordEnvelopeSchema = exports.didDocumentSchema = exports.didServiceSchema = exports.verificationMethodSchema = exports.appAffinityEventsIngestSchema = exports.appAffinityEventSchema = exports.appAffinityEventTypeSchema = exports.appUserSignalIngestSchema = exports.appInterestInputSchema = exports.appEndorsementInputSchema = exports.recommendationResponseSchema = exports.recommendationItemSchema = exports.recommendationCountSchema = exports.recommendationRequestSchema = exports.recommendationSignalWeightsSchema = exports.recommendationBoostSchema = exports.recommendationExcludeTypeSchema = exports.oxyUserInvalidationEventSchema = exports.isPublishedOxyUserChangeReason = void 0;
|
|
30
|
+
exports.moderationAttributionSchema = exports.moderationFindingScopeSchema = exports.moderationSeveritySchema = exports.APPLICATION_MODERATION_STANDINGS = exports.IDENTITY_BINDING_STATUSES = exports.IDENTITY_BINDING_TYPES = exports.PERSONHOOD_STATUSES = exports.CONTRIBUTION_TIERS = exports.CONDUCT_STANDINGS = exports.CONDUCT_STRIKE_STATUSES = exports.MODERATION_EFFECT_SKIP_REASONS = exports.MODERATION_EFFECT_STATUSES = exports.MODERATION_EFFECT_TYPES = exports.MODERATION_DECISION_STATUSES = exports.MODERATION_ATTRIBUTIONS = exports.MODERATION_FINDING_SCOPES = exports.MODERATION_SEVERITIES = exports.isFullReputationBalance = exports.reverseReputationTransactionSchema = exports.upsertReputationRuleSchema = exports.resolveReputationDisputeSchema = exports.createReputationDisputeSchema = exports.awardReputationSchema = exports.reverseReputationTransactionResultSchema = exports.reputationInfluenceResultSchema = exports.reputationLeaderboardEntrySchema = exports.reputationLeaderboardUserSchema = exports.reputationRuleSchema = exports.reputationDisputeSchema = exports.reputationBalanceSchema = exports.reputationBalanceSummarySchema = exports.reputationReliabilitySchema = exports.reputationInfluenceSchema = exports.reputationBalanceBreakdownSchema = exports.reputationTransactionSchema = exports.reputationInfluenceContextSchema = exports.reputationDisputeStatusSchema = exports.reputationTargetEntityTypeSchema = exports.trustTierSchema = exports.reputationTransactionStatusSchema = exports.reputationCategorySchema = exports.REPUTATION_INFLUENCE_CONTEXTS = exports.REPUTATION_DISPUTE_STATUSES = exports.REPUTATION_TARGET_ENTITY_TYPES = exports.TRUST_TIERS = exports.REPUTATION_TRANSACTION_STATUSES = exports.REPUTATION_CATEGORIES = exports.credentialVerifyResultSchema = exports.credentialListResultSchema = exports.credentialIssueResultSchema = void 0;
|
|
31
|
+
exports.oauthConsentDecisionSchema = exports.deviceDirectorySyncSchema = exports.deviceActivateResponseSchema = exports.deviceActivateRequestSchema = exports.deviceDirectorySchema = exports.devicePrincipalSchema = exports.deviceAccountContextSchema = exports.deviceDirectoryProfileSchema = exports.deviceContextRelationshipSchema = exports.sessionAccountsChangedEventSchema = exports.sessionAccountsChangedReasonSchema = exports.SESSION_ACCOUNTS_CHANGED_EVENT = exports.deviceBackgroundTokenResponseSchema = exports.deviceBackgroundTokenRequestSchema = exports.deviceBackgroundCredentialResponseSchema = exports.deviceTokenMintResponseSchema = exports.deviceTokenMintRequestSchema = exports.deviceSessionSyncSchema = exports.activeTokenSchema = exports.deviceSessionStateSchema = exports.sessionAccountSchema = exports.applicationModerationTrustSchema = exports.reputationContextualInfluenceSchema = exports.reputationReviewingSchema = exports.reputationReportingSchema = exports.reputationConductSchema = exports.reputationContributionSchema = exports.reputationPersonhoodSchema = exports.identityBindingSchema = exports.registerIdentityBindingSchema = exports.reverseModerationEffectResultSchema = exports.applyModerationDecisionResultSchema = exports.moderationEffectSchema = exports.reverseModerationEffectSchema = exports.finalizeModerationDecisionSchema = exports.moderationDecisionEventSchema = exports.moderationPolicyVersionsSchema = exports.moderationDecisionEventSubjectSchema = exports.moderationFindingSchema = exports.applicationModerationStandingSchema = exports.identityBindingStatusSchema = exports.identityBindingTypeSchema = exports.personhoodStatusSchema = exports.contributionTierSchema = exports.conductStandingSchema = exports.conductStrikeStatusSchema = exports.moderationEffectSkipReasonSchema = exports.moderationEffectStatusSchema = exports.moderationEffectTypeSchema = exports.moderationDecisionStatusSchema = void 0;
|
|
32
|
+
exports.updatePlatformSchema = exports.identityMoveStateSchema = exports.identityMoveReceiptRequestSchema = exports.identityMoveSealRequestSchema = exports.identityMoveJoinRequestSchema = exports.identityMoveCreateResponseSchema = exports.identityMoveCreateRequestSchema = exports.identityMoveEphemeralKeySchema = exports.identityMoveIdSchema = exports.IDENTITY_MOVE_QR_PREFIX = exports.IDENTITY_MOVE_STATUSES = exports.IDENTITY_MOVE_TTL_MS = exports.webIdentityEnvelopeEstablishSchema = exports.webIdentityEnvelopePutSchema = exports.webIdentityEnvelopeProofSchema = exports.webIdentityEnvelopeResponseSchema = exports.webIdentityEnvelopeUploadSchema = exports.webIdentityEnvelopeSchema = exports.webIdentityWrapSchema = exports.webauthnCredentialIdSchema = exports.webIdentityPublicKeySchema = exports.WEB_IDENTITY_ENVELOPE_VERSION = exports.backupStatusResponseSchema = exports.backupUploadRequestSchema = exports.encryptedBackupEnvelopeSchema = exports.backupLookupIdSchema = exports.rotateKeyCompleteResponseSchema = exports.rotateKeyCompleteRequestSchema = exports.rotateKeyChallengeResponseSchema = exports.loginResultSchema = exports.hubAuthorizeResultSchema = exports.hubAuthorizeRequestSchema = exports.hubActivateRequestSchema = exports.hubClaimRequestSchema = exports.hubSessionSchema = exports.browserHubRevokeResponseSchema = exports.browserHubErrorSchema = exports.browserHubResolveResponseSchema = exports.browserHubHandleResponseSchema = exports.browserHubHandleRequestSchema = exports.browserHubHandleSchema = exports.BROWSER_HUB_HANDLE_TTL_MS = exports.BROWSER_HUB_COOKIE_ATTRIBUTES = exports.BROWSER_HUB_COOKIE_NAME = exports.mcpOAuthConsentResponseSchema = exports.mcpOAuthClientInfoResponseSchema = exports.mcpOAuthConsentContextSchema = exports.mcpOAuthWriteActionSchema = exports.mcpOAuthClientApplicationSchema = exports.oauthAuthorizeCodeResponseSchema = void 0;
|
|
33
|
+
exports.inferenceEnvironmentSchema = exports.idempotencyKeySchema = exports.generationIdSchema = exports.requestIdSchema = exports.oxyCredentialIdSchema = exports.oxyApplicationIdSchema = exports.delegatedUserIdSchema = exports.oxyAccountIdSchema = exports.INFERENCE_CONTRACT_VERSION = exports.transparencyCheckpointListSchema = exports.transparencyInclusionProofSchema = exports.transparencyCheckpointSchema = exports.transparencyAnchorSchema = exports.transparencyCheckpointSignatureSchema = exports.deviceTransferDenyResponseSchema = exports.deviceTransferApproveResponseSchema = exports.deviceTransferApproveRequestSchema = exports.deviceTransferInfoResponseSchema = exports.deviceTransferInitResponseSchema = exports.deviceTransferInitRequestSchema = exports.devicePairingStatusSchema = exports.webauthnLoginVerifyRequestSchema = exports.webauthnRegisterVerifyRequestSchema = exports.webauthnLoginOptionsRequestSchema = exports.webauthnRegisterOptionsRequestSchema = exports.updateRolloutPatchSchema = exports.promoteRequestSchema = exports.rollbackToEmbeddedRequestSchema = exports.rollbackRequestSchema = exports.updateListResponseSchema = exports.channelListResponseSchema = exports.channelSchema = exports.rollbackToEmbeddedEntrySchema = exports.createUpdateResponseSchema = exports.updateSchema = exports.createUpdateRequestSchema = exports.updateAssetRefSchema = exports.assetCompleteResponseSchema = exports.assetCompleteResultItemSchema = exports.assetCompleteRequestSchema = exports.assetInitResponseSchema = exports.assetUploadTicketSchema = exports.assetInitRequestSchema = exports.assetInitItemSchema = exports.rolloutPercentSchema = exports.runtimeVersionSchema = exports.channelNameSchema = exports.sha256HexSchema = exports.updateAssetStatusSchema = exports.updateStatusSchema = void 0;
|
|
34
|
+
exports.inferenceDataPolicySchema = exports.modelProvenanceSchema = exports.modelLicenseSchema = exports.modelCapabilitiesSchema = exports.inferenceModalitySchema = exports.priceSnapshotSchema = exports.priceVersionSchema = exports.priceVersionStatusSchema = exports.embeddingResponseSchema = exports.embeddingFailureSchema = exports.embeddingSuccessSchema = exports.embeddingUsageSchema = exports.embeddingVectorSchema = exports.inferenceErrorSchema = exports.providerErrorPassthroughSchema = exports.safeErrorTextSchema = exports.upstreamErrorCategorySchema = exports.inferenceErrorCodeSchema = exports.NON_RETRYABLE_INFERENCE_ERROR_CODES = exports.INFERENCE_ERROR_CODES = exports.inferenceAttributionSchema = exports.authenticatedPrincipalSchema = exports.billingPrincipalSchema = exports.inferenceScopeSchema = exports.INFERENCE_SCOPES = exports.unitPriceSchema = exports.usageQuantitySchema = exports.usageSourceSchema = exports.USAGE_SOURCES = exports.usageUnitSchema = exports.USAGE_UNITS = exports.moneySchema = exports.exactDecimalSchema = exports.INFERENCE_MONEY_SCALE = exports.currencyCodeSchema = exports.RESERVED_ALIA_PUBLISHER = exports.inferenceRegionSchema = exports.deploymentIdSchema = exports.inferenceProviderSlugSchema = exports.routingProfileSlugSchema = exports.routingProfileIdSchema = exports.modelReferenceSchema = exports.modelRevisionLabelSchema = exports.modelIdSchema = exports.modelSlugSchema = exports.publisherSlugSchema = exports.sha256DigestSchema = exports.inferenceHttpsUrlSchema = exports.inferenceDateSchema = exports.inferenceTimestampSchema = void 0;
|
|
35
|
+
exports.inferenceStreamUsageEventSchema = exports.inferenceStreamToolCallEventSchema = exports.inferenceStreamDeltaEventSchema = exports.inferenceStreamStartEventSchema = exports.inferenceRequestSchema = exports.clientRequestMetadataSchema = exports.responseFormatSchema = exports.toolChoiceSchema = exports.toolDefinitionSchema = exports.samplingParametersSchema = exports.inferenceInputSchema = exports.inferenceMessageSchema = exports.inferenceMessageRoleSchema = exports.inferenceToolCallSchema = exports.inferenceContentPartSchema = exports.inferenceContentSourceSchema = exports.modelDocumentationSchema = exports.modelReleaseIngestionResultSchema = exports.modelReleaseIngestionRequestSchema = exports.modelLineDeclarationSchema = exports.modelGpaiDocumentationSchema = exports.modelDownstreamDocumentationSchema = exports.SYSTEMIC_RISK_COMPUTE_THRESHOLD_FLOPS = exports.trainingComputeFlopsSchema = exports.modelSystemicRiskTierSchema = exports.modelDistributionMethodSchema = exports.aliaModelReleaseManifestSchema = exports.aliaReleaseSignatureSchema = exports.aliaReleaseArtifactSchema = exports.authorizedRouteSchema = exports.routingPolicyReferenceSchema = exports.routingPolicySchema = exports.routingFallbackPolicySchema = exports.routingPolicyScopeSchema = exports.routingTargetSchema = exports.modelCatalogueEntrySchema = exports.catalogueServingProviderSummarySchema = exports.cataloguePublisherSummarySchema = exports.routingProfileSchema = exports.routingProfileCandidateSchema = exports.modelDeploymentSchema = exports.inferenceProviderSchema = exports.modelRevisionSchema = exports.catalogueModelSchema = exports.modelPublisherSchema = exports.modelSafetyMetadataSchema = exports.modelEvaluationResultSchema = exports.modelDeprecationSchema = exports.commercialPermissionSchema = exports.availabilityScopeSchema = void 0;
|
|
36
|
+
exports.BILLING_INVOICE_STATUSES = exports.accountBillingStateSchema = exports.billingProfileSchema = exports.autoRechargeSchema = exports.billingProfileStatusSchema = exports.BILLING_PROFILE_STATUSES = exports.billingModeSchema = exports.BILLING_MODES = exports.providerConnectionSchema = exports.providerConnectionStatusSchema = exports.providerConnectionValidationSchema = exports.providerCredentialCustodyStateSchema = exports.providerCredentialValidationDeploymentSchema = exports.providerCredentialValidationOperationSchema = exports.kaanaCredentialValidationOutcomeSchema = exports.kaanaCredentialValidationFailureCodeSchema = exports.kaanaCredentialValidationOutcomeStateSchema = exports.kaanaCredentialValidationTaskSchema = exports.kaanaCredentialOutcomeSchema = exports.kaanaCredentialConflictOutcomeSchema = exports.kaanaCredentialAppliedOutcomeSchema = exports.kaanaCredentialOutcomeRequestSchema = exports.kaanaCredentialRevokeOutcomeRequestSchema = exports.kaanaCredentialRotateOutcomeRequestSchema = exports.kaanaCredentialCreateOutcomeRequestSchema = exports.kaanaCredentialMutationSchema = exports.kaanaCredentialRevokeMutationSchema = exports.kaanaCredentialRotateMutationSchema = exports.kaanaCredentialCreateMutationSchema = exports.kaanaCredentialIdentitySchema = exports.kaanaCredentialOperationActionSchema = exports.kaanaCredentialOperationIdSchema = exports.kaanaCredentialHandleSchema = exports.providerConnectionScopeSchema = exports.usageRefundSchema = exports.usageRefundReasonSchema = exports.usageRefundSubjectSchema = exports.usageReceiptSchema = exports.normalizedUsageReportSchema = exports.inferenceRequestOutcomeSchema = exports.usageReservationSchema = exports.usageReservationStatusSchema = exports.usageReservationRequestSchema = exports.inferenceStreamEventSchema = exports.inferenceStreamDoneEventSchema = exports.inferenceFinishReasonSchema = exports.inferenceStreamErrorEventSchema = exports.inferenceStreamRouteSwitchEventSchema = exports.inferenceRouteSwitchReasonSchema = exports.inferenceRouteSwitchDetailSchema = void 0;
|
|
37
|
+
exports.catalogEventSchema = exports.catalogToolSchema = exports.auditEventSchema = exports.auditResultSchema = exports.policyDecisionSchema = exports.capabilityTicketClaimsSchema = exports.automationDefinitionSchema = exports.automationDataFlowSchema = exports.automationActorSelectionSchema = exports.automationTriggerSchema = exports.delegationGrantSchema = exports.capabilityCoordinatorSchema = exports.executionAuthorizationRefSchema = exports.capabilityCatalogBindingSchema = exports.grantLimitSchema = exports.toolGrantOverrideSchema = exports.resourceRefSchema = exports.actorRefSchema = exports.capabilityPackageSchema = exports.autonomyLevelSchema = exports.CAPABILITY_PACKAGES = exports.AUTONOMY_LEVELS = exports.productEntitlementSchema = exports.costCenterSpendSchema = exports.costCenterSchema = exports.costCenterStatusSchema = exports.COST_CENTER_STATUSES = exports.payAsYouGoEntitlementSchema = exports.productPlanSchema = exports.planAllowanceSchema = exports.LIVE_PRODUCT_PLAN_STATUSES = exports.productPlanStatusSchema = exports.PRODUCT_PLAN_STATUSES = exports.reconciliationReportSchema = exports.reconciliationRunSchema = exports.reconciliationDiscrepancySchema = exports.reconciliationRunStatusSchema = exports.RECONCILIATION_RUN_STATUSES = exports.reconciliationDiscrepancyKindSchema = exports.RECONCILIATION_DISCREPANCY_KINDS = exports.autoRechargeAttemptSchema = exports.autoRechargeStatusSchema = exports.AUTO_RECHARGE_STATUSES = exports.externalPaymentSchema = exports.externalPaymentKindSchema = exports.EXTERNAL_PAYMENT_KINDS = exports.externalPaymentProviderSchema = exports.EXTERNAL_PAYMENT_PROVIDERS = exports.billingInvoiceSchema = exports.billingInvoiceStatusSchema = void 0;
|
|
38
|
+
exports.inboxInferenceStreamEventSchema = exports.inboxThreadSummaryResponseSchema = exports.inboxSmartRepliesResponseSchema = exports.inboxNaturalSearchResponseSchema = exports.inboxInferenceTextResponseSchema = exports.inboxMessageInferenceParamsSchema = exports.inboxNaturalSearchRequestSchema = exports.inboxDailyBriefRequestSchema = exports.inboxComposeRequestSchema = exports.emailAgentContextSchema = exports.emailContextMessageSchema = exports.emailContextMailboxSchema = exports.emailContextAddressSchema = exports.normalizedAppEventSchema = exports.catalogRegistrationSchema = exports.appCapabilityCatalogSchema = void 0;
|
|
38
39
|
var accountGraph_1 = require("./accountGraph");
|
|
39
40
|
Object.defineProperty(exports, "ACCOUNT_KINDS", { enumerable: true, get: function () { return accountGraph_1.ACCOUNT_KINDS; } });
|
|
40
41
|
Object.defineProperty(exports, "accountKindSchema", { enumerable: true, get: function () { return accountGraph_1.accountKindSchema; } });
|
|
@@ -69,6 +70,7 @@ var userResponse_1 = require("./userResponse");
|
|
|
69
70
|
Object.defineProperty(exports, "userNameSchema", { enumerable: true, get: function () { return userResponse_1.userNameSchema; } });
|
|
70
71
|
Object.defineProperty(exports, "userRelationshipSchema", { enumerable: true, get: function () { return userResponse_1.userRelationshipSchema; } });
|
|
71
72
|
Object.defineProperty(exports, "themePreferenceSchema", { enumerable: true, get: function () { return userResponse_1.themePreferenceSchema; } });
|
|
73
|
+
Object.defineProperty(exports, "dateOfBirthSchema", { enumerable: true, get: function () { return userResponse_1.dateOfBirthSchema; } });
|
|
72
74
|
Object.defineProperty(exports, "userResponseSchema", { enumerable: true, get: function () { return userResponse_1.userResponseSchema; } });
|
|
73
75
|
Object.defineProperty(exports, "userProfileUpdateSchema", { enumerable: true, get: function () { return userResponse_1.userProfileUpdateSchema; } });
|
|
74
76
|
Object.defineProperty(exports, "currentUserResponseSchema", { enumerable: true, get: function () { return userResponse_1.currentUserResponseSchema; } });
|
|
@@ -310,6 +312,31 @@ Object.defineProperty(exports, "backupLookupIdSchema", { enumerable: true, get:
|
|
|
310
312
|
Object.defineProperty(exports, "encryptedBackupEnvelopeSchema", { enumerable: true, get: function () { return keyRecovery_1.encryptedBackupEnvelopeSchema; } });
|
|
311
313
|
Object.defineProperty(exports, "backupUploadRequestSchema", { enumerable: true, get: function () { return keyRecovery_1.backupUploadRequestSchema; } });
|
|
312
314
|
Object.defineProperty(exports, "backupStatusResponseSchema", { enumerable: true, get: function () { return keyRecovery_1.backupStatusResponseSchema; } });
|
|
315
|
+
var webIdentityCarrier_1 = require("./webIdentityCarrier");
|
|
316
|
+
// Schemas — web identity carrier (one identity, two carriers)
|
|
317
|
+
Object.defineProperty(exports, "WEB_IDENTITY_ENVELOPE_VERSION", { enumerable: true, get: function () { return webIdentityCarrier_1.WEB_IDENTITY_ENVELOPE_VERSION; } });
|
|
318
|
+
Object.defineProperty(exports, "webIdentityPublicKeySchema", { enumerable: true, get: function () { return webIdentityCarrier_1.webIdentityPublicKeySchema; } });
|
|
319
|
+
Object.defineProperty(exports, "webauthnCredentialIdSchema", { enumerable: true, get: function () { return webIdentityCarrier_1.webauthnCredentialIdSchema; } });
|
|
320
|
+
Object.defineProperty(exports, "webIdentityWrapSchema", { enumerable: true, get: function () { return webIdentityCarrier_1.webIdentityWrapSchema; } });
|
|
321
|
+
Object.defineProperty(exports, "webIdentityEnvelopeSchema", { enumerable: true, get: function () { return webIdentityCarrier_1.webIdentityEnvelopeSchema; } });
|
|
322
|
+
Object.defineProperty(exports, "webIdentityEnvelopeUploadSchema", { enumerable: true, get: function () { return webIdentityCarrier_1.webIdentityEnvelopeUploadSchema; } });
|
|
323
|
+
Object.defineProperty(exports, "webIdentityEnvelopeResponseSchema", { enumerable: true, get: function () { return webIdentityCarrier_1.webIdentityEnvelopeResponseSchema; } });
|
|
324
|
+
Object.defineProperty(exports, "webIdentityEnvelopeProofSchema", { enumerable: true, get: function () { return webIdentityCarrier_1.webIdentityEnvelopeProofSchema; } });
|
|
325
|
+
Object.defineProperty(exports, "webIdentityEnvelopePutSchema", { enumerable: true, get: function () { return webIdentityCarrier_1.webIdentityEnvelopePutSchema; } });
|
|
326
|
+
Object.defineProperty(exports, "webIdentityEnvelopeEstablishSchema", { enumerable: true, get: function () { return webIdentityCarrier_1.webIdentityEnvelopeEstablishSchema; } });
|
|
327
|
+
var identityMove_1 = require("./identityMove");
|
|
328
|
+
// Schemas — moving a web identity into Commons
|
|
329
|
+
Object.defineProperty(exports, "IDENTITY_MOVE_TTL_MS", { enumerable: true, get: function () { return identityMove_1.IDENTITY_MOVE_TTL_MS; } });
|
|
330
|
+
Object.defineProperty(exports, "IDENTITY_MOVE_STATUSES", { enumerable: true, get: function () { return identityMove_1.IDENTITY_MOVE_STATUSES; } });
|
|
331
|
+
Object.defineProperty(exports, "IDENTITY_MOVE_QR_PREFIX", { enumerable: true, get: function () { return identityMove_1.IDENTITY_MOVE_QR_PREFIX; } });
|
|
332
|
+
Object.defineProperty(exports, "identityMoveIdSchema", { enumerable: true, get: function () { return identityMove_1.identityMoveIdSchema; } });
|
|
333
|
+
Object.defineProperty(exports, "identityMoveEphemeralKeySchema", { enumerable: true, get: function () { return identityMove_1.identityMoveEphemeralKeySchema; } });
|
|
334
|
+
Object.defineProperty(exports, "identityMoveCreateRequestSchema", { enumerable: true, get: function () { return identityMove_1.identityMoveCreateRequestSchema; } });
|
|
335
|
+
Object.defineProperty(exports, "identityMoveCreateResponseSchema", { enumerable: true, get: function () { return identityMove_1.identityMoveCreateResponseSchema; } });
|
|
336
|
+
Object.defineProperty(exports, "identityMoveJoinRequestSchema", { enumerable: true, get: function () { return identityMove_1.identityMoveJoinRequestSchema; } });
|
|
337
|
+
Object.defineProperty(exports, "identityMoveSealRequestSchema", { enumerable: true, get: function () { return identityMove_1.identityMoveSealRequestSchema; } });
|
|
338
|
+
Object.defineProperty(exports, "identityMoveReceiptRequestSchema", { enumerable: true, get: function () { return identityMove_1.identityMoveReceiptRequestSchema; } });
|
|
339
|
+
Object.defineProperty(exports, "identityMoveStateSchema", { enumerable: true, get: function () { return identityMove_1.identityMoveStateSchema; } });
|
|
313
340
|
var updates_1 = require("./updates");
|
|
314
341
|
// Shared primitives
|
|
315
342
|
Object.defineProperty(exports, "updatePlatformSchema", { enumerable: true, get: function () { return updates_1.updatePlatformSchema; } });
|
|
@@ -137,12 +137,13 @@ exports.inferenceDataPolicySchema = zod_1.z
|
|
|
137
137
|
}
|
|
138
138
|
});
|
|
139
139
|
/**
|
|
140
|
-
* Who a route may be served to. Availability
|
|
141
|
-
* permission to resell the same provider/model publicly, which is why
|
|
142
|
-
* an explicit scope on the route rather than a boolean derived from
|
|
140
|
+
* Who a route may be served to. Availability to an official Oxy product never
|
|
141
|
+
* implies permission to resell the same provider/model publicly, which is why
|
|
142
|
+
* this is an explicit scope on the route rather than a boolean derived from
|
|
143
|
+
* "it works".
|
|
143
144
|
*/
|
|
144
145
|
exports.availabilityScopeSchema = zod_1.z.enum([
|
|
145
|
-
'
|
|
146
|
+
'platform_internal',
|
|
146
147
|
'public_payg',
|
|
147
148
|
'enterprise',
|
|
148
149
|
'byok_only',
|
|
@@ -335,7 +336,7 @@ exports.inferenceProviderSchema = zod_1.z.object({
|
|
|
335
336
|
exports.modelDeploymentSchema = zod_1.z
|
|
336
337
|
.object({
|
|
337
338
|
/** See `version.ts`: exchanged with the data plane on its own. */
|
|
338
|
-
schemaVersion: zod_1.z.literal(
|
|
339
|
+
schemaVersion: zod_1.z.literal(2),
|
|
339
340
|
deploymentId: identifiers_1.deploymentIdSchema,
|
|
340
341
|
provider: identifiers_1.inferenceProviderSlugSchema,
|
|
341
342
|
/** Always revision-pinned: a deployment serves specific weights. */
|
|
@@ -458,7 +459,7 @@ exports.catalogueServingProviderSummarySchema = zod_1.z
|
|
|
458
459
|
*/
|
|
459
460
|
exports.modelCatalogueEntrySchema = zod_1.z.object({
|
|
460
461
|
/** See `version.ts`: this is the public catalogue response shape. */
|
|
461
|
-
schemaVersion: zod_1.z.literal(
|
|
462
|
+
schemaVersion: zod_1.z.literal(3),
|
|
462
463
|
modelId: identifiers_1.modelIdSchema,
|
|
463
464
|
publisher: exports.cataloguePublisherSummarySchema,
|
|
464
465
|
displayName: zod_1.z.string().min(1).max(200),
|
|
@@ -102,4 +102,4 @@ exports.INFERENCE_CONTRACT_VERSION = void 0;
|
|
|
102
102
|
* change to, say, the catalogue reject every in-flight inference request; the
|
|
103
103
|
* per-shape `schemaVersion` is what a message is validated against.
|
|
104
104
|
*/
|
|
105
|
-
exports.INFERENCE_CONTRACT_VERSION = '
|
|
105
|
+
exports.INFERENCE_CONTRACT_VERSION = '3.0.0';
|
package/dist/cjs/userResponse.js
CHANGED
|
@@ -30,7 +30,7 @@
|
|
|
30
30
|
* `require()`).
|
|
31
31
|
*/
|
|
32
32
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
33
|
-
exports.deviceLinkedSessionsResponseSchema = exports.deviceLinkedSessionSchema = exports.currentUserResponseSchema = exports.userProfileUpdateSchema = exports.userResponseSchema = exports.themePreferenceSchema = exports.userRelationshipSchema = exports.userNameSchema = void 0;
|
|
33
|
+
exports.deviceLinkedSessionsResponseSchema = exports.deviceLinkedSessionSchema = exports.currentUserResponseSchema = exports.userProfileUpdateSchema = exports.userResponseSchema = exports.dateOfBirthSchema = exports.themePreferenceSchema = exports.userRelationshipSchema = exports.userNameSchema = void 0;
|
|
34
34
|
exports.resolveUserId = resolveUserId;
|
|
35
35
|
exports.safeParseContract = safeParseContract;
|
|
36
36
|
const zod_1 = require("zod");
|
|
@@ -52,6 +52,60 @@ exports.themePreferenceSchema = zod_1.z.object({
|
|
|
52
52
|
mode: zod_1.z.enum(['light', 'dark', 'system']),
|
|
53
53
|
colorPreset: zod_1.z.string(),
|
|
54
54
|
});
|
|
55
|
+
/**
|
|
56
|
+
* The earliest calendar year `dateOfBirthSchema` accepts.
|
|
57
|
+
*
|
|
58
|
+
* Not a real biological bound — it exists to catch an obviously-transposed
|
|
59
|
+
* year (`1027` for `2027`, a stray OCR/typo digit) with a clear message
|
|
60
|
+
* instead of the value quietly becoming a 150-year-old account. 1900 is
|
|
61
|
+
* generous enough that no living person's real birthdate is rejected by it.
|
|
62
|
+
*/
|
|
63
|
+
const MIN_BIRTH_YEAR = 1900;
|
|
64
|
+
/**
|
|
65
|
+
* `true` when `year`/`month`/`day` name a date that actually exists on the
|
|
66
|
+
* Gregorian calendar — the check `z.string().regex(...)` alone cannot make,
|
|
67
|
+
* since the regex only constrains digit COUNT and would pass `2024-02-30`.
|
|
68
|
+
*/
|
|
69
|
+
function isRealCalendarDate(year, month, day) {
|
|
70
|
+
const isLeapYear = (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0;
|
|
71
|
+
const daysInMonth = [31, isLeapYear ? 29 : 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
|
|
72
|
+
return month >= 1 && month <= 12 && day >= 1 && day <= daysInMonth[month - 1];
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* A date of birth, `YYYY-MM-DD`, the sole structured representation this
|
|
76
|
+
* platform stores going forward (`users.date_of_birth` — see
|
|
77
|
+
* `packages/api/src/db/schema/users.ts`). `birthday` (below) stays as the
|
|
78
|
+
* legacy free-text field for backward compatibility with existing readers;
|
|
79
|
+
* this schema is what both the write path (`user.service.ts`) and the read
|
|
80
|
+
* path (nothing — a date of birth is owner-only, never echoed to another
|
|
81
|
+
* viewer) validate against.
|
|
82
|
+
*
|
|
83
|
+
* Three checks, in order, because a regex alone would accept a string-shaped
|
|
84
|
+
* lie:
|
|
85
|
+
* 1. Exactly `YYYY-MM-DD` — the wire format, nothing looser.
|
|
86
|
+
* 2. A real Gregorian date — rejects `2024-02-30`, a date the regex cannot see
|
|
87
|
+
* is impossible.
|
|
88
|
+
* 3. Bounded to a plausible human lifetime — not before {@link MIN_BIRTH_YEAR}
|
|
89
|
+
* and not after today (comparing the zero-padded ISO strings directly is
|
|
90
|
+
* a valid, simpler stand-in for a numeric comparison here, since two
|
|
91
|
+
* `YYYY-MM-DD` strings of equal length sort exactly the way their dates
|
|
92
|
+
* do). "Today" is UTC — see `computeIsAdult` in `user.service.ts` for why
|
|
93
|
+
* a date with no timezone of its own is evaluated in UTC rather than any
|
|
94
|
+
* particular caller's local zone.
|
|
95
|
+
*/
|
|
96
|
+
exports.dateOfBirthSchema = zod_1.z
|
|
97
|
+
.string()
|
|
98
|
+
.regex(/^\d{4}-\d{2}-\d{2}$/, 'dateOfBirth must be an ISO 8601 calendar date (YYYY-MM-DD)')
|
|
99
|
+
.refine((value) => {
|
|
100
|
+
const [year, month, day] = value.split('-').map(Number);
|
|
101
|
+
return isRealCalendarDate(year, month, day);
|
|
102
|
+
}, { message: 'dateOfBirth is not a real calendar date' })
|
|
103
|
+
.refine((value) => Number(value.slice(0, 4)) >= MIN_BIRTH_YEAR, {
|
|
104
|
+
message: `dateOfBirth must not be before ${MIN_BIRTH_YEAR}`,
|
|
105
|
+
})
|
|
106
|
+
.refine((value) => value <= new Date().toISOString().slice(0, 10), {
|
|
107
|
+
message: 'dateOfBirth must not be in the future',
|
|
108
|
+
});
|
|
55
109
|
/**
|
|
56
110
|
* The canonical user object emitted by `formatUserResponse`.
|
|
57
111
|
*
|
|
@@ -81,6 +135,26 @@ exports.userResponseSchema = zod_1.z
|
|
|
81
135
|
phone: zod_1.z.string().optional(),
|
|
82
136
|
address: zod_1.z.string().optional(),
|
|
83
137
|
birthday: zod_1.z.string().optional(),
|
|
138
|
+
/**
|
|
139
|
+
* Structured date of birth, `YYYY-MM-DD`. Present only on the
|
|
140
|
+
* account's OWN profile response (`GET /users/me`, `PUT /users/me`
|
|
141
|
+
* with `includePrivateFields`) — never on another account's profile,
|
|
142
|
+
* the same visibility `phone`/`address`/`birthday` already have. See
|
|
143
|
+
* {@link dateOfBirthSchema}.
|
|
144
|
+
*/
|
|
145
|
+
dateOfBirth: exports.dateOfBirthSchema.optional(),
|
|
146
|
+
/**
|
|
147
|
+
* Derived, non-PII signal: whether the account holder is at least 18
|
|
148
|
+
* (see `computeIsAdult` in `user.service.ts` for the exact threshold
|
|
149
|
+
* and the UTC-"today" choice). Computed fresh on every read — age
|
|
150
|
+
* changes daily, so this is never stored. `undefined` when
|
|
151
|
+
* `dateOfBirth` is unset ("unknown"), distinct from `false` ("known,
|
|
152
|
+
* not yet 18"). Rides the same owner-only visibility as
|
|
153
|
+
* `dateOfBirth`; a future pass may widen this specific field to
|
|
154
|
+
* other viewers without exposing the birthdate itself, but that is
|
|
155
|
+
* not decided here.
|
|
156
|
+
*/
|
|
157
|
+
isAdult: zod_1.z.boolean().optional(),
|
|
84
158
|
/** Avatar file id (string) or null. */
|
|
85
159
|
avatar: zod_1.z.string().nullable().optional(),
|
|
86
160
|
/** Named Bloom color preset (e.g. `"blue"`) or null. */
|
|
@@ -176,6 +250,13 @@ exports.userProfileUpdateSchema = zod_1.z
|
|
|
176
250
|
phone: zod_1.z.string().optional(),
|
|
177
251
|
address: zod_1.z.string().optional(),
|
|
178
252
|
birthday: zod_1.z.string().optional(),
|
|
253
|
+
/**
|
|
254
|
+
* Structured date of birth. `null` (or `''`, at the service layer)
|
|
255
|
+
* clears it. Independently settable from `birthday` — see
|
|
256
|
+
* `user.service.ts`'s `updateUserProfile` for why the two legacy and
|
|
257
|
+
* structured fields are not kept in sync with each other.
|
|
258
|
+
*/
|
|
259
|
+
dateOfBirth: exports.dateOfBirthSchema.nullable().optional(),
|
|
179
260
|
locations: zod_1.z.array(zod_1.z.unknown()).optional(),
|
|
180
261
|
links: zod_1.z.array(zod_1.z.string()).optional(),
|
|
181
262
|
linksMetadata: zod_1.z
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.webIdentityEnvelopeEstablishSchema = exports.webIdentityEnvelopePutSchema = exports.webIdentityEnvelopeProofSchema = exports.webIdentityEnvelopeResponseSchema = exports.webIdentityEnvelopeUploadSchema = exports.webIdentityEnvelopeSchema = exports.webIdentityWrapSchema = exports.webauthnCredentialIdSchema = exports.webIdentityPublicKeySchema = exports.WEB_IDENTITY_ENVELOPE_VERSION = void 0;
|
|
4
|
+
/**
|
|
5
|
+
* Web identity carrier contract — "one identity, two carriers".
|
|
6
|
+
*
|
|
7
|
+
* SINGLE SOURCE OF TRUTH for the sealed envelope that lets a browser carry an
|
|
8
|
+
* account's self-custody identity without Oxy ever holding it
|
|
9
|
+
* (`docs/superpowers/specs/2026-09-15-one-identity-two-carriers-design.md`).
|
|
10
|
+
*
|
|
11
|
+
* The identity is a BIP-39 mnemonic whose seed's first 32 bytes are the
|
|
12
|
+
* secp256k1 key — exactly the Commons derivation — so a web identity and a
|
|
13
|
+
* Commons identity are the same thing. On the web it travels as:
|
|
14
|
+
*
|
|
15
|
+
* entropy (16 bytes) ── XChaCha20-Poly1305 under a random DEK ──▶ sealedEntropy
|
|
16
|
+
* DEK ── XChaCha20-Poly1305 under KEK_i ──▶ wraps[i]
|
|
17
|
+
* KEK_i = HKDF(PRF output of passkey i)
|
|
18
|
+
*
|
|
19
|
+
* The server stores the envelope and can open NONE of it: the PRF output never
|
|
20
|
+
* leaves the user's authenticator, and the mnemonic is never uploaded. The AEAD
|
|
21
|
+
* associated data binds every ciphertext to the identity's public key (and each
|
|
22
|
+
* wrap to its credential), so a re-labelled or transplanted envelope fails to
|
|
23
|
+
* open instead of decrypting into the wrong identity.
|
|
24
|
+
*
|
|
25
|
+
* Every hex field is lowercase-or-uppercase hex. Platform-agnostic — zod only,
|
|
26
|
+
* ESM-safe (no `require()`).
|
|
27
|
+
*/
|
|
28
|
+
const zod_1 = require("zod");
|
|
29
|
+
/** The only envelope version. A scheme change is a new literal, never a mutation. */
|
|
30
|
+
exports.WEB_IDENTITY_ENVELOPE_VERSION = 1;
|
|
31
|
+
const hex = (bytes, label) => zod_1.z
|
|
32
|
+
.string()
|
|
33
|
+
.trim()
|
|
34
|
+
.regex(new RegExp(`^[0-9a-fA-F]{${bytes * 2}}$`), `${label} must be ${bytes * 2} hex characters`);
|
|
35
|
+
/**
|
|
36
|
+
* The identity's secp256k1 public key in Oxy's canonical form: uncompressed SEC1
|
|
37
|
+
* (`04` + 64 bytes), lowercase hex — what `KeyManager.derivePublicKey` produces
|
|
38
|
+
* and `users.public_key` stores.
|
|
39
|
+
*/
|
|
40
|
+
exports.webIdentityPublicKeySchema = zod_1.z
|
|
41
|
+
.string()
|
|
42
|
+
.trim()
|
|
43
|
+
.regex(/^04[0-9a-f]{128}$/, 'publicKey must be an uncompressed, lowercase secp256k1 key (130 hex characters)');
|
|
44
|
+
/** A WebAuthn credential id, base64url as the browser reports it. */
|
|
45
|
+
exports.webauthnCredentialIdSchema = zod_1.z
|
|
46
|
+
.string()
|
|
47
|
+
.trim()
|
|
48
|
+
.min(16)
|
|
49
|
+
.max(1024)
|
|
50
|
+
.regex(/^[A-Za-z0-9_-]+$/, 'credentialId must be base64url');
|
|
51
|
+
/** One passkey's wrap of the envelope's data key. */
|
|
52
|
+
exports.webIdentityWrapSchema = zod_1.z.object({
|
|
53
|
+
credentialId: exports.webauthnCredentialIdSchema,
|
|
54
|
+
/** 24-byte XChaCha20-Poly1305 nonce. */
|
|
55
|
+
nonce: hex(24, 'nonce'),
|
|
56
|
+
/** The 32-byte DEK sealed under this passkey's KEK, with the 16-byte tag appended (48 bytes). */
|
|
57
|
+
wrappedKey: hex(48, 'wrappedKey'),
|
|
58
|
+
createdAt: zod_1.z.string().datetime(),
|
|
59
|
+
});
|
|
60
|
+
/**
|
|
61
|
+
* The sealed identity as it is stored (server copy and local copy alike).
|
|
62
|
+
*
|
|
63
|
+
* `wraps` holds one entry per passkey able to open it; at least one, and a
|
|
64
|
+
* bounded number so an envelope cannot grow without limit.
|
|
65
|
+
*/
|
|
66
|
+
exports.webIdentityEnvelopeSchema = zod_1.z.object({
|
|
67
|
+
version: zod_1.z.literal(exports.WEB_IDENTITY_ENVELOPE_VERSION),
|
|
68
|
+
algorithm: zod_1.z.literal('xchacha20poly1305'),
|
|
69
|
+
publicKey: exports.webIdentityPublicKeySchema,
|
|
70
|
+
/** 24-byte nonce of the entropy seal. */
|
|
71
|
+
entropyNonce: hex(24, 'entropyNonce'),
|
|
72
|
+
/** The 16-byte BIP-39 entropy sealed under the DEK, tag appended (32 bytes). */
|
|
73
|
+
sealedEntropy: hex(32, 'sealedEntropy'),
|
|
74
|
+
wraps: zod_1.z.array(exports.webIdentityWrapSchema).min(1).max(10),
|
|
75
|
+
});
|
|
76
|
+
/**
|
|
77
|
+
* `PUT /identity/web-envelope` — store or replace the caller's envelope.
|
|
78
|
+
*
|
|
79
|
+
* Refused unless `envelope.publicKey` is the identity key already linked to the
|
|
80
|
+
* account: an envelope can only ever carry the account's own identity.
|
|
81
|
+
*/
|
|
82
|
+
exports.webIdentityEnvelopeUploadSchema = zod_1.z.object({
|
|
83
|
+
envelope: exports.webIdentityEnvelopeSchema,
|
|
84
|
+
});
|
|
85
|
+
/** `GET /identity/web-envelope` — the caller's envelope and its recovery-phrase state. */
|
|
86
|
+
exports.webIdentityEnvelopeResponseSchema = zod_1.z.object({
|
|
87
|
+
envelope: exports.webIdentityEnvelopeSchema.nullable(),
|
|
88
|
+
/**
|
|
89
|
+
* When the owner confirmed they wrote the recovery phrase down, or `null`.
|
|
90
|
+
* Until then the identity must not be unlocked on a second device, nor used
|
|
91
|
+
* for any operation that needs the key (design decision D2).
|
|
92
|
+
*/
|
|
93
|
+
phraseConfirmedAt: zod_1.z.string().datetime().nullable(),
|
|
94
|
+
updatedAt: zod_1.z.string().datetime().nullable(),
|
|
95
|
+
});
|
|
96
|
+
/**
|
|
97
|
+
* `POST /identity/web-envelope/phrase-confirmed` and
|
|
98
|
+
* `DELETE /identity/web-envelope` both prove control of the identity key, not
|
|
99
|
+
* just a bearer: a stolen session must not be able to mark a phrase as saved or
|
|
100
|
+
* destroy the web copy of someone's identity.
|
|
101
|
+
*
|
|
102
|
+
* The signed message is `JSON.stringify({ action, userId, timestamp })` — the
|
|
103
|
+
* same scheme as `link_identity`.
|
|
104
|
+
*/
|
|
105
|
+
exports.webIdentityEnvelopeProofSchema = zod_1.z.object({
|
|
106
|
+
signature: zod_1.z.string().trim().min(1).max(512),
|
|
107
|
+
timestamp: zod_1.z.number().int().positive(),
|
|
108
|
+
});
|
|
109
|
+
/** `PUT /identity/web-envelope` body: the envelope plus a `web_envelope_put` identity-key proof. */
|
|
110
|
+
exports.webIdentityEnvelopePutSchema = exports.webIdentityEnvelopeUploadSchema.extend(exports.webIdentityEnvelopeProofSchema.shape);
|
|
111
|
+
/**
|
|
112
|
+
* `POST /identity/web-envelope/establish` body — create an account's FIRST
|
|
113
|
+
* identity on the web: link the key and store its envelope in ONE transaction.
|
|
114
|
+
*
|
|
115
|
+
* Linking and storing as two calls would let a failure (or a closed tab) in
|
|
116
|
+
* between leave the account bound to a key that nothing carries — an identity
|
|
117
|
+
* lost at birth. `link` is a `link_identity` proof and the outer proof a
|
|
118
|
+
* `web_envelope_put` proof, both signed by the envelope's own key.
|
|
119
|
+
*/
|
|
120
|
+
exports.webIdentityEnvelopeEstablishSchema = exports.webIdentityEnvelopePutSchema.extend({
|
|
121
|
+
link: exports.webIdentityEnvelopeProofSchema,
|
|
122
|
+
});
|