@yielded/auth-persistence 0.1.0-beta.10
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 +27 -0
- package/dist/Adapter.d.mts +30 -0
- package/dist/Adapter.mjs +25 -0
- package/dist/index.d.mts +7 -0
- package/dist/index.mjs +7 -0
- package/dist/internal/PasswordPreparedPostconditions.d.mts +22 -0
- package/dist/internal/PasswordPreparedPostconditions.mjs +12 -0
- package/dist/internal/PasswordPreparedPostconditions.mjs.map +1 -0
- package/dist/internal/configuration.d.mts +174 -0
- package/dist/internal/configuration.mjs +7 -0
- package/dist/internal/configuration.mjs.map +1 -0
- package/dist/internal/email-kernel.d.mts +275 -0
- package/dist/internal/email-kernel.mjs +487 -0
- package/dist/internal/email-kernel.mjs.map +1 -0
- package/dist/internal/mapping-error.d.mts +10 -0
- package/dist/internal/mapping-error.mjs +30 -0
- package/dist/internal/mapping-error.mjs.map +1 -0
- package/dist/internal/models/common.d.mts +12 -0
- package/dist/internal/models/email-model.d.mts +353 -0
- package/dist/internal/models/email-model.mjs +21 -0
- package/dist/internal/models/email-model.mjs.map +1 -0
- package/dist/internal/models/passkey-model.d.mts +266 -0
- package/dist/internal/models/passkey-model.mjs +34 -0
- package/dist/internal/models/passkey-model.mjs.map +1 -0
- package/dist/internal/models/passkey-registration-ceremony-model.d.mts +49 -0
- package/dist/internal/models/passkey-registration-ceremony-model.mjs +18 -0
- package/dist/internal/models/passkey-registration-ceremony-model.mjs.map +1 -0
- package/dist/internal/models/passkey-write-model.d.mts +189 -0
- package/dist/internal/models/passkey-write-model.mjs +13 -0
- package/dist/internal/models/passkey-write-model.mjs.map +1 -0
- package/dist/internal/models/password-model.d.mts +328 -0
- package/dist/internal/models/password-model.mjs +23 -0
- package/dist/internal/models/password-model.mjs.map +1 -0
- package/dist/internal/models/proof-model.d.mts +285 -0
- package/dist/internal/models/proof-model.mjs +17 -0
- package/dist/internal/models/proof-model.mjs.map +1 -0
- package/dist/internal/models/session-model.d.mts +199 -0
- package/dist/internal/models/session-model.mjs +20 -0
- package/dist/internal/models/session-model.mjs.map +1 -0
- package/dist/internal/models/step-up-model.d.mts +66 -0
- package/dist/internal/models/step-up-model.mjs +9 -0
- package/dist/internal/models/step-up-model.mjs.map +1 -0
- package/dist/internal/oauth-app.d.mts +11 -0
- package/dist/internal/oauth-app.mjs +57 -0
- package/dist/internal/oauth-app.mjs.map +1 -0
- package/dist/internal/oauth-server.d.mts +10 -0
- package/dist/internal/oauth-server.mjs +66 -0
- package/dist/internal/oauth-server.mjs.map +1 -0
- package/dist/internal/passkey/admission.d.mts +6 -0
- package/dist/internal/passkey/admission.mjs +216 -0
- package/dist/internal/passkey/admission.mjs.map +1 -0
- package/dist/internal/passkey/credentials.d.mts +14 -0
- package/dist/internal/passkey/credentials.mjs +249 -0
- package/dist/internal/passkey/credentials.mjs.map +1 -0
- package/dist/internal/passkey/enrollment.mjs +138 -0
- package/dist/internal/passkey/enrollment.mjs.map +1 -0
- package/dist/internal/passkey/flow.d.mts +21 -0
- package/dist/internal/passkey/flow.mjs +452 -0
- package/dist/internal/passkey/flow.mjs.map +1 -0
- package/dist/internal/passkey/management.mjs +231 -0
- package/dist/internal/passkey/management.mjs.map +1 -0
- package/dist/internal/passkey/registration-ceremony.d.mts +9 -0
- package/dist/internal/passkey/registration-ceremony.mjs +129 -0
- package/dist/internal/passkey/registration-ceremony.mjs.map +1 -0
- package/dist/internal/passkey/registration-custody.d.mts +2 -0
- package/dist/internal/passkey/registration-custody.mjs +52 -0
- package/dist/internal/passkey/registration-custody.mjs.map +1 -0
- package/dist/internal/passkey/registration-write.mjs +211 -0
- package/dist/internal/passkey/registration-write.mjs.map +1 -0
- package/dist/internal/passkey/state.d.mts +10 -0
- package/dist/internal/passkey/state.mjs +234 -0
- package/dist/internal/passkey/state.mjs.map +1 -0
- package/dist/internal/passkey/target.d.mts +19 -0
- package/dist/internal/passkey/target.mjs +190 -0
- package/dist/internal/passkey/target.mjs.map +1 -0
- package/dist/internal/passkey/write-state.d.mts +17 -0
- package/dist/internal/passkey/write-state.mjs +345 -0
- package/dist/internal/passkey/write-state.mjs.map +1 -0
- package/dist/internal/passkey/write-target.mjs +192 -0
- package/dist/internal/passkey/write-target.mjs.map +1 -0
- package/dist/internal/passkey-kernel.d.mts +5592 -0
- package/dist/internal/passkey-kernel.mjs +49 -0
- package/dist/internal/passkey-kernel.mjs.map +1 -0
- package/dist/internal/passkeys.d.mts +7 -0
- package/dist/internal/passkeys.mjs +368 -0
- package/dist/internal/passkeys.mjs.map +1 -0
- package/dist/internal/password-kernel.d.mts +290 -0
- package/dist/internal/password-kernel.mjs +704 -0
- package/dist/internal/password-kernel.mjs.map +1 -0
- package/dist/internal/persistence.d.mts +25 -0
- package/dist/internal/persistence.mjs +291 -0
- package/dist/internal/persistence.mjs.map +1 -0
- package/dist/internal/phone-kernel.d.mts +162 -0
- package/dist/internal/phone-kernel.mjs +434 -0
- package/dist/internal/phone-kernel.mjs.map +1 -0
- package/dist/internal/proof-kernel.d.mts +93 -0
- package/dist/internal/proof-kernel.mjs +619 -0
- package/dist/internal/proof-kernel.mjs.map +1 -0
- package/dist/internal/query-operations.d.mts +61 -0
- package/dist/internal/registration-contract.d.mts +16 -0
- package/dist/internal/registration.mjs +66 -0
- package/dist/internal/registration.mjs.map +1 -0
- package/dist/internal/session-kernel.d.mts +48 -0
- package/dist/internal/session-kernel.mjs +737 -0
- package/dist/internal/session-kernel.mjs.map +1 -0
- package/dist/internal/sql-persistence.d.mts +10 -0
- package/dist/internal/sql-persistence.mjs +37 -0
- package/dist/internal/sql-persistence.mjs.map +1 -0
- package/dist/internal/sql-query.mjs +207 -0
- package/dist/internal/sql-query.mjs.map +1 -0
- package/dist/internal/sql-table.d.mts +36 -0
- package/dist/internal/sql-table.mjs +81 -0
- package/dist/internal/sql-table.mjs.map +1 -0
- package/dist/internal/standalone.d.mts +9 -0
- package/dist/internal/standalone.mjs +13 -0
- package/dist/internal/standalone.mjs.map +1 -0
- package/dist/internal/step-up-state.d.mts +49 -0
- package/dist/internal/step-up-state.mjs +32 -0
- package/dist/internal/step-up-state.mjs.map +1 -0
- package/dist/internal/storage-mapping.mjs +686 -0
- package/dist/internal/storage-mapping.mjs.map +1 -0
- package/dist/internal/storage-tables.d.mts +913 -0
- package/dist/internal/storage-tables.mjs +387 -0
- package/dist/internal/storage-tables.mjs.map +1 -0
- package/dist/internal/storage-validation.mjs +58 -0
- package/dist/internal/storage-validation.mjs.map +1 -0
- package/dist/internal/transaction-execution-kernel.d.mts +38 -0
- package/dist/internal/transaction-execution-kernel.mjs +116 -0
- package/dist/internal/transaction-execution-kernel.mjs.map +1 -0
- package/dist/internal/transaction-kernel.d.mts +77 -0
- package/dist/internal/transaction-kernel.mjs +260 -0
- package/dist/internal/transaction-kernel.mjs.map +1 -0
- package/package.json +1 -0
- package/src/Adapter.ts +291 -0
- package/src/index.ts +6 -0
- package/src/internal/PasswordPreparedPostconditions.ts +30 -0
- package/src/internal/configuration.ts +282 -0
- package/src/internal/email-kernel.ts +1535 -0
- package/src/internal/mapping-error.ts +36 -0
- package/src/internal/models/common.ts +11 -0
- package/src/internal/models/email-model.ts +559 -0
- package/src/internal/models/passkey-model.ts +390 -0
- package/src/internal/models/passkey-registration-ceremony-model.ts +72 -0
- package/src/internal/models/passkey-write-model.ts +297 -0
- package/src/internal/models/password-model.ts +513 -0
- package/src/internal/models/proof-model.ts +424 -0
- package/src/internal/models/session-model.ts +375 -0
- package/src/internal/models/step-up-model.ts +135 -0
- package/src/internal/oauth-app.ts +82 -0
- package/src/internal/oauth-server.ts +89 -0
- package/src/internal/passkey/admission.ts +361 -0
- package/src/internal/passkey/credentials.ts +511 -0
- package/src/internal/passkey/enrollment.ts +326 -0
- package/src/internal/passkey/flow.ts +1062 -0
- package/src/internal/passkey/management.ts +421 -0
- package/src/internal/passkey/registration-ceremony.ts +283 -0
- package/src/internal/passkey/registration-custody.ts +91 -0
- package/src/internal/passkey/registration-write.ts +426 -0
- package/src/internal/passkey/state.ts +353 -0
- package/src/internal/passkey/target.ts +586 -0
- package/src/internal/passkey/write-state.ts +681 -0
- package/src/internal/passkey/write-target.ts +452 -0
- package/src/internal/passkey-kernel.ts +104 -0
- package/src/internal/passkeys.ts +606 -0
- package/src/internal/password-kernel.ts +2124 -0
- package/src/internal/persistence.ts +588 -0
- package/src/internal/phone-kernel.ts +846 -0
- package/src/internal/proof-kernel.ts +1954 -0
- package/src/internal/query-operations.ts +81 -0
- package/src/internal/registration-contract.ts +22 -0
- package/src/internal/registration.ts +161 -0
- package/src/internal/session-kernel.ts +2217 -0
- package/src/internal/sql-persistence.ts +45 -0
- package/src/internal/sql-query.ts +298 -0
- package/src/internal/sql-table.ts +104 -0
- package/src/internal/standalone.ts +30 -0
- package/src/internal/step-up-state.ts +139 -0
- package/src/internal/storage-mapping.ts +708 -0
- package/src/internal/storage-tables.ts +408 -0
- package/src/internal/storage-validation.ts +117 -0
- package/src/internal/transaction-execution-kernel.ts +313 -0
- package/src/internal/transaction-kernel.ts +593 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"email-model.mjs","names":[],"sources":["../../../src/internal/models/email-model.ts"],"sourcesContent":["import type { EmailAction, EmailRegistrationDecision } from \"@yielded/auth/Email\";\nimport type { LoginIdentifier } from \"@yielded/auth/Identity\";\nimport type { ProofBinding, ProofContinuationId, ProofPurpose } from \"@yielded/auth/Proofs\";\nimport type { TokenDigest } from \"@yielded/auth/Schema\";\nimport type { AuthenticationRequirement, SecurityRevision } from \"@yielded/auth/Sessions\";\nimport type { Effect } from \"effect\";\n\nimport type { AnyTableModel, TableModel as Table, SqlExpression } from \"../query-operations\";\nimport type { PersistenceMappingError, SubjectIdCodec } from \"./common\";\n\ntype ColumnKey<T extends Table> = T[\"column\"];\n\nexport interface EmailSubjectReadTable<Subject extends Table> {\n readonly table: Subject[\"table\"];\n readonly id: ColumnKey<Subject>;\n readonly status: ColumnKey<Subject>;\n readonly securityRevision: ColumnKey<Subject>;\n readonly isActiveStatus: (value: unknown) => boolean;\n readonly d1ActiveStatusValue?: unknown;\n}\n\nexport interface EmailSubjectTable<Subject extends Table> extends EmailSubjectReadTable<Subject> {\n readonly decodeActionRequirement: (\n row: Subject[\"select\"],\n action: EmailAction,\n ) => Effect.Effect<AuthenticationRequirement, PersistenceMappingError>;\n readonly nextSecurityRevision?: (\n current: SecurityRevision,\n ) => Effect.Effect<SecurityRevision, PersistenceMappingError>;\n readonly nextSecurityRevisionSync?: (current: SecurityRevision) => SecurityRevision;\n readonly d1ActiveStatusValue?: unknown;\n}\n\nexport interface EmailIdentifierReadTable<Identifier extends Table> {\n readonly table: Identifier[\"table\"];\n readonly namespace: ColumnKey<Identifier>;\n readonly value: ColumnKey<Identifier>;\n readonly subjectId: ColumnKey<Identifier>;\n readonly verifiedAt: ColumnKey<Identifier>;\n readonly bindingRevision: ColumnKey<Identifier>;\n readonly isCurrent: (row: Identifier[\"select\"]) => boolean;\n}\n\nexport interface EmailIdentifierTable<\n Identifier extends Table,\n NativeSubjectId,\n Expression extends SqlExpression = SqlExpression,\n> extends EmailIdentifierReadTable<Identifier> {\n /** True only for an active, unverified binding. Confirming it preserves existing sessions. */\n readonly isMutableTarget: (row: Identifier[\"select\"]) => boolean;\n readonly encodeVerifiedInsert: (input: {\n readonly identifier: LoginIdentifier;\n readonly subjectId: NativeSubjectId;\n readonly verifiedAtMillis: number;\n readonly bindingRevision: SecurityRevision;\n }) => Identifier[\"insert\"];\n readonly encodeVerification: (input: {\n readonly verifiedAtMillis: number;\n readonly bindingRevision: SecurityRevision;\n }) => Partial<Identifier[\"insert\"]>;\n /** Must make the selected source unavailable to sign-in. */\n readonly encodeRetirement: (input: {\n readonly source: LoginIdentifier;\n readonly bindingRevision: SecurityRevision;\n }) => Partial<Identifier[\"insert\"]>;\n readonly d1CurrentCondition?: (input: {\n readonly identifier: LoginIdentifier;\n readonly nativeSubjectId: NativeSubjectId;\n readonly bindingRevision: SecurityRevision;\n }) => Expression;\n readonly d1MutableTargetCondition?: (input: {\n readonly identifier: LoginIdentifier;\n readonly nativeSubjectId: NativeSubjectId;\n }) => Expression;\n}\n\nexport interface EmailCredentialReadTable<\n Subject extends Table,\n Identifier extends Table,\n Credential extends Table,\n _NativeSubjectId,\n> {\n readonly table: Credential[\"table\"];\n readonly moduleId: ColumnKey<Credential>;\n readonly subjectId: ColumnKey<Credential>;\n readonly credentialId: ColumnKey<Credential>;\n readonly identifierNamespace: ColumnKey<Credential>;\n readonly identifierValue: ColumnKey<Credential>;\n readonly credentialRevision: ColumnKey<Credential>;\n readonly status: ColumnKey<Credential>;\n readonly isActiveStatus: (value: unknown) => boolean;\n readonly decode: (input: {\n readonly moduleId: string;\n readonly subject: Subject[\"select\"];\n readonly identifier: Identifier[\"select\"];\n readonly credential: Credential[\"select\"];\n }) => Effect.Effect<\n import(\"@yielded/auth/Email\").EmailCredentialSnapshot,\n PersistenceMappingError\n >;\n}\n\nexport interface EmailCredentialTable<\n Subject extends Table,\n Identifier extends Table,\n Credential extends Table,\n NativeSubjectId,\n> extends EmailCredentialReadTable<Subject, Identifier, Credential, NativeSubjectId> {\n readonly encodeVerifiedInsert: (input: {\n readonly moduleId: string;\n readonly subjectId: NativeSubjectId;\n readonly credentialId: string;\n readonly identifier: LoginIdentifier;\n readonly credentialRevision: SecurityRevision;\n }) => Credential[\"insert\"];\n readonly encodeActivation: (input: {\n readonly identifier: LoginIdentifier;\n readonly credentialRevision: SecurityRevision;\n }) => Partial<Credential[\"insert\"]>;\n readonly encodeRetirement: (input: {\n readonly source: LoginIdentifier;\n readonly credentialRevision: SecurityRevision;\n }) => Partial<Credential[\"insert\"]>;\n readonly d1ActiveStatusValue?: unknown;\n}\n\nexport interface EmailAuthorityCredentialTable<Credential extends Table, NativeSubjectId> {\n readonly table: Credential[\"table\"];\n readonly subjectId: ColumnKey<Credential>;\n readonly credentialId: ColumnKey<Credential>;\n readonly revision: ColumnKey<Credential>;\n readonly status: ColumnKey<Credential>;\n readonly isActiveStatus: (value: unknown) => boolean;\n readonly encodeInsert: (input: {\n readonly subjectId: NativeSubjectId;\n readonly credentialId: string;\n readonly revision: SecurityRevision;\n }) => Credential[\"insert\"];\n readonly encodeActivation: (revision: SecurityRevision) => Partial<Credential[\"insert\"]>;\n readonly encodeRetirement: (revision: SecurityRevision) => Partial<Credential[\"insert\"]>;\n readonly d1ActiveStatusValue?: unknown;\n}\n\nexport interface EmailCommandTable<Command extends Table> {\n readonly table: Command[\"table\"];\n readonly moduleId: ColumnKey<Command>;\n readonly commandId: ColumnKey<Command>;\n readonly action: ColumnKey<Command>;\n readonly bindingDigest: ColumnKey<Command>;\n readonly retentionUntil: ColumnKey<Command>;\n readonly encodeInsert: (input: {\n readonly moduleId: string;\n readonly commandId: string;\n readonly action: EmailAction;\n readonly bindingDigest: TokenDigest;\n readonly retentionUntilMillis: number;\n }) => Command[\"insert\"];\n}\n\nexport interface RequiredEmailSignInConstraints {\n readonly identifier: \"unique(identifier.namespace,identifier.value)\";\n readonly credentialId: \"unique(emailCredential.moduleId,emailCredential.credentialId)\";\n readonly credentialIdentifier: \"unique(emailCredential.moduleId,emailCredential.identifierNamespace,emailCredential.identifierValue)\";\n}\n\nexport const requiredEmailSignInConstraints: RequiredEmailSignInConstraints = {\n identifier: \"unique(identifier.namespace,identifier.value)\",\n credentialId: \"unique(emailCredential.moduleId,emailCredential.credentialId)\",\n credentialIdentifier:\n \"unique(emailCredential.moduleId,emailCredential.identifierNamespace,emailCredential.identifierValue)\",\n};\n\nexport interface EmailSignInMapping<\n Subject extends Table,\n Identifier extends Table,\n Credential extends Table,\n NativeSubjectId,\n> {\n readonly subject: EmailSubjectReadTable<Subject>;\n readonly identifier: EmailIdentifierReadTable<Identifier>;\n readonly credential: EmailCredentialReadTable<Subject, Identifier, Credential, NativeSubjectId>;\n readonly subjectId: SubjectIdCodec<NativeSubjectId>;\n readonly constraints: RequiredEmailSignInConstraints;\n readonly decodeInstant: (native: unknown) => Effect.Effect<number, PersistenceMappingError>;\n}\n\nexport interface RequiredEmailAddressConstraints extends RequiredEmailSignInConstraints {\n readonly authorityCredential: \"unique(authorityCredential.subjectId,authorityCredential.credentialId)\";\n readonly command: \"unique(emailCommand.moduleId,emailCommand.commandId)\";\n}\n\nexport const requiredEmailAddressConstraints: RequiredEmailAddressConstraints = {\n ...requiredEmailSignInConstraints,\n authorityCredential: \"unique(authorityCredential.subjectId,authorityCredential.credentialId)\",\n command: \"unique(emailCommand.moduleId,emailCommand.commandId)\",\n};\n\nexport interface EmailD1Clock<Expression extends SqlExpression = SqlExpression> {\n readonly engineNow: Expression;\n readonly engineNowMillis: Expression;\n readonly engineInstantPlus: (millis: number) => Expression;\n}\n\nexport interface EmailAddressMapping<\n Subject extends Table,\n Identifier extends Table,\n Credential extends Table,\n AuthorityCredential extends Table,\n Command extends Table,\n NativeSubjectId,\n Expression extends SqlExpression = SqlExpression,\n> extends EmailSignInMapping<Subject, Identifier, Credential, NativeSubjectId> {\n readonly subject: EmailSubjectTable<Subject>;\n readonly identifier: EmailIdentifierTable<Identifier, NativeSubjectId, Expression>;\n readonly credential: EmailCredentialTable<Subject, Identifier, Credential, NativeSubjectId>;\n readonly authorityCredential: EmailAuthorityCredentialTable<AuthorityCredential, NativeSubjectId>;\n readonly command: EmailCommandTable<Command>;\n readonly constraints: RequiredEmailAddressConstraints;\n readonly addressCardinality: \"single\" | \"multiple\";\n readonly changeDisposition: \"retire-source\";\n readonly allocateCredentialId?: Effect.Effect<string, PersistenceMappingError>;\n readonly allocateCredentialIdSync?: () => string;\n readonly allocateRevision?: Effect.Effect<SecurityRevision, PersistenceMappingError>;\n readonly allocateRevisionSync?: () => SecurityRevision;\n readonly encodeInstant: (epochMillis: number) => unknown;\n readonly commandRetentionMillis: number;\n readonly sessionInvalidation: \"same-authority-immediate\" | \"original-absolute-expiry\";\n readonly isCommandConflict: (cause: unknown) => boolean;\n readonly isIdentifierConflict: (cause: unknown) => boolean;\n readonly isCredentialConflict: (cause: unknown) => boolean;\n readonly d1?: EmailD1Clock<Expression>;\n}\n\nexport type D1EmailAddressMapping<\n Subject extends Table,\n Identifier extends Table,\n Credential extends Table,\n AuthorityCredential extends Table,\n Command extends Table,\n NativeSubjectId,\n Expression extends SqlExpression = SqlExpression,\n> = EmailAddressMapping<\n Subject,\n Identifier,\n Credential,\n AuthorityCredential,\n Command,\n NativeSubjectId,\n Expression\n> & {\n readonly d1: EmailD1Clock<Expression>;\n readonly subject: EmailSubjectTable<Subject> & {\n readonly d1ActiveStatusValue: unknown;\n };\n readonly identifier: EmailIdentifierTable<Identifier, NativeSubjectId, Expression> & {\n readonly d1CurrentCondition: NonNullable<\n EmailIdentifierTable<Identifier, NativeSubjectId, Expression>[\"d1CurrentCondition\"]\n >;\n readonly d1MutableTargetCondition: NonNullable<\n EmailIdentifierTable<Identifier, NativeSubjectId, Expression>[\"d1MutableTargetCondition\"]\n >;\n };\n readonly credential: EmailCredentialTable<Subject, Identifier, Credential, NativeSubjectId> & {\n readonly d1ActiveStatusValue: unknown;\n };\n readonly authorityCredential: EmailAuthorityCredentialTable<\n AuthorityCredential,\n NativeSubjectId\n > & {\n readonly d1ActiveStatusValue: unknown;\n };\n};\n\nexport type EmailRegistrationState = \"pending\" | \"registered\";\n\nexport interface EmailRegistrationIntent<Registration> {\n readonly moduleId: string;\n readonly commandId: string;\n readonly identifier: LoginIdentifier;\n readonly registration: Registration;\n readonly fingerprint: TokenDigest;\n readonly completion: {\n readonly moduleId: string;\n readonly purpose: ProofPurpose;\n readonly continuationId: ProofContinuationId;\n readonly binding: ProofBinding;\n };\n}\n\nexport interface EmailRegistrationTable<Registration, Request extends Table, NativeSubjectId> {\n readonly table: Request[\"table\"];\n readonly moduleId: ColumnKey<Request>;\n readonly commandId: ColumnKey<Request>;\n readonly fingerprint: ColumnKey<Request>;\n readonly state: ColumnKey<Request>;\n readonly subjectId: ColumnKey<Request>;\n readonly pendingReference: ColumnKey<Request>;\n readonly retentionUntil: ColumnKey<Request>;\n readonly encodeInsert: (\n input: EmailRegistrationIntent<Registration>,\n state: {\n readonly state: EmailRegistrationState;\n readonly nativeSubjectId?: NativeSubjectId;\n readonly pendingReference?: string;\n readonly retentionUntilMillis: number;\n },\n ) => Request[\"insert\"];\n readonly decodeReplay: (row: Request[\"select\"]) => Effect.Effect<\n Exclude<\n EmailRegistrationDecision,\n {\n readonly _tag: \"Registered\";\n }\n >,\n PersistenceMappingError\n >;\n}\n\nexport interface EmailRegistrationProvisioning<\n Registration,\n Subject extends Table,\n NativeSubjectId,\n> {\n readonly encodeSubjectInsert: (\n input: EmailRegistrationIntent<Registration>,\n values: {\n readonly nativeSubjectId: NativeSubjectId | undefined;\n readonly securityRevision: SecurityRevision;\n },\n ) => Subject[\"insert\"];\n readonly allocateSubjectId?: Effect.Effect<NativeSubjectId, PersistenceMappingError>;\n readonly allocateSubjectIdSync?: () => NativeSubjectId;\n readonly decodeGeneratedId?: (\n rows: ReadonlyArray<unknown>,\n ) => Effect.Effect<NativeSubjectId, PersistenceMappingError>;\n}\n\nexport interface EmailRegistrationIdentifierTable<\n Identifier extends Table,\n NativeSubjectId,\n Expression extends SqlExpression = SqlExpression,\n> {\n readonly table: Identifier[\"table\"];\n readonly namespace: ColumnKey<Identifier>;\n readonly value: ColumnKey<Identifier>;\n readonly subjectId: ColumnKey<Identifier>;\n readonly verifiedAt: ColumnKey<Identifier>;\n readonly bindingRevision: ColumnKey<Identifier>;\n readonly isCurrent: (row: Identifier[\"select\"]) => boolean;\n readonly d1CurrentCondition?: (input: {\n readonly identifier: LoginIdentifier;\n readonly nativeSubjectId: NativeSubjectId;\n readonly bindingRevision: SecurityRevision;\n }) => Expression;\n readonly encodeVerifiedInsert: (input: {\n readonly identifier: LoginIdentifier;\n readonly subjectId: NativeSubjectId;\n readonly verifiedAtMillis: number;\n readonly bindingRevision: SecurityRevision;\n }) => Identifier[\"insert\"];\n}\n\nexport interface EmailRegistrationCredentialTable<Credential extends Table, NativeSubjectId> {\n readonly table: Credential[\"table\"];\n readonly moduleId: ColumnKey<Credential>;\n readonly subjectId: ColumnKey<Credential>;\n readonly credentialId: ColumnKey<Credential>;\n readonly identifierNamespace: ColumnKey<Credential>;\n readonly identifierValue: ColumnKey<Credential>;\n readonly credentialRevision: ColumnKey<Credential>;\n readonly status: ColumnKey<Credential>;\n readonly isActiveStatus: (value: unknown) => boolean;\n readonly d1ActiveStatusValue?: unknown;\n readonly encodeVerifiedInsert: (input: {\n readonly moduleId: string;\n readonly subjectId: NativeSubjectId;\n readonly credentialId: string;\n readonly identifier: LoginIdentifier;\n readonly credentialRevision: SecurityRevision;\n }) => Credential[\"insert\"];\n}\n\nexport interface EmailRegistrationAuthorityCredentialTable<\n Credential extends Table,\n NativeSubjectId,\n> {\n readonly table: Credential[\"table\"];\n readonly subjectId: ColumnKey<Credential>;\n readonly credentialId: ColumnKey<Credential>;\n readonly revision: ColumnKey<Credential>;\n readonly status: ColumnKey<Credential>;\n readonly isActiveStatus: (value: unknown) => boolean;\n readonly d1ActiveStatusValue?: unknown;\n readonly encodeInsert: (input: {\n readonly subjectId: NativeSubjectId;\n readonly credentialId: string;\n readonly revision: SecurityRevision;\n }) => Credential[\"insert\"];\n}\n\nexport interface RequiredEmailRegistrationConstraints extends RequiredEmailSignInConstraints {\n readonly authorityCredential: \"unique(authorityCredential.subjectId,authorityCredential.credentialId)\";\n readonly request: \"unique(emailRegistration.moduleId,emailRegistration.commandId)\";\n readonly pendingReference: \"unique(emailRegistration.pendingReference)\";\n}\n\nexport const requiredEmailRegistrationConstraints: RequiredEmailRegistrationConstraints = {\n ...requiredEmailSignInConstraints,\n authorityCredential: \"unique(authorityCredential.subjectId,authorityCredential.credentialId)\",\n request: \"unique(emailRegistration.moduleId,emailRegistration.commandId)\",\n pendingReference: \"unique(emailRegistration.pendingReference)\",\n};\n\ntype EmailRegistrationBase<Registration, Request extends Table, NativeSubjectId> = {\n readonly registration: EmailRegistrationTable<Registration, Request, NativeSubjectId>;\n readonly constraints: Pick<RequiredEmailRegistrationConstraints, \"request\" | \"pendingReference\">;\n readonly inspect: (input: {\n readonly identifier: LoginIdentifier;\n readonly registration: Registration;\n }) => Effect.Effect<\n {\n readonly fingerprint: TokenDigest;\n readonly eligible: boolean;\n },\n PersistenceMappingError\n >;\n /** Projects one detached value of the factory-specific Registration Type. */\n readonly snapshotRegistration: (\n registration: Registration,\n ) => Effect.Effect<Registration, PersistenceMappingError>;\n /** Required by synchronous transaction-bound services. */\n readonly snapshotRegistrationSync?: (registration: Registration) => Registration;\n /** Required by synchronous Durable Object transaction-bound services. */\n readonly inspectSync?: (input: {\n readonly identifier: LoginIdentifier;\n readonly registration: Registration;\n }) => {\n readonly fingerprint: TokenDigest;\n readonly eligible: boolean;\n };\n readonly allocatePendingReference?: Effect.Effect<string, PersistenceMappingError>;\n readonly allocatePendingReferenceSync?: () => string;\n readonly encodeInstant: (epochMillis: number) => unknown;\n readonly retentionMillis: number;\n readonly isRequestConflict: (cause: unknown) => boolean;\n};\n\nexport type EmailRegistrationMapping<\n Registration,\n Subject extends Table,\n Identifier extends Table,\n Credential extends Table,\n AuthorityCredential extends Table,\n Request extends Table,\n NativeSubjectId,\n Expression extends SqlExpression = SqlExpression,\n> = EmailRegistrationBase<Registration, Request, NativeSubjectId> &\n (\n | {\n readonly mode: \"atomic\";\n readonly subject: EmailSubjectReadTable<Subject>;\n readonly identifier: EmailRegistrationIdentifierTable<\n Identifier,\n NativeSubjectId,\n Expression\n >;\n readonly credential: EmailRegistrationCredentialTable<Credential, NativeSubjectId>;\n readonly authorityCredential: EmailRegistrationAuthorityCredentialTable<\n AuthorityCredential,\n NativeSubjectId\n >;\n readonly subjectId: SubjectIdCodec<NativeSubjectId>;\n readonly constraints: RequiredEmailRegistrationConstraints;\n readonly allocateCredentialId?: Effect.Effect<string, PersistenceMappingError>;\n readonly allocateCredentialIdSync?: () => string;\n readonly allocateRevision?: Effect.Effect<SecurityRevision, PersistenceMappingError>;\n readonly allocateRevisionSync?: () => SecurityRevision;\n readonly isIdentifierConflict: (cause: unknown) => boolean;\n readonly isCredentialConflict: (cause: unknown) => boolean;\n readonly provisioning: EmailRegistrationProvisioning<\n Registration,\n Subject,\n NativeSubjectId\n > &\n (\n | {\n readonly idMode: \"allocated\";\n readonly allocateSubjectId: Effect.Effect<NativeSubjectId, PersistenceMappingError>;\n }\n | {\n readonly idMode: \"synchronous\";\n readonly allocateSubjectIdSync: () => NativeSubjectId;\n }\n | {\n readonly idMode: \"generated\";\n readonly decodeGeneratedId: (\n rows: ReadonlyArray<unknown>,\n ) => Effect.Effect<NativeSubjectId, PersistenceMappingError>;\n }\n );\n }\n | {\n readonly mode: \"pending\";\n }\n );\n\nexport type AnyEmailSignInMapping = EmailSignInMapping<\n AnyTableModel,\n AnyTableModel,\n AnyTableModel,\n unknown\n>;\n\nexport type AnyEmailAddressMapping<Expression extends SqlExpression = SqlExpression> =\n EmailAddressMapping<\n AnyTableModel,\n AnyTableModel,\n AnyTableModel,\n AnyTableModel,\n AnyTableModel,\n unknown,\n Expression\n >;\n\nexport type AnyEmailRegistrationMapping<\n Registration = unknown,\n Expression extends SqlExpression = SqlExpression,\n> = EmailRegistrationMapping<\n Registration,\n AnyTableModel,\n AnyTableModel,\n AnyTableModel,\n AnyTableModel,\n AnyTableModel,\n unknown,\n Expression\n>;\n\nexport type D1EmailRegistrationMapping<\n Registration,\n Subject extends Table,\n Identifier extends Table,\n Credential extends Table,\n AuthorityCredential extends Table,\n Request extends Table,\n NativeSubjectId,\n Expression extends SqlExpression = SqlExpression,\n> = EmailRegistrationMapping<\n Registration,\n Subject,\n Identifier,\n Credential,\n AuthorityCredential,\n Request,\n NativeSubjectId,\n Expression\n> & {\n readonly d1: EmailD1Clock<Expression>;\n};\n"],"mappings":";AAqKA,MAAa,iCAAiE;CAC5E,YAAY;CACZ,cAAc;CACd,sBACE;AACJ;AAqBA,MAAa,kCAAmE;CAC9E,GAAG;CACH,qBAAqB;CACrB,SAAS;AACX;AAmNA,MAAa,uCAA6E;CACxF,GAAG;CACH,qBAAqB;CACrB,SAAS;CACT,kBAAkB;AACpB"}
|
|
@@ -0,0 +1,266 @@
|
|
|
1
|
+
import { SqlExpression, TableModel } from "../query-operations.mjs";
|
|
2
|
+
import { PersistenceMappingError } from "../mapping-error.mjs";
|
|
3
|
+
import "./common.mjs";
|
|
4
|
+
import { Effect, Layer } from "effect";
|
|
5
|
+
import { PasskeyCeremony, PasskeyCredential, PasskeyCredentials, PasskeyEnrollmentContext, PasskeyMethodPolicy, PasskeyPersistence } from "@yielded/auth/Passkey";
|
|
6
|
+
import { SubjectId } from "@yielded/auth/Schema";
|
|
7
|
+
//#region src/internal/models/passkey-model.d.ts
|
|
8
|
+
export type PasskeyColumn<T extends TableModel> = T["column"];
|
|
9
|
+
export type PasskeyMappingSource<M, RSetup = never> = M | Effect.Effect<M, PersistenceMappingError, RSetup>;
|
|
10
|
+
export interface PasskeyCredentialServices {
|
|
11
|
+
readonly passkeyCredentials: PasskeyCredentials["Service"];
|
|
12
|
+
}
|
|
13
|
+
export interface PasskeyPersistenceServices {
|
|
14
|
+
readonly passkeyPersistence: PasskeyPersistence["Service"];
|
|
15
|
+
}
|
|
16
|
+
export interface PasskeyEnrollmentContextServices {
|
|
17
|
+
readonly passkeyEnrollmentContext: PasskeyEnrollmentContext["Service"];
|
|
18
|
+
}
|
|
19
|
+
export declare const passkeyCredentialsLayer: <E, R>(services: Effect.Effect<PasskeyCredentialServices, E, R>) => Layer.Layer<PasskeyCredentials, E, R>;
|
|
20
|
+
export declare const passkeyPersistenceLayer: <E, R>(services: Effect.Effect<PasskeyPersistenceServices, E, R>) => Layer.Layer<PasskeyPersistence, E, R>;
|
|
21
|
+
export declare const passkeyEnrollmentContextLayer: <E, R>(services: Effect.Effect<PasskeyEnrollmentContextServices, E, R>) => Layer.Layer<PasskeyEnrollmentContext, E, R>;
|
|
22
|
+
/** Native IDs roundtrip exactly; protocol IDs and authentication references are
|
|
23
|
+
* different identities. These callbacks never suspend inside an owner. */
|
|
24
|
+
export interface PasskeySubjectIdCodec<N> {
|
|
25
|
+
readonly toNative: (id: SubjectId) => N;
|
|
26
|
+
readonly toSubject: (id: N) => SubjectId;
|
|
27
|
+
readonly equals: (left: N, right: N) => boolean;
|
|
28
|
+
}
|
|
29
|
+
export interface PasskeyClock<Expression extends SqlExpression = SqlExpression> {
|
|
30
|
+
readonly encodeInstant: (millis: number) => unknown;
|
|
31
|
+
readonly decodeInstant: (value: unknown) => number;
|
|
32
|
+
readonly engineNowMillis: Expression;
|
|
33
|
+
readonly toMillis: (expression: Expression) => Expression;
|
|
34
|
+
readonly fromMillis: (expression: Expression) => Expression;
|
|
35
|
+
}
|
|
36
|
+
export interface PasskeySubjectReadTable<T extends TableModel, N, Expression extends SqlExpression = SqlExpression> {
|
|
37
|
+
readonly table: T["table"];
|
|
38
|
+
readonly id: PasskeyColumn<T>;
|
|
39
|
+
readonly status: PasskeyColumn<T>;
|
|
40
|
+
readonly securityRevision: PasskeyColumn<T>;
|
|
41
|
+
readonly decodeId: (row: Readonly<Partial<T["select"]>>) => N;
|
|
42
|
+
readonly isActiveStatus: (value: unknown) => boolean;
|
|
43
|
+
readonly activeCondition: Expression;
|
|
44
|
+
}
|
|
45
|
+
export interface PasskeyFactorReadTable<T extends TableModel, Expression extends SqlExpression = SqlExpression> {
|
|
46
|
+
readonly table: T["table"];
|
|
47
|
+
readonly subjectId: PasskeyColumn<T>;
|
|
48
|
+
readonly credentialId: PasskeyColumn<T>;
|
|
49
|
+
readonly revision: PasskeyColumn<T>;
|
|
50
|
+
readonly status: PasskeyColumn<T>;
|
|
51
|
+
readonly isActiveStatus: (value: unknown) => boolean;
|
|
52
|
+
readonly activeCondition: Expression;
|
|
53
|
+
}
|
|
54
|
+
/** decode uses only these declared columns. Counter columns are native integral
|
|
55
|
+
* numbers; BS may use a consumer enum. Name/creation metadata is not required. */
|
|
56
|
+
export interface PasskeyCredentialReadTable<T extends TableModel, N, Expression extends SqlExpression = SqlExpression> {
|
|
57
|
+
readonly table: T["table"];
|
|
58
|
+
readonly credentialId: PasskeyColumn<T>;
|
|
59
|
+
readonly subjectId: PasskeyColumn<T>;
|
|
60
|
+
readonly rpId: PasskeyColumn<T>;
|
|
61
|
+
readonly protocolCredentialId: PasskeyColumn<T>;
|
|
62
|
+
readonly credentialKey: PasskeyColumn<T>;
|
|
63
|
+
readonly handleKey: PasskeyColumn<T>;
|
|
64
|
+
readonly userHandle: PasskeyColumn<T>;
|
|
65
|
+
readonly publicKey: PasskeyColumn<T>;
|
|
66
|
+
readonly algorithm: PasskeyColumn<T>;
|
|
67
|
+
readonly profile: PasskeyColumn<T>;
|
|
68
|
+
readonly credentialRevision: PasskeyColumn<T>;
|
|
69
|
+
readonly status: PasskeyColumn<T>;
|
|
70
|
+
readonly primarySignIn: PasskeyColumn<T>;
|
|
71
|
+
readonly enrollmentUserVerified: PasskeyColumn<T>;
|
|
72
|
+
readonly backupEligible: PasskeyColumn<T>;
|
|
73
|
+
readonly backupState: PasskeyColumn<T>;
|
|
74
|
+
readonly counter: PasskeyColumn<T>;
|
|
75
|
+
readonly maximumCounter: PasskeyColumn<T>;
|
|
76
|
+
readonly decode: (row: Readonly<Partial<T["select"]>>) => Omit<PasskeyCredential, "revision" | "active">;
|
|
77
|
+
readonly decodeSubjectId: (row: Readonly<Partial<T["select"]>>) => N;
|
|
78
|
+
readonly isActiveStatus: (value: unknown) => boolean;
|
|
79
|
+
readonly activeCondition: Expression;
|
|
80
|
+
}
|
|
81
|
+
export interface PasskeyCredentialOwnershipTable<T extends TableModel, N, Expression extends SqlExpression = SqlExpression> {
|
|
82
|
+
readonly table: T["table"];
|
|
83
|
+
readonly credentialKey: PasskeyColumn<T>;
|
|
84
|
+
readonly rpId: PasskeyColumn<T>;
|
|
85
|
+
readonly protocolCredentialId: PasskeyColumn<T>;
|
|
86
|
+
readonly subjectId: PasskeyColumn<T>;
|
|
87
|
+
readonly credentialId: PasskeyColumn<T>;
|
|
88
|
+
readonly state: PasskeyColumn<T>;
|
|
89
|
+
readonly version: PasskeyColumn<T>;
|
|
90
|
+
readonly reservationId: PasskeyColumn<T>;
|
|
91
|
+
readonly ownedCondition: Expression;
|
|
92
|
+
readonly isOwnedState: (value: unknown) => boolean;
|
|
93
|
+
readonly decodeSubjectId: (row: Readonly<Partial<T["select"]>>) => N;
|
|
94
|
+
}
|
|
95
|
+
/** Reservations do not manufacture a subject; bound handles are RP-global. */
|
|
96
|
+
export interface PasskeyHandleReadTable<T extends TableModel> {
|
|
97
|
+
readonly table: T["table"];
|
|
98
|
+
readonly handleKey: PasskeyColumn<T>;
|
|
99
|
+
readonly rpId: PasskeyColumn<T>;
|
|
100
|
+
readonly userHandle: PasskeyColumn<T>;
|
|
101
|
+
readonly state: PasskeyColumn<T>;
|
|
102
|
+
readonly version: PasskeyColumn<T>;
|
|
103
|
+
readonly reservationId: PasskeyColumn<T>;
|
|
104
|
+
}
|
|
105
|
+
export interface PasskeyHandleReservationTable<T extends TableModel, Expression extends SqlExpression = SqlExpression> extends PasskeyHandleReadTable<T> {
|
|
106
|
+
readonly reservedCondition: Expression;
|
|
107
|
+
readonly isReservedState: (value: unknown) => boolean;
|
|
108
|
+
}
|
|
109
|
+
export interface PasskeyHandleOwnershipTable<T extends TableModel, N, Expression extends SqlExpression = SqlExpression> extends PasskeyHandleReadTable<T> {
|
|
110
|
+
readonly subjectId: PasskeyColumn<T>;
|
|
111
|
+
readonly ownedCondition: Expression;
|
|
112
|
+
readonly isOwnedState: (value: unknown) => boolean;
|
|
113
|
+
readonly decodeSubjectId: (row: Readonly<Partial<T["select"]>>) => N;
|
|
114
|
+
}
|
|
115
|
+
export declare const requiredPasskeyCredentialConstraints: {
|
|
116
|
+
readonly credentialId: readonly ["credentialId"];
|
|
117
|
+
readonly factor: readonly ["subjectId", "credentialId"];
|
|
118
|
+
readonly credentialOwnership: readonly ["credentialKey"];
|
|
119
|
+
readonly handleOwnership: readonly ["handleKey"];
|
|
120
|
+
readonly boundSubjectHandle: readonly ["rpId", "subjectId"];
|
|
121
|
+
};
|
|
122
|
+
export interface PasskeyCredentialMapping<S extends TableModel, C extends TableModel, F extends TableModel, Ownership extends TableModel, Handle extends TableModel, N, Expression extends SqlExpression = SqlExpression> {
|
|
123
|
+
readonly subject: PasskeySubjectReadTable<S, N, Expression>;
|
|
124
|
+
readonly credential: PasskeyCredentialReadTable<C, N, Expression>;
|
|
125
|
+
readonly authority: PasskeyFactorReadTable<F, Expression>;
|
|
126
|
+
readonly credentialOwnership: PasskeyCredentialOwnershipTable<Ownership, N, Expression>;
|
|
127
|
+
readonly handleOwnership: PasskeyHandleOwnershipTable<Handle, N, Expression>;
|
|
128
|
+
readonly subjectIds: PasskeySubjectIdCodec<N>;
|
|
129
|
+
readonly constraints: typeof requiredPasskeyCredentialConstraints;
|
|
130
|
+
}
|
|
131
|
+
/** A stable additional policy row, acquired before RP/credential locks. The
|
|
132
|
+
* factory checks column names without erasing the consumer table at its input. */
|
|
133
|
+
declare const PasskeyPolicyGuardTypeId: unique symbol;
|
|
134
|
+
export interface PasskeyPolicyGuard<Expression extends SqlExpression = SqlExpression> {
|
|
135
|
+
readonly [PasskeyPolicyGuardTypeId]: true;
|
|
136
|
+
readonly scope: string;
|
|
137
|
+
readonly table: object;
|
|
138
|
+
readonly columns: ReadonlyArray<string>;
|
|
139
|
+
readonly where: (moduleId: string) => Expression;
|
|
140
|
+
readonly condition: (moduleId: string) => Expression;
|
|
141
|
+
}
|
|
142
|
+
export declare const passkeyPolicyGuard: <T extends TableModel, Expression extends SqlExpression = SqlExpression>(input: {
|
|
143
|
+
readonly scope: string;
|
|
144
|
+
readonly table: T["table"];
|
|
145
|
+
readonly columns: ReadonlyArray<PasskeyColumn<T>>;
|
|
146
|
+
readonly where: (moduleId: string) => Expression;
|
|
147
|
+
readonly condition: (moduleId: string) => Expression;
|
|
148
|
+
}) => PasskeyPolicyGuard<Expression>;
|
|
149
|
+
export interface PasskeyModuleTable<T extends TableModel, Expression extends SqlExpression = SqlExpression> {
|
|
150
|
+
readonly table: T["table"];
|
|
151
|
+
readonly moduleId: PasskeyColumn<T>;
|
|
152
|
+
readonly status: PasskeyColumn<T>;
|
|
153
|
+
readonly policyRevision: PasskeyColumn<T>;
|
|
154
|
+
/** All physical fields used by decodeMethodPolicy, including policyRevision. */
|
|
155
|
+
readonly policyColumns: ReadonlyArray<PasskeyColumn<T>>;
|
|
156
|
+
readonly isActiveStatus: (value: unknown) => boolean;
|
|
157
|
+
readonly activeCondition: Expression;
|
|
158
|
+
readonly decodeMethodPolicy: (row: Readonly<Partial<T["select"]>>) => PasskeyMethodPolicy;
|
|
159
|
+
readonly guards?: ReadonlyArray<PasskeyPolicyGuard<Expression>>;
|
|
160
|
+
}
|
|
161
|
+
export type PasskeyFlowState = "Pending" | "Claimed" | "Verified" | "Rejected" | "Ambiguous" | "RegistrationAccepted" | "ProvisioningPending";
|
|
162
|
+
export interface PasskeyFlowInsert {
|
|
163
|
+
readonly ceremony: PasskeyCeremony;
|
|
164
|
+
readonly policy: PasskeyMethodPolicy;
|
|
165
|
+
readonly marker: string;
|
|
166
|
+
}
|
|
167
|
+
export interface PasskeyFlowTable<T extends TableModel> {
|
|
168
|
+
readonly table: T["table"];
|
|
169
|
+
readonly moduleId: PasskeyColumn<T>;
|
|
170
|
+
readonly flowId: PasskeyColumn<T>;
|
|
171
|
+
readonly commandId: PasskeyColumn<T>;
|
|
172
|
+
readonly purpose: PasskeyColumn<T>;
|
|
173
|
+
readonly state: PasskeyColumn<T>;
|
|
174
|
+
readonly version: PasskeyColumn<T>;
|
|
175
|
+
readonly generation: PasskeyColumn<T>;
|
|
176
|
+
readonly snapshot: PasskeyColumn<T>;
|
|
177
|
+
readonly policySnapshot: PasskeyColumn<T>;
|
|
178
|
+
readonly requestBindingVerifier: PasskeyColumn<T>;
|
|
179
|
+
readonly requestBindingExpiresAt: PasskeyColumn<T>;
|
|
180
|
+
readonly issuedAt: PasskeyColumn<T>;
|
|
181
|
+
readonly expiresAt: PasskeyColumn<T>;
|
|
182
|
+
readonly retentionUntil: PasskeyColumn<T>;
|
|
183
|
+
readonly claimId: PasskeyColumn<T>;
|
|
184
|
+
readonly claimedAt: PasskeyColumn<T>;
|
|
185
|
+
readonly claimExpiresAt: PasskeyColumn<T>;
|
|
186
|
+
readonly credentialSnapshot: PasskeyColumn<T>;
|
|
187
|
+
/** Core SubjectId scope text, not a consumer's native subject ID. */
|
|
188
|
+
readonly subjectScope: PasskeyColumn<T>;
|
|
189
|
+
readonly targetScope: PasskeyColumn<T>;
|
|
190
|
+
readonly states: Readonly<Record<PasskeyFlowState, unknown>>;
|
|
191
|
+
readonly encodeInsert: (input: PasskeyFlowInsert) => T["insert"];
|
|
192
|
+
}
|
|
193
|
+
export interface PasskeyAdmissionTable<T extends TableModel> {
|
|
194
|
+
readonly table: T["table"];
|
|
195
|
+
readonly authorityScope: PasskeyColumn<T>;
|
|
196
|
+
readonly moduleId: PasskeyColumn<T>;
|
|
197
|
+
readonly version: PasskeyColumn<T>;
|
|
198
|
+
readonly ownerMarker: PasskeyColumn<T>;
|
|
199
|
+
/** One physical clock sample, reused by every charge of this decision. */
|
|
200
|
+
readonly admittedAt: PasskeyColumn<T>;
|
|
201
|
+
}
|
|
202
|
+
export type PasskeyChargeKind = "global" | "subject" | "target";
|
|
203
|
+
export interface PasskeyChargeInsert {
|
|
204
|
+
readonly moduleId: string;
|
|
205
|
+
readonly flowId: string;
|
|
206
|
+
readonly purpose: PasskeyCeremony["purpose"];
|
|
207
|
+
readonly kind: PasskeyChargeKind;
|
|
208
|
+
readonly scope: string;
|
|
209
|
+
readonly originalWindowMillis: number;
|
|
210
|
+
readonly marker: string;
|
|
211
|
+
}
|
|
212
|
+
/** Charge scope is canonical core identity text; this subject-free descriptor
|
|
213
|
+
* can count all purposes without decoding any unrelated native subject. */
|
|
214
|
+
export interface PasskeyChargeTable<T extends TableModel> {
|
|
215
|
+
readonly table: T["table"];
|
|
216
|
+
readonly moduleId: PasskeyColumn<T>;
|
|
217
|
+
readonly flowId: PasskeyColumn<T>;
|
|
218
|
+
readonly purpose: PasskeyColumn<T>;
|
|
219
|
+
readonly kind: PasskeyColumn<T>;
|
|
220
|
+
readonly scope: PasskeyColumn<T>;
|
|
221
|
+
readonly originalWindowMillis: PasskeyColumn<T>;
|
|
222
|
+
readonly admittedAt: PasskeyColumn<T>;
|
|
223
|
+
readonly retainUntil: PasskeyColumn<T>;
|
|
224
|
+
readonly version: PasskeyColumn<T>;
|
|
225
|
+
readonly ownerMarker: PasskeyColumn<T>;
|
|
226
|
+
readonly encodeInsert: (input: PasskeyChargeInsert) => T["insert"];
|
|
227
|
+
}
|
|
228
|
+
export declare const requiredPasskeyPersistenceConstraints: {
|
|
229
|
+
readonly flow: readonly ["moduleId", "flowId"];
|
|
230
|
+
readonly command: readonly ["moduleId", "commandId"];
|
|
231
|
+
readonly admission: readonly ["authorityScope", "moduleId"];
|
|
232
|
+
readonly charge: readonly ["moduleId", "flowId", "kind"];
|
|
233
|
+
};
|
|
234
|
+
export interface PasskeyCeremonyMapping<Module extends TableModel, Flow extends TableModel, Admission extends TableModel, Charge extends TableModel, Expression extends SqlExpression = SqlExpression> {
|
|
235
|
+
readonly moduleId: string;
|
|
236
|
+
readonly authorityScope: string;
|
|
237
|
+
readonly module: PasskeyModuleTable<Module, Expression>;
|
|
238
|
+
readonly flow: PasskeyFlowTable<Flow>;
|
|
239
|
+
readonly admission: PasskeyAdmissionTable<Admission>;
|
|
240
|
+
readonly charge: PasskeyChargeTable<Charge>;
|
|
241
|
+
readonly clock: PasskeyClock<Expression>;
|
|
242
|
+
readonly constraints: typeof requiredPasskeyPersistenceConstraints;
|
|
243
|
+
}
|
|
244
|
+
export interface PasskeyPersistenceMapping<Read, Module extends TableModel, Flow extends TableModel, Admission extends TableModel, Charge extends TableModel, N, Expression extends SqlExpression = SqlExpression, Credential extends TableModel = TableModel> extends PasskeyCeremonyMapping<Module, Flow, Admission, Charge, Expression> {
|
|
245
|
+
readonly read: Read & {
|
|
246
|
+
readonly subjectIds: PasskeySubjectIdCodec<N>;
|
|
247
|
+
};
|
|
248
|
+
readonly telemetry: {
|
|
249
|
+
readonly lastUsedAt: PasskeyColumn<Credential>;
|
|
250
|
+
readonly encodeBackupState: (value: boolean) => unknown;
|
|
251
|
+
};
|
|
252
|
+
}
|
|
253
|
+
export interface PasskeyEnrollmentContextMapping<Read, Module extends TableModel, N, Expression extends SqlExpression = SqlExpression> {
|
|
254
|
+
readonly moduleId: string;
|
|
255
|
+
readonly read: Read & {
|
|
256
|
+
readonly subjectIds: PasskeySubjectIdCodec<N>;
|
|
257
|
+
};
|
|
258
|
+
readonly module: PasskeyModuleTable<Module, Expression>;
|
|
259
|
+
}
|
|
260
|
+
export interface D1PasskeyMapping {
|
|
261
|
+
readonly d1: {
|
|
262
|
+
readonly primary: true;
|
|
263
|
+
};
|
|
264
|
+
}
|
|
265
|
+
//#endregion
|
|
266
|
+
//# sourceMappingURL=passkey-model.d.mts.map
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { Effect, Layer } from "effect";
|
|
2
|
+
import { PasskeyCredentials, PasskeyEnrollmentContext, PasskeyPersistence } from "@yielded/auth/Passkey";
|
|
3
|
+
//#region src/internal/models/passkey-model.ts
|
|
4
|
+
const passkeyCredentialsLayer = (services) => Layer.effect(PasskeyCredentials, Effect.map(services, (value) => value.passkeyCredentials));
|
|
5
|
+
const passkeyPersistenceLayer = (services) => Layer.effect(PasskeyPersistence, Effect.map(services, (value) => value.passkeyPersistence));
|
|
6
|
+
const passkeyEnrollmentContextLayer = (services) => Layer.effect(PasskeyEnrollmentContext, Effect.map(services, (value) => value.passkeyEnrollmentContext));
|
|
7
|
+
const requiredPasskeyCredentialConstraints = {
|
|
8
|
+
credentialId: ["credentialId"],
|
|
9
|
+
factor: ["subjectId", "credentialId"],
|
|
10
|
+
credentialOwnership: ["credentialKey"],
|
|
11
|
+
handleOwnership: ["handleKey"],
|
|
12
|
+
boundSubjectHandle: ["rpId", "subjectId"]
|
|
13
|
+
};
|
|
14
|
+
/** A stable additional policy row, acquired before RP/credential locks. The
|
|
15
|
+
* factory checks column names without erasing the consumer table at its input. */
|
|
16
|
+
const PasskeyPolicyGuardTypeId = Symbol("effect-auth/drizzle/PasskeyPolicyGuard");
|
|
17
|
+
const passkeyPolicyGuard = (input) => ({
|
|
18
|
+
...input,
|
|
19
|
+
[PasskeyPolicyGuardTypeId]: true
|
|
20
|
+
});
|
|
21
|
+
const requiredPasskeyPersistenceConstraints = {
|
|
22
|
+
flow: ["moduleId", "flowId"],
|
|
23
|
+
command: ["moduleId", "commandId"],
|
|
24
|
+
admission: ["authorityScope", "moduleId"],
|
|
25
|
+
charge: [
|
|
26
|
+
"moduleId",
|
|
27
|
+
"flowId",
|
|
28
|
+
"kind"
|
|
29
|
+
]
|
|
30
|
+
};
|
|
31
|
+
//#endregion
|
|
32
|
+
export { passkeyCredentialsLayer, passkeyEnrollmentContextLayer, passkeyPersistenceLayer, passkeyPolicyGuard, requiredPasskeyCredentialConstraints, requiredPasskeyPersistenceConstraints };
|
|
33
|
+
|
|
34
|
+
//# sourceMappingURL=passkey-model.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"passkey-model.mjs","names":[],"sources":["../../../src/internal/models/passkey-model.ts"],"sourcesContent":["import {\n type PasskeyCeremony,\n type PasskeyCredential,\n type PasskeyMethodPolicy,\n PasskeyCredentials,\n PasskeyEnrollmentContext,\n PasskeyPersistence,\n} from \"@yielded/auth/Passkey\";\nimport type { SubjectId } from \"@yielded/auth/Schema\";\nimport { Effect, Layer } from \"effect\";\n\nimport type { TableModel as Table, SqlExpression } from \"../query-operations\";\nimport type { PersistenceMappingError } from \"./common\";\n\nexport type PasskeyColumn<T extends Table> = T[\"column\"];\n\nexport type PasskeyMappingSource<M, RSetup = never> =\n | M\n | Effect.Effect<M, PersistenceMappingError, RSetup>;\n\nexport interface PasskeyCredentialServices {\n readonly passkeyCredentials: PasskeyCredentials[\"Service\"];\n}\n\nexport interface PasskeyPersistenceServices {\n readonly passkeyPersistence: PasskeyPersistence[\"Service\"];\n}\n\nexport interface PasskeyEnrollmentContextServices {\n readonly passkeyEnrollmentContext: PasskeyEnrollmentContext[\"Service\"];\n}\n\nexport const passkeyCredentialsLayer = <E, R>(\n services: Effect.Effect<PasskeyCredentialServices, E, R>,\n): Layer.Layer<PasskeyCredentials, E, R> =>\n Layer.effect(\n PasskeyCredentials,\n Effect.map(services, (value) => value.passkeyCredentials),\n );\n\nexport const passkeyPersistenceLayer = <E, R>(\n services: Effect.Effect<PasskeyPersistenceServices, E, R>,\n): Layer.Layer<PasskeyPersistence, E, R> =>\n Layer.effect(\n PasskeyPersistence,\n Effect.map(services, (value) => value.passkeyPersistence),\n );\n\nexport const passkeyEnrollmentContextLayer = <E, R>(\n services: Effect.Effect<PasskeyEnrollmentContextServices, E, R>,\n): Layer.Layer<PasskeyEnrollmentContext, E, R> =>\n Layer.effect(\n PasskeyEnrollmentContext,\n Effect.map(services, (value) => value.passkeyEnrollmentContext),\n );\n\n/** Native IDs roundtrip exactly; protocol IDs and authentication references are\n * different identities. These callbacks never suspend inside an owner. */\nexport interface PasskeySubjectIdCodec<N> {\n readonly toNative: (id: SubjectId) => N;\n readonly toSubject: (id: N) => SubjectId;\n readonly equals: (left: N, right: N) => boolean;\n}\n\nexport interface PasskeyClock<Expression extends SqlExpression = SqlExpression> {\n readonly encodeInstant: (millis: number) => unknown;\n readonly decodeInstant: (value: unknown) => number;\n readonly engineNowMillis: Expression;\n readonly toMillis: (expression: Expression) => Expression;\n readonly fromMillis: (expression: Expression) => Expression;\n}\n\nexport interface PasskeySubjectReadTable<\n T extends Table,\n N,\n Expression extends SqlExpression = SqlExpression,\n> {\n readonly table: T[\"table\"];\n readonly id: PasskeyColumn<T>;\n readonly status: PasskeyColumn<T>;\n readonly securityRevision: PasskeyColumn<T>;\n readonly decodeId: (row: Readonly<Partial<T[\"select\"]>>) => N;\n readonly isActiveStatus: (value: unknown) => boolean;\n readonly activeCondition: Expression;\n}\n\nexport interface PasskeyFactorReadTable<\n T extends Table,\n Expression extends SqlExpression = SqlExpression,\n> {\n readonly table: T[\"table\"];\n readonly subjectId: PasskeyColumn<T>;\n readonly credentialId: PasskeyColumn<T>;\n readonly revision: PasskeyColumn<T>;\n readonly status: PasskeyColumn<T>;\n readonly isActiveStatus: (value: unknown) => boolean;\n readonly activeCondition: Expression;\n}\n\n/** decode uses only these declared columns. Counter columns are native integral\n * numbers; BS may use a consumer enum. Name/creation metadata is not required. */\nexport interface PasskeyCredentialReadTable<\n T extends Table,\n N,\n Expression extends SqlExpression = SqlExpression,\n> {\n readonly table: T[\"table\"];\n readonly credentialId: PasskeyColumn<T>;\n readonly subjectId: PasskeyColumn<T>;\n readonly rpId: PasskeyColumn<T>;\n readonly protocolCredentialId: PasskeyColumn<T>;\n readonly credentialKey: PasskeyColumn<T>;\n readonly handleKey: PasskeyColumn<T>;\n readonly userHandle: PasskeyColumn<T>;\n readonly publicKey: PasskeyColumn<T>;\n readonly algorithm: PasskeyColumn<T>;\n readonly profile: PasskeyColumn<T>;\n readonly credentialRevision: PasskeyColumn<T>;\n readonly status: PasskeyColumn<T>;\n readonly primarySignIn: PasskeyColumn<T>;\n readonly enrollmentUserVerified: PasskeyColumn<T>;\n readonly backupEligible: PasskeyColumn<T>;\n readonly backupState: PasskeyColumn<T>;\n readonly counter: PasskeyColumn<T>;\n readonly maximumCounter: PasskeyColumn<T>;\n readonly decode: (\n row: Readonly<Partial<T[\"select\"]>>,\n ) => Omit<PasskeyCredential, \"revision\" | \"active\">;\n readonly decodeSubjectId: (row: Readonly<Partial<T[\"select\"]>>) => N;\n readonly isActiveStatus: (value: unknown) => boolean;\n readonly activeCondition: Expression;\n}\n\nexport interface PasskeyCredentialOwnershipTable<\n T extends Table,\n N,\n Expression extends SqlExpression = SqlExpression,\n> {\n readonly table: T[\"table\"];\n readonly credentialKey: PasskeyColumn<T>;\n readonly rpId: PasskeyColumn<T>;\n readonly protocolCredentialId: PasskeyColumn<T>;\n readonly subjectId: PasskeyColumn<T>;\n readonly credentialId: PasskeyColumn<T>;\n readonly state: PasskeyColumn<T>;\n readonly version: PasskeyColumn<T>;\n readonly reservationId: PasskeyColumn<T>;\n readonly ownedCondition: Expression;\n readonly isOwnedState: (value: unknown) => boolean;\n readonly decodeSubjectId: (row: Readonly<Partial<T[\"select\"]>>) => N;\n}\n\n/** Reservations do not manufacture a subject; bound handles are RP-global. */\nexport interface PasskeyHandleReadTable<T extends Table> {\n readonly table: T[\"table\"];\n readonly handleKey: PasskeyColumn<T>;\n readonly rpId: PasskeyColumn<T>;\n readonly userHandle: PasskeyColumn<T>;\n readonly state: PasskeyColumn<T>;\n readonly version: PasskeyColumn<T>;\n readonly reservationId: PasskeyColumn<T>;\n}\n\nexport interface PasskeyHandleReservationTable<\n T extends Table,\n Expression extends SqlExpression = SqlExpression,\n> extends PasskeyHandleReadTable<T> {\n readonly reservedCondition: Expression;\n readonly isReservedState: (value: unknown) => boolean;\n}\n\nexport interface PasskeyHandleOwnershipTable<\n T extends Table,\n N,\n Expression extends SqlExpression = SqlExpression,\n> extends PasskeyHandleReadTable<T> {\n readonly subjectId: PasskeyColumn<T>;\n readonly ownedCondition: Expression;\n readonly isOwnedState: (value: unknown) => boolean;\n readonly decodeSubjectId: (row: Readonly<Partial<T[\"select\"]>>) => N;\n}\n\nexport const requiredPasskeyCredentialConstraints = {\n credentialId: [\"credentialId\"],\n factor: [\"subjectId\", \"credentialId\"],\n credentialOwnership: [\"credentialKey\"],\n handleOwnership: [\"handleKey\"],\n boundSubjectHandle: [\"rpId\", \"subjectId\"],\n} as const;\n\nexport interface PasskeyCredentialMapping<\n S extends Table,\n C extends Table,\n F extends Table,\n Ownership extends Table,\n Handle extends Table,\n N,\n Expression extends SqlExpression = SqlExpression,\n> {\n readonly subject: PasskeySubjectReadTable<S, N, Expression>;\n readonly credential: PasskeyCredentialReadTable<C, N, Expression>;\n readonly authority: PasskeyFactorReadTable<F, Expression>;\n readonly credentialOwnership: PasskeyCredentialOwnershipTable<Ownership, N, Expression>;\n readonly handleOwnership: PasskeyHandleOwnershipTable<Handle, N, Expression>;\n readonly subjectIds: PasskeySubjectIdCodec<N>;\n readonly constraints: typeof requiredPasskeyCredentialConstraints;\n}\n\n/** A stable additional policy row, acquired before RP/credential locks. The\n * factory checks column names without erasing the consumer table at its input. */\nconst PasskeyPolicyGuardTypeId: unique symbol = Symbol(\"effect-auth/drizzle/PasskeyPolicyGuard\");\n\nexport interface PasskeyPolicyGuard<Expression extends SqlExpression = SqlExpression> {\n readonly [PasskeyPolicyGuardTypeId]: true;\n readonly scope: string;\n readonly table: object;\n readonly columns: ReadonlyArray<string>;\n readonly where: (moduleId: string) => Expression;\n readonly condition: (moduleId: string) => Expression;\n}\n\nexport const passkeyPolicyGuard = <\n T extends Table,\n Expression extends SqlExpression = SqlExpression,\n>(input: {\n readonly scope: string;\n readonly table: T[\"table\"];\n readonly columns: ReadonlyArray<PasskeyColumn<T>>;\n readonly where: (moduleId: string) => Expression;\n readonly condition: (moduleId: string) => Expression;\n}): PasskeyPolicyGuard<Expression> => ({ ...input, [PasskeyPolicyGuardTypeId]: true });\n\nexport interface PasskeyModuleTable<\n T extends Table,\n Expression extends SqlExpression = SqlExpression,\n> {\n readonly table: T[\"table\"];\n readonly moduleId: PasskeyColumn<T>;\n readonly status: PasskeyColumn<T>;\n readonly policyRevision: PasskeyColumn<T>;\n /** All physical fields used by decodeMethodPolicy, including policyRevision. */\n readonly policyColumns: ReadonlyArray<PasskeyColumn<T>>;\n readonly isActiveStatus: (value: unknown) => boolean;\n readonly activeCondition: Expression;\n readonly decodeMethodPolicy: (row: Readonly<Partial<T[\"select\"]>>) => PasskeyMethodPolicy;\n readonly guards?: ReadonlyArray<PasskeyPolicyGuard<Expression>>;\n}\n\nexport type PasskeyFlowState =\n | \"Pending\"\n | \"Claimed\"\n | \"Verified\"\n | \"Rejected\"\n | \"Ambiguous\"\n | \"RegistrationAccepted\"\n | \"ProvisioningPending\";\n\nexport interface PasskeyFlowInsert {\n readonly ceremony: PasskeyCeremony;\n readonly policy: PasskeyMethodPolicy;\n readonly marker: string;\n}\n\nexport interface PasskeyFlowTable<T extends Table> {\n readonly table: T[\"table\"];\n readonly moduleId: PasskeyColumn<T>;\n readonly flowId: PasskeyColumn<T>;\n readonly commandId: PasskeyColumn<T>;\n readonly purpose: PasskeyColumn<T>;\n readonly state: PasskeyColumn<T>;\n readonly version: PasskeyColumn<T>;\n readonly generation: PasskeyColumn<T>;\n readonly snapshot: PasskeyColumn<T>;\n readonly policySnapshot: PasskeyColumn<T>;\n readonly requestBindingVerifier: PasskeyColumn<T>;\n readonly requestBindingExpiresAt: PasskeyColumn<T>;\n readonly issuedAt: PasskeyColumn<T>;\n readonly expiresAt: PasskeyColumn<T>;\n readonly retentionUntil: PasskeyColumn<T>;\n readonly claimId: PasskeyColumn<T>;\n readonly claimedAt: PasskeyColumn<T>;\n readonly claimExpiresAt: PasskeyColumn<T>;\n readonly credentialSnapshot: PasskeyColumn<T>;\n /** Core SubjectId scope text, not a consumer's native subject ID. */\n readonly subjectScope: PasskeyColumn<T>;\n readonly targetScope: PasskeyColumn<T>;\n readonly states: Readonly<Record<PasskeyFlowState, unknown>>;\n readonly encodeInsert: (input: PasskeyFlowInsert) => T[\"insert\"];\n}\n\nexport interface PasskeyAdmissionTable<T extends Table> {\n readonly table: T[\"table\"];\n readonly authorityScope: PasskeyColumn<T>;\n readonly moduleId: PasskeyColumn<T>;\n readonly version: PasskeyColumn<T>;\n readonly ownerMarker: PasskeyColumn<T>;\n /** One physical clock sample, reused by every charge of this decision. */\n readonly admittedAt: PasskeyColumn<T>;\n}\n\nexport type PasskeyChargeKind = \"global\" | \"subject\" | \"target\";\n\nexport interface PasskeyChargeInsert {\n readonly moduleId: string;\n readonly flowId: string;\n readonly purpose: PasskeyCeremony[\"purpose\"];\n readonly kind: PasskeyChargeKind;\n readonly scope: string;\n readonly originalWindowMillis: number;\n readonly marker: string;\n}\n\n/** Charge scope is canonical core identity text; this subject-free descriptor\n * can count all purposes without decoding any unrelated native subject. */\nexport interface PasskeyChargeTable<T extends Table> {\n readonly table: T[\"table\"];\n readonly moduleId: PasskeyColumn<T>;\n readonly flowId: PasskeyColumn<T>;\n readonly purpose: PasskeyColumn<T>;\n readonly kind: PasskeyColumn<T>;\n readonly scope: PasskeyColumn<T>;\n readonly originalWindowMillis: PasskeyColumn<T>;\n readonly admittedAt: PasskeyColumn<T>;\n readonly retainUntil: PasskeyColumn<T>;\n readonly version: PasskeyColumn<T>;\n readonly ownerMarker: PasskeyColumn<T>;\n readonly encodeInsert: (input: PasskeyChargeInsert) => T[\"insert\"];\n}\n\nexport const requiredPasskeyPersistenceConstraints = {\n flow: [\"moduleId\", \"flowId\"],\n command: [\"moduleId\", \"commandId\"],\n admission: [\"authorityScope\", \"moduleId\"],\n charge: [\"moduleId\", \"flowId\", \"kind\"],\n} as const;\n\nexport interface PasskeyCeremonyMapping<\n Module extends Table,\n Flow extends Table,\n Admission extends Table,\n Charge extends Table,\n Expression extends SqlExpression = SqlExpression,\n> {\n readonly moduleId: string;\n readonly authorityScope: string;\n readonly module: PasskeyModuleTable<Module, Expression>;\n readonly flow: PasskeyFlowTable<Flow>;\n readonly admission: PasskeyAdmissionTable<Admission>;\n readonly charge: PasskeyChargeTable<Charge>;\n readonly clock: PasskeyClock<Expression>;\n readonly constraints: typeof requiredPasskeyPersistenceConstraints;\n}\n\nexport interface PasskeyPersistenceMapping<\n Read,\n Module extends Table,\n Flow extends Table,\n Admission extends Table,\n Charge extends Table,\n N,\n Expression extends SqlExpression = SqlExpression,\n Credential extends Table = Table,\n> extends PasskeyCeremonyMapping<Module, Flow, Admission, Charge, Expression> {\n readonly read: Read & {\n readonly subjectIds: PasskeySubjectIdCodec<N>;\n };\n readonly telemetry: {\n readonly lastUsedAt: PasskeyColumn<Credential>;\n readonly encodeBackupState: (value: boolean) => unknown;\n };\n}\n\nexport interface PasskeyEnrollmentContextMapping<\n Read,\n Module extends Table,\n N,\n Expression extends SqlExpression = SqlExpression,\n> {\n readonly moduleId: string;\n readonly read: Read & {\n readonly subjectIds: PasskeySubjectIdCodec<N>;\n };\n readonly module: PasskeyModuleTable<Module, Expression>;\n}\n\nexport interface D1PasskeyMapping {\n readonly d1: {\n readonly primary: true;\n };\n}\n"],"mappings":";;;AAgCA,MAAa,2BACX,aAEA,MAAM,OACJ,oBACA,OAAO,IAAI,WAAW,UAAU,MAAM,kBAAkB,CAC1D;AAEF,MAAa,2BACX,aAEA,MAAM,OACJ,oBACA,OAAO,IAAI,WAAW,UAAU,MAAM,kBAAkB,CAC1D;AAEF,MAAa,iCACX,aAEA,MAAM,OACJ,0BACA,OAAO,IAAI,WAAW,UAAU,MAAM,wBAAwB,CAChE;AAgIF,MAAa,uCAAuC;CAClD,cAAc,CAAC,cAAc;CAC7B,QAAQ,CAAC,aAAa,cAAc;CACpC,qBAAqB,CAAC,eAAe;CACrC,iBAAiB,CAAC,WAAW;CAC7B,oBAAoB,CAAC,QAAQ,WAAW;AAC1C;;;AAsBA,MAAM,2BAA0C,OAAO,wCAAwC;AAW/F,MAAa,sBAGX,WAMqC;CAAE,GAAG;EAAQ,2BAA2B;AAAK;AAmGpF,MAAa,wCAAwC;CACnD,MAAM,CAAC,YAAY,QAAQ;CAC3B,SAAS,CAAC,YAAY,WAAW;CACjC,WAAW,CAAC,kBAAkB,UAAU;CACxC,QAAQ;EAAC;EAAY;EAAU;CAAM;AACvC"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import { SqlExpression, TableModel } from "../query-operations.mjs";
|
|
2
|
+
import { PasskeyCeremonyMapping, PasskeyChargeTable, PasskeyColumn, PasskeyFlowTable, PasskeyHandleReservationTable, PasskeyPersistenceServices } from "./passkey-model.mjs";
|
|
3
|
+
//#region src/internal/models/passkey-registration-ceremony-model.d.ts
|
|
4
|
+
export interface PasskeyRegistrationCeremonyCapabilities {
|
|
5
|
+
readonly purposes: readonly ["registration"];
|
|
6
|
+
readonly issue: "registration-authority";
|
|
7
|
+
readonly assertionSettlement: false;
|
|
8
|
+
}
|
|
9
|
+
export interface PasskeyRegistrationCeremonyServices extends PasskeyPersistenceServices {
|
|
10
|
+
readonly capabilities: PasskeyRegistrationCeremonyCapabilities;
|
|
11
|
+
}
|
|
12
|
+
/** Read-only custody supplied by a separate registration issuance authority.
|
|
13
|
+
* No application payload codec, subject codec or provisioning callback runs here. */
|
|
14
|
+
export interface PasskeyRegistrationIntentReadTable<T extends TableModel, Expression extends SqlExpression = SqlExpression> {
|
|
15
|
+
readonly table: T["table"];
|
|
16
|
+
readonly moduleId: PasskeyColumn<T>;
|
|
17
|
+
readonly flowId: PasskeyColumn<T>;
|
|
18
|
+
readonly commandId: PasskeyColumn<T>;
|
|
19
|
+
readonly state: PasskeyColumn<T>;
|
|
20
|
+
readonly version: PasskeyColumn<T>;
|
|
21
|
+
readonly fingerprint: PasskeyColumn<T>;
|
|
22
|
+
readonly handleKey: PasskeyColumn<T>;
|
|
23
|
+
readonly reservationId: PasskeyColumn<T>;
|
|
24
|
+
readonly ceremonySnapshot: PasskeyColumn<T>;
|
|
25
|
+
/** Already validated by the issuing authority; compare opaque bytes only. */
|
|
26
|
+
readonly applicationSnapshot: PasskeyColumn<T>;
|
|
27
|
+
readonly pendingCondition: Expression;
|
|
28
|
+
readonly isPendingState: (value: unknown) => boolean;
|
|
29
|
+
/** Any unresolved initial intent or provisioning job; cleanup never releases it. */
|
|
30
|
+
readonly custodyCondition: Expression;
|
|
31
|
+
}
|
|
32
|
+
export declare const requiredPasskeyRegistrationCeremonyConstraints: {
|
|
33
|
+
readonly flow: readonly ["moduleId", "flowId"];
|
|
34
|
+
readonly command: readonly ["moduleId", "commandId"];
|
|
35
|
+
readonly admission: readonly ["authorityScope", "moduleId"];
|
|
36
|
+
readonly charge: readonly ["moduleId", "flowId", "kind"];
|
|
37
|
+
readonly intentFlow: readonly ["moduleId", "flowId"];
|
|
38
|
+
readonly intentCommand: readonly ["moduleId", "commandId"];
|
|
39
|
+
readonly handle: readonly ["handleKey"];
|
|
40
|
+
};
|
|
41
|
+
export interface PasskeyRegistrationCeremonyMapping<Module extends TableModel, Flow extends TableModel, Admission extends TableModel, Charge extends TableModel, Intent extends TableModel, Handle extends TableModel, Expression extends SqlExpression = SqlExpression> extends Omit<PasskeyCeremonyMapping<Module, Flow, Admission, Charge, Expression>, "constraints" | "flow" | "charge"> {
|
|
42
|
+
readonly flow: Omit<PasskeyFlowTable<Flow>, "encodeInsert">;
|
|
43
|
+
readonly charge: Omit<PasskeyChargeTable<Charge>, "encodeInsert">;
|
|
44
|
+
readonly intent: PasskeyRegistrationIntentReadTable<Intent, Expression>;
|
|
45
|
+
readonly handle: PasskeyHandleReservationTable<Handle, Expression>;
|
|
46
|
+
readonly constraints: typeof requiredPasskeyRegistrationCeremonyConstraints;
|
|
47
|
+
}
|
|
48
|
+
//#endregion
|
|
49
|
+
//# sourceMappingURL=passkey-registration-ceremony-model.d.mts.map
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
//#region src/internal/models/passkey-registration-ceremony-model.ts
|
|
2
|
+
const requiredPasskeyRegistrationCeremonyConstraints = {
|
|
3
|
+
flow: ["moduleId", "flowId"],
|
|
4
|
+
command: ["moduleId", "commandId"],
|
|
5
|
+
admission: ["authorityScope", "moduleId"],
|
|
6
|
+
charge: [
|
|
7
|
+
"moduleId",
|
|
8
|
+
"flowId",
|
|
9
|
+
"kind"
|
|
10
|
+
],
|
|
11
|
+
intentFlow: ["moduleId", "flowId"],
|
|
12
|
+
intentCommand: ["moduleId", "commandId"],
|
|
13
|
+
handle: ["handleKey"]
|
|
14
|
+
};
|
|
15
|
+
//#endregion
|
|
16
|
+
export { requiredPasskeyRegistrationCeremonyConstraints };
|
|
17
|
+
|
|
18
|
+
//# sourceMappingURL=passkey-registration-ceremony-model.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"passkey-registration-ceremony-model.mjs","names":[],"sources":["../../../src/internal/models/passkey-registration-ceremony-model.ts"],"sourcesContent":["import type { TableModel as Table, SqlExpression } from \"../query-operations\";\nimport type {\n PasskeyCeremonyMapping,\n PasskeyChargeTable,\n PasskeyColumn,\n PasskeyFlowTable,\n PasskeyHandleReservationTable,\n PasskeyPersistenceServices,\n} from \"./passkey-model\";\n\nexport interface PasskeyRegistrationCeremonyCapabilities {\n readonly purposes: readonly [\"registration\"];\n readonly issue: \"registration-authority\";\n readonly assertionSettlement: false;\n}\n\nexport interface PasskeyRegistrationCeremonyServices extends PasskeyPersistenceServices {\n readonly capabilities: PasskeyRegistrationCeremonyCapabilities;\n}\n\n/** Read-only custody supplied by a separate registration issuance authority.\n * No application payload codec, subject codec or provisioning callback runs here. */\nexport interface PasskeyRegistrationIntentReadTable<\n T extends Table,\n Expression extends SqlExpression = SqlExpression,\n> {\n readonly table: T[\"table\"];\n readonly moduleId: PasskeyColumn<T>;\n readonly flowId: PasskeyColumn<T>;\n readonly commandId: PasskeyColumn<T>;\n readonly state: PasskeyColumn<T>;\n readonly version: PasskeyColumn<T>;\n readonly fingerprint: PasskeyColumn<T>;\n readonly handleKey: PasskeyColumn<T>;\n readonly reservationId: PasskeyColumn<T>;\n readonly ceremonySnapshot: PasskeyColumn<T>;\n /** Already validated by the issuing authority; compare opaque bytes only. */\n readonly applicationSnapshot: PasskeyColumn<T>;\n readonly pendingCondition: Expression;\n readonly isPendingState: (value: unknown) => boolean;\n /** Any unresolved initial intent or provisioning job; cleanup never releases it. */\n readonly custodyCondition: Expression;\n}\n\nexport const requiredPasskeyRegistrationCeremonyConstraints = {\n flow: [\"moduleId\", \"flowId\"],\n command: [\"moduleId\", \"commandId\"],\n admission: [\"authorityScope\", \"moduleId\"],\n charge: [\"moduleId\", \"flowId\", \"kind\"],\n intentFlow: [\"moduleId\", \"flowId\"],\n intentCommand: [\"moduleId\", \"commandId\"],\n handle: [\"handleKey\"],\n} as const;\n\nexport interface PasskeyRegistrationCeremonyMapping<\n Module extends Table,\n Flow extends Table,\n Admission extends Table,\n Charge extends Table,\n Intent extends Table,\n Handle extends Table,\n Expression extends SqlExpression = SqlExpression,\n> extends Omit<\n PasskeyCeremonyMapping<Module, Flow, Admission, Charge, Expression>,\n \"constraints\" | \"flow\" | \"charge\"\n> {\n readonly flow: Omit<PasskeyFlowTable<Flow>, \"encodeInsert\">;\n readonly charge: Omit<PasskeyChargeTable<Charge>, \"encodeInsert\">;\n readonly intent: PasskeyRegistrationIntentReadTable<Intent, Expression>;\n readonly handle: PasskeyHandleReservationTable<Handle, Expression>;\n readonly constraints: typeof requiredPasskeyRegistrationCeremonyConstraints;\n}\n"],"mappings":";AA4CA,MAAa,iDAAiD;CAC5D,MAAM,CAAC,YAAY,QAAQ;CAC3B,SAAS,CAAC,YAAY,WAAW;CACjC,WAAW,CAAC,kBAAkB,UAAU;CACxC,QAAQ;EAAC;EAAY;EAAU;CAAM;CACrC,YAAY,CAAC,YAAY,QAAQ;CACjC,eAAe,CAAC,YAAY,WAAW;CACvC,QAAQ,CAAC,WAAW;AACtB"}
|