@yielded/auth-persistence-drizzle 0.1.0-beta.23 → 0.1.0-beta.24
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 +3 -0
- package/dist/D1.d.mts +9 -9
- package/dist/D1.mjs +2 -1
- package/dist/D1.mjs.map +1 -1
- package/dist/Libsql.d.mts +46 -62
- package/dist/Libsql.mjs +2 -1
- package/dist/Libsql.mjs.map +1 -1
- package/dist/Mysql2.d.mts +24 -25
- package/dist/Pglite.d.mts +26 -26
- package/dist/Pglite.mjs +2 -1
- package/dist/Pglite.mjs.map +1 -1
- package/dist/Postgres.d.mts +27 -27
- package/dist/Postgres.mjs +2 -1
- package/dist/Postgres.mjs.map +1 -1
- package/dist/SqliteBun.d.mts +47 -63
- package/dist/SqliteBun.mjs +2 -1
- package/dist/SqliteBun.mjs.map +1 -1
- package/dist/SqliteDo.d.mts +45 -61
- package/dist/SqliteDo.mjs +2 -1
- package/dist/SqliteDo.mjs.map +1 -1
- package/dist/SqliteNode.d.mts +49 -65
- package/dist/SqliteNode.mjs +2 -1
- package/dist/SqliteNode.mjs.map +1 -1
- package/dist/SqliteWasm.d.mts +45 -61
- package/dist/SqliteWasm.mjs +2 -1
- package/dist/SqliteWasm.mjs.map +1 -1
- package/dist/drizzle/crypto.mjs +1 -1
- package/dist/drizzle/d1-emails.d.mts +1 -1
- package/dist/drizzle/d1-oauth.d.mts +13 -13
- package/dist/drizzle/d1-passkey.d.mts +1 -1
- package/dist/drizzle/d1-password-prepared.d.mts +4 -4
- package/dist/drizzle/d1-password-prepared.mjs.map +1 -1
- package/dist/drizzle/d1-passwords.d.mts +17 -33
- package/dist/drizzle/d1-passwords.mjs +56 -198
- package/dist/drizzle/d1-passwords.mjs.map +1 -1
- package/dist/drizzle/d1-phone.d.mts +1 -1
- package/dist/drizzle/d1-proofs.d.mts +1 -1
- package/dist/drizzle/d1-sessions.d.mts +2 -2
- package/dist/drizzle/d1-sessions.mjs +11 -6
- package/dist/drizzle/d1-sessions.mjs.map +1 -1
- package/dist/drizzle/d1-totp.d.mts +1 -1
- package/dist/drizzle/mysql-password-prepared.d.mts +5 -5
- package/dist/drizzle/mysql-password-prepared.mjs.map +1 -1
- package/dist/drizzle/mysql-passwords.d.mts +16 -32
- package/dist/drizzle/mysql-passwords.mjs.map +1 -1
- package/dist/drizzle/mysql-sessions.d.mts +1 -1
- package/dist/drizzle/native-sql-table.mjs +26 -1
- package/dist/drizzle/native-sql-table.mjs.map +1 -1
- package/dist/drizzle/oauth-connected-model.d.mts +20 -281
- package/dist/drizzle/oauth-connected-model.mjs +3 -17
- package/dist/drizzle/oauth-connected-model.mjs.map +1 -1
- package/dist/drizzle/oauth-connected-reference.d.mts +1 -3
- package/dist/drizzle/oauth-connected-reference.mjs +4 -53
- package/dist/drizzle/oauth-connected-reference.mjs.map +1 -1
- package/dist/drizzle/oauth-connected-target.d.mts +3 -990
- package/dist/drizzle/oauth-connected-target.mjs +8 -92
- package/dist/drizzle/oauth-connected-target.mjs.map +1 -1
- package/dist/drizzle/oauth-kernel.mjs +11 -0
- package/dist/drizzle/oauth-kernel.mjs.map +1 -0
- package/dist/drizzle/oauth-model.d.mts +35 -438
- package/dist/drizzle/oauth-model.mjs +6 -44
- package/dist/drizzle/oauth-model.mjs.map +1 -1
- package/dist/drizzle/oauth-mysql.mjs +2 -2
- package/dist/drizzle/oauth-mysql.mjs.map +1 -1
- package/dist/drizzle/oauth-proxy.d.mts +10 -0
- package/dist/drizzle/oauth-proxy.mjs +54 -0
- package/dist/drizzle/oauth-proxy.mjs.map +1 -0
- package/dist/drizzle/oauth-target.d.mts +6 -107
- package/dist/drizzle/oauth-target.mjs +15 -245
- package/dist/drizzle/oauth-target.mjs.map +1 -1
- package/dist/drizzle/password-model.d.mts +5 -6
- package/dist/drizzle/password-prepared-model.d.mts +5 -5
- package/dist/drizzle/password-prepared-model.mjs.map +1 -1
- package/dist/drizzle/password-prepared-state.mjs +1 -1
- package/dist/drizzle/pg-password-prepared.d.mts +5 -5
- package/dist/drizzle/pg-password-prepared.mjs.map +1 -1
- package/dist/drizzle/pg-passwords.d.mts +16 -32
- package/dist/drizzle/pg-passwords.mjs.map +1 -1
- package/dist/drizzle/pg-sessions.d.mts +1 -1
- package/dist/drizzle/phone-target.d.mts +1 -1
- package/dist/drizzle/phone-target.mjs +1 -1
- package/dist/drizzle/query-operations.mjs +3 -1
- package/dist/drizzle/query-operations.mjs.map +1 -1
- package/dist/drizzle/sqlite-password-prepared.mjs.map +1 -1
- package/dist/drizzle/sqlite-passwords.mjs.map +1 -1
- package/dist/drizzle/storage-validation.mjs +10 -185
- package/dist/drizzle/storage-validation.mjs.map +1 -1
- package/dist/drizzle/totp-target.d.mts +2 -2
- package/dist/drizzle/totp-target.mjs +2 -2
- package/dist/drizzle/transaction-execution.d.mts +2 -2
- package/dist/drizzle/transaction-owner.d.mts +1 -2
- package/dist/index.d.mts +3 -2
- package/dist/internal/drizzle-postgres-oauth-proxy.d.mts +138 -0
- package/dist/internal/drizzle-postgres-oauth-proxy.mjs +29 -0
- package/dist/internal/drizzle-postgres-oauth-proxy.mjs.map +1 -0
- package/dist/internal/drizzle-sqlite-oauth-proxy.d.mts +146 -0
- package/dist/internal/drizzle-sqlite-oauth-proxy.mjs +29 -0
- package/dist/internal/drizzle-sqlite-oauth-proxy.mjs.map +1 -0
- package/package.json +1 -1
- package/src/D1.ts +2 -0
- package/src/Libsql.ts +2 -0
- package/src/Pglite.ts +2 -0
- package/src/Postgres.ts +2 -0
- package/src/SqliteBun.ts +2 -0
- package/src/SqliteDo.ts +2 -0
- package/src/SqliteNode.ts +2 -0
- package/src/SqliteWasm.ts +2 -0
- package/src/drizzle/d1-password-prepared.ts +2 -5
- package/src/drizzle/d1-passwords.ts +123 -458
- package/src/drizzle/d1-sessions.ts +21 -6
- package/src/drizzle/mysql-password-prepared.ts +4 -8
- package/src/drizzle/mysql-passwords.ts +5 -10
- package/src/drizzle/native-sql-table.ts +30 -0
- package/src/drizzle/oauth-connected-model.ts +97 -315
- package/src/drizzle/oauth-connected-reference.ts +13 -93
- package/src/drizzle/oauth-connected-target.ts +14 -271
- package/src/drizzle/oauth-kernel.ts +10 -0
- package/src/drizzle/oauth-model.ts +188 -541
- package/src/drizzle/oauth-mysql.ts +2 -2
- package/src/drizzle/oauth-proxy.ts +101 -0
- package/src/drizzle/oauth-target.ts +33 -737
- package/src/drizzle/password-model.ts +0 -13
- package/src/drizzle/password-prepared-model.ts +0 -6
- package/src/drizzle/pg-password-prepared.ts +4 -8
- package/src/drizzle/pg-passwords.ts +5 -10
- package/src/drizzle/query-operations.ts +4 -0
- package/src/drizzle/sqlite-password-prepared.ts +4 -8
- package/src/drizzle/sqlite-passwords.ts +7 -14
- package/src/drizzle/storage-validation.ts +13 -214
- package/src/index.ts +2 -4
- package/src/internal/drizzle-postgres-oauth-proxy.ts +37 -0
- package/src/internal/drizzle-sqlite-oauth-proxy.ts +44 -0
- package/dist/_virtual/_rolldown/runtime.mjs +0 -13
- package/dist/drizzle/oauth-accounts.mjs +0 -359
- package/dist/drizzle/oauth-accounts.mjs.map +0 -1
- package/dist/drizzle/oauth-connected-access.mjs +0 -212
- package/dist/drizzle/oauth-connected-access.mjs.map +0 -1
- package/dist/drizzle/oauth-connected-collection.mjs +0 -202
- package/dist/drizzle/oauth-connected-collection.mjs.map +0 -1
- package/dist/drizzle/oauth-connected-custody.mjs +0 -147
- package/dist/drizzle/oauth-connected-custody.mjs.map +0 -1
- package/dist/drizzle/oauth-connected-flow.mjs +0 -297
- package/dist/drizzle/oauth-connected-flow.mjs.map +0 -1
- package/dist/drizzle/oauth-connected-input.mjs +0 -122
- package/dist/drizzle/oauth-connected-input.mjs.map +0 -1
- package/dist/drizzle/oauth-connected-maintenance.mjs +0 -214
- package/dist/drizzle/oauth-connected-maintenance.mjs.map +0 -1
- package/dist/drizzle/oauth-connected-management.mjs +0 -229
- package/dist/drizzle/oauth-connected-management.mjs.map +0 -1
- package/dist/drizzle/oauth-connected-settlement.mjs +0 -128
- package/dist/drizzle/oauth-connected-settlement.mjs.map +0 -1
- package/dist/drizzle/oauth-connected-sign-in.mjs +0 -265
- package/dist/drizzle/oauth-connected-sign-in.mjs.map +0 -1
- package/dist/drizzle/oauth-connected-state.d.mts +0 -2062
- package/dist/drizzle/oauth-connected-state.mjs +0 -430
- package/dist/drizzle/oauth-connected-state.mjs.map +0 -1
- package/dist/drizzle/oauth-flow.d.mts +0 -22
- package/dist/drizzle/oauth-flow.mjs +0 -253
- package/dist/drizzle/oauth-flow.mjs.map +0 -1
- package/dist/drizzle/oauth-input.mjs +0 -127
- package/dist/drizzle/oauth-input.mjs.map +0 -1
- package/dist/drizzle/oauth-owner.d.mts +0 -10
- package/dist/drizzle/oauth-owner.mjs +0 -10
- package/dist/drizzle/oauth-owner.mjs.map +0 -1
- package/dist/drizzle/oauth-registration.d.mts +0 -5
- package/dist/drizzle/oauth-registration.mjs +0 -374
- package/dist/drizzle/oauth-registration.mjs.map +0 -1
- package/dist/drizzle/oauth-state.mjs +0 -107
- package/dist/drizzle/oauth-state.mjs.map +0 -1
- package/src/drizzle/oauth-accounts.ts +0 -805
- package/src/drizzle/oauth-connected-access.ts +0 -361
- package/src/drizzle/oauth-connected-collection.ts +0 -324
- package/src/drizzle/oauth-connected-custody.ts +0 -279
- package/src/drizzle/oauth-connected-flow.ts +0 -529
- package/src/drizzle/oauth-connected-input.ts +0 -147
- package/src/drizzle/oauth-connected-maintenance.ts +0 -346
- package/src/drizzle/oauth-connected-management.ts +0 -365
- package/src/drizzle/oauth-connected-settlement.ts +0 -251
- package/src/drizzle/oauth-connected-sign-in.ts +0 -443
- package/src/drizzle/oauth-connected-state.ts +0 -872
- package/src/drizzle/oauth-flow.ts +0 -462
- package/src/drizzle/oauth-input.ts +0 -201
- package/src/drizzle/oauth-owner.ts +0 -29
- package/src/drizzle/oauth-registration.ts +0 -640
- package/src/drizzle/oauth-state.ts +0 -218
|
@@ -16,6 +16,7 @@ import {
|
|
|
16
16
|
} from "@yielded/auth/Hooks";
|
|
17
17
|
import type { LoginIdentifier } from "@yielded/auth/Identity";
|
|
18
18
|
import {
|
|
19
|
+
EncodedPasswordHash,
|
|
19
20
|
PasswordUnavailable,
|
|
20
21
|
PasswordPersistence,
|
|
21
22
|
type PasswordMutationInput,
|
|
@@ -24,11 +25,7 @@ import {
|
|
|
24
25
|
snapshotPasswordRequirement,
|
|
25
26
|
snapshotPasswordRevision,
|
|
26
27
|
type PasswordAction,
|
|
27
|
-
type PasswordAttemptDecision,
|
|
28
|
-
type PasswordCredentialSnapshot,
|
|
29
28
|
type PasswordMutationDecision,
|
|
30
|
-
type PasswordAttemptPreparation,
|
|
31
|
-
type PasswordAttemptAdmission,
|
|
32
29
|
} from "@yielded/auth/Password";
|
|
33
30
|
import { reportPersistenceFailure } from "@yielded/auth/Persistence";
|
|
34
31
|
import {
|
|
@@ -43,7 +40,16 @@ import {
|
|
|
43
40
|
AuthenticationRequirement,
|
|
44
41
|
type SecurityRevision,
|
|
45
42
|
} from "@yielded/auth/Sessions";
|
|
46
|
-
import {
|
|
43
|
+
import {
|
|
44
|
+
and,
|
|
45
|
+
eq,
|
|
46
|
+
getTableColumns,
|
|
47
|
+
inArray,
|
|
48
|
+
sql,
|
|
49
|
+
type AnyRelations,
|
|
50
|
+
type SQL,
|
|
51
|
+
type Table,
|
|
52
|
+
} from "drizzle-orm";
|
|
47
53
|
import type { EffectSQLiteD1Database } from "drizzle-orm/effect-d1";
|
|
48
54
|
import type { AnySQLiteTable } from "drizzle-orm/sqlite-core";
|
|
49
55
|
import { Cause, DateTime, Effect, Option, Predicate, Redacted, Schema, Context } from "effect";
|
|
@@ -59,7 +65,6 @@ import { nativeDatabase } from "./native-database";
|
|
|
59
65
|
import {
|
|
60
66
|
type AnyPasswordRegistrationMapping,
|
|
61
67
|
type D1PasswordPersistenceMapping,
|
|
62
|
-
type PasswordAttemptRecord,
|
|
63
68
|
type PasswordRegistrationMapping,
|
|
64
69
|
requiredPasswordConstraints,
|
|
65
70
|
requiredPasswordRegistrationConstraints,
|
|
@@ -75,7 +80,7 @@ type PlanPrepare<Method extends (...args: any[]) => any, A> = (
|
|
|
75
80
|
) => PreparedCommit<A>;
|
|
76
81
|
|
|
77
82
|
type Database = EffectSQLiteD1Database<AnyRelations> & { readonly $client: D1Client };
|
|
78
|
-
type Mapping = D1PasswordPersistenceMapping<Table, Table, Table, Table, Table,
|
|
83
|
+
type Mapping = D1PasswordPersistenceMapping<Table, Table, Table, Table, Table, unknown>;
|
|
79
84
|
type RegistrationMapping<Registration> = AnyPasswordRegistrationMapping<Registration>;
|
|
80
85
|
|
|
81
86
|
interface Planned<A> {
|
|
@@ -189,11 +194,6 @@ const readEngineNowMillis = Effect.fn("Drizzle.readEngineNowMillis")(function* (
|
|
|
189
194
|
);
|
|
190
195
|
});
|
|
191
196
|
|
|
192
|
-
const driverValues = (values: object, entries: ReadonlyArray<readonly [string, unknown]>) => ({
|
|
193
|
-
...values,
|
|
194
|
-
...Object.fromEntries(entries),
|
|
195
|
-
});
|
|
196
|
-
|
|
197
197
|
const allocate = <A>(
|
|
198
198
|
asyncValue: Effect.Effect<A, PersistenceMappingError> | undefined,
|
|
199
199
|
syncValue: (() => A) | undefined,
|
|
@@ -249,27 +249,6 @@ const authorityColumns = (mapping: Mapping) => ({
|
|
|
249
249
|
: column(mapping.authorityCredential.table, mapping.authorityCredential.status),
|
|
250
250
|
});
|
|
251
251
|
|
|
252
|
-
const attemptColumns = (mapping: Mapping) => ({
|
|
253
|
-
moduleId: column(mapping.attempt.table, mapping.attempt.moduleId),
|
|
254
|
-
action: column(mapping.attempt.table, mapping.attempt.action),
|
|
255
|
-
attemptId: column(mapping.attempt.table, mapping.attempt.attemptId),
|
|
256
|
-
identifierNamespace: column(mapping.attempt.table, mapping.attempt.identifierNamespace),
|
|
257
|
-
identifierValue: column(mapping.attempt.table, mapping.attempt.identifierValue),
|
|
258
|
-
subjectId: column(mapping.attempt.table, mapping.attempt.subjectId),
|
|
259
|
-
credentialId: column(mapping.attempt.table, mapping.attempt.credentialId),
|
|
260
|
-
securityRevision: column(mapping.attempt.table, mapping.attempt.securityRevision),
|
|
261
|
-
credentialRevision: column(mapping.attempt.table, mapping.attempt.credentialRevision),
|
|
262
|
-
verifierVersion: column(mapping.attempt.table, mapping.attempt.verifierVersion),
|
|
263
|
-
identifierBindingRevision: column(
|
|
264
|
-
mapping.attempt.table,
|
|
265
|
-
mapping.attempt.identifierBindingRevision,
|
|
266
|
-
),
|
|
267
|
-
admittedAt: column(mapping.attempt.table, mapping.attempt.admittedAt),
|
|
268
|
-
deadline: column(mapping.attempt.table, mapping.attempt.deadline),
|
|
269
|
-
retentionUntil: column(mapping.attempt.table, mapping.attempt.retentionUntil),
|
|
270
|
-
state: column(mapping.attempt.table, mapping.attempt.state),
|
|
271
|
-
});
|
|
272
|
-
|
|
273
252
|
const commandColumns = (mapping: Mapping) => ({
|
|
274
253
|
moduleId: column(mapping.command.table, mapping.command.moduleId),
|
|
275
254
|
commandId: column(mapping.command.table, mapping.command.commandId),
|
|
@@ -323,14 +302,6 @@ const readCredentialNative = Effect.fn("Drizzle.readCredentialNative")(function*
|
|
|
323
302
|
.limit(1);
|
|
324
303
|
});
|
|
325
304
|
|
|
326
|
-
interface Resolved {
|
|
327
|
-
readonly nativeSubjectId: unknown;
|
|
328
|
-
readonly subject: any;
|
|
329
|
-
readonly identifier: any;
|
|
330
|
-
readonly credential?: any;
|
|
331
|
-
readonly snapshot?: PasswordCredentialSnapshot;
|
|
332
|
-
}
|
|
333
|
-
|
|
334
305
|
const resolveCredential = Effect.fn("DrizzleD1Password.resolveCredential")(function* (
|
|
335
306
|
mapping: Mapping,
|
|
336
307
|
moduleId: string,
|
|
@@ -741,34 +712,6 @@ const credentialCurrentCondition = (
|
|
|
741
712
|
: sql`exists(select 1 from ${mapping.credential.table} where ${c.moduleId} = ${sql.param(input.moduleId, c.moduleId)} and ${c.subjectId} = ${sql.param(nativeSubjectId, c.subjectId)} and ${c.credentialId} = ${sql.param(input.credential.credentialId, c.credentialId)} and ${c.credentialRevision} = ${sql.param(input.credential.credentialRevision, c.credentialRevision)} and ${c.verifierVersion} = ${sql.param(input.credential.verifierVersion, c.verifierVersion)} and ${c.verifier} = ${sql.param(Redacted.value(input.credential.verifier), c.verifier)} and ${c.normalization} = ${sql.param(input.credential.normalization, c.normalization)})`;
|
|
742
713
|
};
|
|
743
714
|
|
|
744
|
-
const admittedSnapshotCondition = (
|
|
745
|
-
mapping: Mapping,
|
|
746
|
-
resolved: Resolved | undefined,
|
|
747
|
-
moduleId: string,
|
|
748
|
-
) => {
|
|
749
|
-
const snapshot = resolved?.snapshot;
|
|
750
|
-
|
|
751
|
-
if (snapshot === undefined || resolved === undefined) return sql`true`;
|
|
752
|
-
const s = subjectColumns(mapping);
|
|
753
|
-
const i = identifierColumns(mapping);
|
|
754
|
-
const c = credentialColumns(mapping);
|
|
755
|
-
const ac = authorityColumns(mapping);
|
|
756
|
-
|
|
757
|
-
return and(
|
|
758
|
-
sql`exists(select 1 from ${mapping.subject.table} where ${s.id} = ${sql.param(resolved.nativeSubjectId, s.id)} and ${s.status} = ${sql.param(mapping.subject.d1ActiveStatusValue, s.status)} and ${s.securityRevision} = ${sql.param(snapshot.revision.securityRevision, s.securityRevision)})`,
|
|
759
|
-
mapping.identifier.d1CurrentCondition({
|
|
760
|
-
identifier: snapshot.identifier,
|
|
761
|
-
nativeSubjectId: resolved.nativeSubjectId,
|
|
762
|
-
}),
|
|
763
|
-
sql`exists(select 1 from ${mapping.identifier.table} where ${i.namespace} = ${sql.param(snapshot.identifier.namespace, i.namespace)} and ${i.value} = ${sql.param(snapshot.identifier.value, i.value)} and ${i.subjectId} = ${sql.param(resolved.nativeSubjectId, i.subjectId)} and ${i.bindingRevision} = ${sql.param(snapshot.identifierBindingRevision, i.bindingRevision)} and ${Predicate.isNullish(resolved.identifier[mapping.identifier.verifiedAt]) ? sql`${i.verifiedAt} is null` : sql`${i.verifiedAt} = ${sql.param(resolved.identifier[mapping.identifier.verifiedAt], i.verifiedAt)}`})`,
|
|
764
|
-
sql`exists(select 1 from ${mapping.credential.table} where ${c.moduleId} = ${sql.param(moduleId, c.moduleId)} and ${c.subjectId} = ${sql.param(resolved.nativeSubjectId, c.subjectId)} and ${c.credentialId} = ${sql.param(snapshot.credentialId, c.credentialId)} and ${c.credentialRevision} = ${sql.param(snapshot.credentialRevision, c.credentialRevision)} and ${c.verifierVersion} = ${sql.param(snapshot.verifierVersion, c.verifierVersion)} and ${c.verifier} = ${sql.param(Redacted.value(snapshot.verifier), c.verifier)} and ${c.normalization} = ${sql.param(snapshot.normalization, c.normalization)})`,
|
|
765
|
-
...snapshot.revision.credentials.map(
|
|
766
|
-
(item) =>
|
|
767
|
-
sql`exists(select 1 from ${mapping.authorityCredential.table} where ${ac.subjectId} = ${sql.param(resolved.nativeSubjectId, ac.subjectId)} and ${ac.credentialId} = ${sql.param(item.credentialId, ac.credentialId)} and ${ac.revision} = ${sql.param(item.revision, ac.revision)}${ac.status === undefined ? sql`` : sql` and ${ac.status} = ${sql.param(mapping.authorityCredential.d1ActiveStatusValue, ac.status)}`})`,
|
|
768
|
-
),
|
|
769
|
-
)!;
|
|
770
|
-
};
|
|
771
|
-
|
|
772
715
|
const mutationStatements = Effect.fn(function* (
|
|
773
716
|
mapping: Mapping,
|
|
774
717
|
input: PasswordMutationInput,
|
|
@@ -993,312 +936,121 @@ const makePasswordPlans = (
|
|
|
993
936
|
});
|
|
994
937
|
|
|
995
938
|
return {
|
|
996
|
-
|
|
939
|
+
findCredential: (uncaptured: Parameters<PasswordPersistence["Service"]["findCredential"]>[0]) =>
|
|
997
940
|
Effect.gen(function* () {
|
|
998
941
|
if (!validConstraints(mapping)) return yield* unavailable();
|
|
942
|
+
const input = { ...uncaptured, identifier: { ...uncaptured.identifier } };
|
|
943
|
+
const database = yield* CurrentD1PlanningDatabase;
|
|
944
|
+
const identifierRow = (yield* readIdentifier(mapping, input.identifier))[0];
|
|
999
945
|
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
mapping
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
used = true;
|
|
1023
|
-
|
|
1024
|
-
return Effect.void;
|
|
1025
|
-
}),
|
|
1026
|
-
admit: <A>(prepare: PreparePasswordCommit<PasswordAttemptAdmission, A>) =>
|
|
1027
|
-
run(
|
|
1028
|
-
Effect.gen(function* () {
|
|
1029
|
-
const database = yield* CurrentD1PlanningDatabase;
|
|
1030
|
-
const journal = yield* CurrentCommitJournal;
|
|
1031
|
-
const now = yield* readEngineNowMillis(mapping);
|
|
1032
|
-
const marker = `effect-auth-password-guard:admit:${attemptId}`;
|
|
1033
|
-
const a = attemptColumns(mapping);
|
|
1034
|
-
const key = and(eq(a.moduleId, input.moduleId), eq(a.attemptId, attemptId))!;
|
|
1035
|
-
const current = admittedSnapshotCondition(mapping, resolved, input.moduleId);
|
|
1036
|
-
|
|
1037
|
-
const record: PasswordAttemptRecord = {
|
|
1038
|
-
moduleId: input.moduleId,
|
|
1039
|
-
action: input.action,
|
|
1040
|
-
attemptId,
|
|
1041
|
-
identifier: input.identifier,
|
|
1042
|
-
...(snapshot === undefined
|
|
1043
|
-
? {}
|
|
1044
|
-
: {
|
|
1045
|
-
subjectId: snapshot.revision.subjectId,
|
|
1046
|
-
credentialId: snapshot.credentialId,
|
|
1047
|
-
securityRevision: snapshot.revision.securityRevision,
|
|
1048
|
-
credentialRevision: snapshot.credentialRevision,
|
|
1049
|
-
verifierVersion: snapshot.verifierVersion,
|
|
1050
|
-
identifierBindingRevision: snapshot.identifierBindingRevision,
|
|
1051
|
-
}),
|
|
1052
|
-
admittedAtMillis: now,
|
|
1053
|
-
deadlineMillis: now + input.attemptLifetimeMillis,
|
|
1054
|
-
retentionUntilMillis: now + input.attemptLifetimeMillis,
|
|
1055
|
-
};
|
|
1056
|
-
|
|
1057
|
-
const receipt = prepare(
|
|
1058
|
-
{
|
|
1059
|
-
_tag: "Admitted",
|
|
1060
|
-
attemptId,
|
|
1061
|
-
...(snapshot === undefined ? {} : { credential: snapshot }),
|
|
1062
|
-
},
|
|
1063
|
-
journal,
|
|
1064
|
-
);
|
|
1065
|
-
|
|
1066
|
-
const admitted = and(
|
|
1067
|
-
current,
|
|
1068
|
-
sql`exists(select 1 from ${mapping.attempt.table} where ${key} and ${a.state} = ${"pending"} and ${a.deadline} > ${mapping.d1.engineNow})`,
|
|
1069
|
-
)!;
|
|
1070
|
-
|
|
1071
|
-
const statements: Statement<any>[] = [
|
|
1072
|
-
yield* assertion(
|
|
1073
|
-
and(
|
|
1074
|
-
current,
|
|
1075
|
-
sql`not exists(select 1 from ${mapping.attempt.table} where ${key})`,
|
|
1076
|
-
)!,
|
|
1077
|
-
marker,
|
|
1078
|
-
),
|
|
1079
|
-
yield* statement(
|
|
1080
|
-
database.insert(mapping.attempt.table).values(
|
|
1081
|
-
driverValues(
|
|
1082
|
-
mapping.attempt.encodeInsert(record, {
|
|
1083
|
-
...(resolved?.nativeSubjectId === undefined
|
|
1084
|
-
? {}
|
|
1085
|
-
: { nativeSubjectId: resolved.nativeSubjectId }),
|
|
1086
|
-
state: "pending",
|
|
1087
|
-
}),
|
|
1088
|
-
[
|
|
1089
|
-
[mapping.attempt.admittedAt, mapping.d1.engineNow],
|
|
1090
|
-
[
|
|
1091
|
-
mapping.attempt.deadline,
|
|
1092
|
-
mapping.d1.engineInstantPlus(input.attemptLifetimeMillis),
|
|
1093
|
-
],
|
|
1094
|
-
[
|
|
1095
|
-
mapping.attempt.retentionUntil,
|
|
1096
|
-
mapping.d1.engineInstantPlus(input.attemptLifetimeMillis),
|
|
1097
|
-
],
|
|
1098
|
-
],
|
|
1099
|
-
),
|
|
1100
|
-
),
|
|
1101
|
-
),
|
|
1102
|
-
yield* assertion(and(sql`changes() = 1`, admitted)!, marker),
|
|
1103
|
-
];
|
|
1104
|
-
|
|
1105
|
-
// A failed captured-snapshot guard cannot authorize refreshing the
|
|
1106
|
-
// candidate after the strategy has consumed that subject's limit.
|
|
1107
|
-
return {
|
|
1108
|
-
receipt,
|
|
1109
|
-
statements,
|
|
1110
|
-
postconditions: [yield* assertion(admitted, marker)],
|
|
1111
|
-
};
|
|
1112
|
-
}),
|
|
946
|
+
if (identifierRow === undefined || !mapping.identifier.isCurrent(identifierRow))
|
|
947
|
+
return Option.none();
|
|
948
|
+
const nativeId = identifierRow[mapping.identifier.subjectId];
|
|
949
|
+
|
|
950
|
+
const sc = subjectColumns(mapping),
|
|
951
|
+
ic = identifierColumns(mapping),
|
|
952
|
+
cc = credentialColumns(mapping);
|
|
953
|
+
|
|
954
|
+
// Bind the same native ID through each column's codec, then inspect one coherent snapshot.
|
|
955
|
+
const rows = yield* database
|
|
956
|
+
.select({
|
|
957
|
+
subject: getTableColumns(mapping.subject.table),
|
|
958
|
+
identifier: getTableColumns(mapping.identifier.table),
|
|
959
|
+
credential: getTableColumns(mapping.credential.table),
|
|
960
|
+
})
|
|
961
|
+
.from(mapping.subject.table)
|
|
962
|
+
.innerJoin(
|
|
963
|
+
mapping.identifier.table,
|
|
964
|
+
and(
|
|
965
|
+
eq(ic.namespace, input.identifier.namespace),
|
|
966
|
+
eq(ic.value, input.identifier.value),
|
|
967
|
+
eq(ic.subjectId, nativeId),
|
|
1113
968
|
),
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
Effect.gen(function* () {
|
|
1121
|
-
const database = yield* CurrentD1PlanningDatabase;
|
|
969
|
+
)
|
|
970
|
+
.innerJoin(
|
|
971
|
+
mapping.credential.table,
|
|
972
|
+
and(eq(cc.moduleId, input.moduleId), eq(cc.subjectId, nativeId)),
|
|
973
|
+
)
|
|
974
|
+
.where(eq(sc.id, nativeId));
|
|
1122
975
|
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
? undefined
|
|
1126
|
-
: yield* snapshotPasswordCredential(uncaptured.captured);
|
|
976
|
+
if (rows.length !== 1) return Option.none();
|
|
977
|
+
const row = rows[0]!;
|
|
1127
978
|
|
|
1128
|
-
|
|
979
|
+
if (
|
|
980
|
+
!mapping.subject.isActiveStatus(row.subject[mapping.subject.status]) ||
|
|
981
|
+
!mapping.identifier.isCurrent(row.identifier) ||
|
|
982
|
+
!mapping.subjectId.equals(nativeId, row.subject[mapping.subject.id]) ||
|
|
983
|
+
!mapping.subjectId.equals(nativeId, row.identifier[mapping.identifier.subjectId]) ||
|
|
984
|
+
!mapping.subjectId.equals(nativeId, row.credential[mapping.credential.subjectId])
|
|
985
|
+
)
|
|
986
|
+
return Option.none();
|
|
1129
987
|
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
988
|
+
const credential = yield* mapping.credential
|
|
989
|
+
.decode({ moduleId: input.moduleId, ...row })
|
|
990
|
+
.pipe(Effect.flatMap(snapshotPasswordCredential));
|
|
1133
991
|
|
|
1134
|
-
|
|
992
|
+
return input.subjectId !== undefined && credential.revision.subjectId !== input.subjectId
|
|
993
|
+
? Option.none()
|
|
994
|
+
: Option.some(credential);
|
|
995
|
+
}),
|
|
996
|
+
rehashIfCurrent: (input: Parameters<PasswordPersistence["Service"]["rehashIfCurrent"]>[0]) =>
|
|
997
|
+
run(
|
|
998
|
+
Effect.gen(function* () {
|
|
999
|
+
const nextVerifier = Redacted.make(
|
|
1000
|
+
yield* Schema.decodeEffect(EncodedPasswordHash)(Redacted.value(input.nextVerifier)),
|
|
1001
|
+
);
|
|
1135
1002
|
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
.limit(1);
|
|
1003
|
+
const credential = yield* snapshotPasswordCredential(input.credential);
|
|
1004
|
+
const database = yield* CurrentD1PlanningDatabase;
|
|
1005
|
+
const nativeId = yield* mapping.subjectId.toNative(credential.revision.subjectId);
|
|
1006
|
+
const version = yield* allocate(mapping.allocateRevision, mapping.allocateRevisionSync);
|
|
1141
1007
|
|
|
1142
|
-
|
|
1143
|
-
|
|
1008
|
+
if (version === credential.verifierVersion) return yield* unavailable();
|
|
1009
|
+
const encoded = mapping.credential.encodeVerifier(nextVerifier, version);
|
|
1144
1010
|
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1011
|
+
const values = {
|
|
1012
|
+
[mapping.credential.verifier]: encoded[mapping.credential.verifier],
|
|
1013
|
+
[mapping.credential.verifierVersion]: encoded[mapping.credential.verifierVersion],
|
|
1014
|
+
};
|
|
1149
1015
|
|
|
1150
|
-
|
|
1151
|
-
|
|
1016
|
+
if (Object.values(values).some((value) => value === undefined))
|
|
1017
|
+
return yield* unavailable();
|
|
1018
|
+
const c = credentialColumns(mapping);
|
|
1152
1019
|
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
input.outcome === "verified" &&
|
|
1157
|
-
input.captured !== undefined &&
|
|
1158
|
-
deadline !== undefined &&
|
|
1159
|
-
deadline > engineNow
|
|
1160
|
-
) {
|
|
1161
|
-
resolved = yield* resolveCredential(
|
|
1162
|
-
mapping,
|
|
1163
|
-
input.moduleId,
|
|
1164
|
-
input.captured.identifier,
|
|
1165
|
-
input.captured.revision.subjectId,
|
|
1166
|
-
);
|
|
1167
|
-
verified =
|
|
1168
|
-
input.captured.moduleId === input.moduleId &&
|
|
1169
|
-
resolved?.snapshot !== undefined &&
|
|
1170
|
-
sameSnapshot(resolved.snapshot, input.captured) &&
|
|
1171
|
-
mapping.subjectId.equals(
|
|
1172
|
-
row[mapping.attempt.subjectId],
|
|
1173
|
-
resolved.nativeSubjectId,
|
|
1174
|
-
) &&
|
|
1175
|
-
row[mapping.attempt.identifierNamespace] === input.captured.identifier.namespace &&
|
|
1176
|
-
row[mapping.attempt.identifierValue] === input.captured.identifier.value &&
|
|
1177
|
-
row[mapping.attempt.credentialId] === input.captured.credentialId &&
|
|
1178
|
-
row[mapping.attempt.securityRevision] ===
|
|
1179
|
-
input.captured.revision.securityRevision &&
|
|
1180
|
-
row[mapping.attempt.credentialRevision] === input.captured.credentialRevision &&
|
|
1181
|
-
row[mapping.attempt.verifierVersion] === input.captured.verifierVersion &&
|
|
1182
|
-
row[mapping.attempt.identifierBindingRevision] ===
|
|
1183
|
-
input.captured.identifierBindingRevision;
|
|
1184
|
-
}
|
|
1185
|
-
const decision: PasswordAttemptDecision = verified ? "verified" : "rejected";
|
|
1186
|
-
const receipt = prepare(decision, journal);
|
|
1187
|
-
|
|
1188
|
-
if (row === undefined || row[mapping.attempt.state] !== "pending")
|
|
1189
|
-
return { receipt, statements: [] };
|
|
1190
|
-
const marker = `effect-auth-password-guard:settle:${input.attemptId}`;
|
|
1191
|
-
|
|
1192
|
-
const base = and(
|
|
1193
|
-
eq(a.moduleId, input.moduleId),
|
|
1194
|
-
eq(a.attemptId, input.attemptId),
|
|
1195
|
-
eq(a.state, "pending"),
|
|
1196
|
-
)!;
|
|
1197
|
-
|
|
1198
|
-
const attemptSnapshot =
|
|
1199
|
-
verified && resolved?.snapshot !== undefined
|
|
1200
|
-
? and(
|
|
1201
|
-
eq(a.action, row[mapping.attempt.action]),
|
|
1202
|
-
eq(a.subjectId, resolved.nativeSubjectId),
|
|
1203
|
-
eq(a.identifierNamespace, input.captured!.identifier.namespace),
|
|
1204
|
-
eq(a.identifierValue, input.captured!.identifier.value),
|
|
1205
|
-
eq(a.credentialId, input.captured!.credentialId),
|
|
1206
|
-
eq(a.securityRevision, input.captured!.revision.securityRevision),
|
|
1207
|
-
eq(a.credentialRevision, input.captured!.credentialRevision),
|
|
1208
|
-
eq(a.verifierVersion, input.captured!.verifierVersion),
|
|
1209
|
-
eq(a.identifierBindingRevision, input.captured!.identifierBindingRevision),
|
|
1210
|
-
eq(a.deadline, row[mapping.attempt.deadline]),
|
|
1211
|
-
)!
|
|
1212
|
-
: sql`true`;
|
|
1213
|
-
|
|
1214
|
-
const condition = verified
|
|
1215
|
-
? and(base, attemptSnapshot, sql`${a.deadline} > ${mapping.d1.engineNow}`)!
|
|
1216
|
-
: base;
|
|
1217
|
-
|
|
1218
|
-
const statements: Statement<any>[] = [
|
|
1219
|
-
yield* assertion(
|
|
1220
|
-
sql`exists(select 1 from ${mapping.attempt.table} where ${condition})`,
|
|
1221
|
-
marker,
|
|
1222
|
-
),
|
|
1020
|
+
return {
|
|
1021
|
+
receipt: undefined,
|
|
1022
|
+
statements: [
|
|
1223
1023
|
yield* statement(
|
|
1224
1024
|
database
|
|
1225
|
-
.update(mapping.
|
|
1226
|
-
.set(
|
|
1227
|
-
.where(
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
mapping.allocateRevision,
|
|
1247
|
-
mapping.allocateRevisionSync,
|
|
1248
|
-
);
|
|
1249
|
-
|
|
1250
|
-
statements.push(
|
|
1251
|
-
yield* assertion(sql`changes() = 1`, marker),
|
|
1252
|
-
yield* statement(
|
|
1253
|
-
database
|
|
1254
|
-
.update(mapping.credential.table)
|
|
1255
|
-
.set(
|
|
1256
|
-
mapping.credential.encodeVerifier(input.rehash.nextVerifier, nextVersion),
|
|
1257
|
-
)
|
|
1258
|
-
.where(
|
|
1259
|
-
and(
|
|
1260
|
-
eq(c.moduleId, input.moduleId),
|
|
1261
|
-
eq(c.subjectId, resolved.nativeSubjectId),
|
|
1262
|
-
eq(c.credentialId, captured.credentialId),
|
|
1263
|
-
eq(c.credentialRevision, captured.credentialRevision),
|
|
1264
|
-
eq(c.verifierVersion, input.rehash.expectedVersion),
|
|
1265
|
-
eq(c.verifier, Redacted.value(input.rehash.expectedVerifier)),
|
|
1266
|
-
),
|
|
1025
|
+
.update(mapping.credential.table)
|
|
1026
|
+
.set(values)
|
|
1027
|
+
.where(
|
|
1028
|
+
and(
|
|
1029
|
+
eq(c.moduleId, credential.moduleId),
|
|
1030
|
+
eq(c.subjectId, nativeId),
|
|
1031
|
+
eq(c.credentialId, credential.credentialId),
|
|
1032
|
+
...(
|
|
1033
|
+
[
|
|
1034
|
+
[c.moduleId, credential.moduleId],
|
|
1035
|
+
[c.subjectId, nativeId],
|
|
1036
|
+
[c.credentialId, credential.credentialId],
|
|
1037
|
+
[c.credentialRevision, credential.credentialRevision],
|
|
1038
|
+
[c.verifierVersion, credential.verifierVersion],
|
|
1039
|
+
[c.verifier, Redacted.value(credential.verifier)],
|
|
1040
|
+
[c.normalization, credential.normalization],
|
|
1041
|
+
] as const
|
|
1042
|
+
).map(([column, value]) =>
|
|
1043
|
+
typeof value === "string"
|
|
1044
|
+
? sql`cast(${column} as blob) = cast(${sql.param(value, column)} as blob)`
|
|
1045
|
+
: eq(column, value),
|
|
1267
1046
|
),
|
|
1047
|
+
),
|
|
1268
1048
|
),
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1272
|
-
|
|
1273
|
-
|
|
1274
|
-
snapshot: {
|
|
1275
|
-
...resolved.snapshot,
|
|
1276
|
-
verifierVersion: nextVersion,
|
|
1277
|
-
verifier: input.rehash.nextVerifier,
|
|
1278
|
-
},
|
|
1279
|
-
},
|
|
1280
|
-
input.moduleId,
|
|
1281
|
-
);
|
|
1282
|
-
}
|
|
1283
|
-
}
|
|
1284
|
-
|
|
1285
|
-
const settled = and(
|
|
1286
|
-
finalAuthority,
|
|
1287
|
-
sql`exists(select 1 from ${mapping.attempt.table} where ${a.moduleId} = ${sql.param(input.moduleId, a.moduleId)} and ${a.attemptId} = ${sql.param(input.attemptId, a.attemptId)} and ${a.state} = ${sql.param(decision, a.state)} and ${attemptSnapshot}${verified ? sql` and ${a.deadline} > ${mapping.d1.engineNow}` : sql``})`,
|
|
1288
|
-
)!;
|
|
1289
|
-
|
|
1290
|
-
// Run after attempt/rehash triggers, before the batch can publish its journal.
|
|
1291
|
-
statements.push(yield* assertion(and(sql`changes() = 1`, settled)!, marker));
|
|
1292
|
-
|
|
1293
|
-
return {
|
|
1294
|
-
receipt,
|
|
1295
|
-
statements,
|
|
1296
|
-
postconditions: [yield* assertion(settled, marker)],
|
|
1297
|
-
retryable: (cause: unknown) => isGuardFailure(cause, marker),
|
|
1298
|
-
};
|
|
1299
|
-
}),
|
|
1300
|
-
);
|
|
1301
|
-
}),
|
|
1049
|
+
),
|
|
1050
|
+
],
|
|
1051
|
+
};
|
|
1052
|
+
}),
|
|
1053
|
+
),
|
|
1302
1054
|
readForSubject: (input: Parameters<PasswordPersistence["Service"]["readForSubject"]>[0]) =>
|
|
1303
1055
|
Effect.gen(function* () {
|
|
1304
1056
|
const database = yield* CurrentD1PlanningDatabase;
|
|
@@ -1456,15 +1208,6 @@ const makePasswordPlans = (
|
|
|
1456
1208
|
"reset-password",
|
|
1457
1209
|
),
|
|
1458
1210
|
),
|
|
1459
|
-
cleanupAttempts: <A>(
|
|
1460
|
-
input: Parameters<PasswordPersistence["Service"]["cleanupAttempts"]>[0],
|
|
1461
|
-
prepare: PlanPrepare<PasswordPersistence["Service"]["cleanupAttempts"], A>,
|
|
1462
|
-
) =>
|
|
1463
|
-
run(
|
|
1464
|
-
Effect.gen(function* () {
|
|
1465
|
-
return yield* cleanupPlan(mapping, input, prepare);
|
|
1466
|
-
}),
|
|
1467
|
-
),
|
|
1468
1211
|
};
|
|
1469
1212
|
};
|
|
1470
1213
|
|
|
@@ -1623,68 +1366,15 @@ const replacementPlan = Effect.fn("Drizzle.replacementPlan")(function* <A>(
|
|
|
1623
1366
|
};
|
|
1624
1367
|
});
|
|
1625
1368
|
|
|
1626
|
-
const cleanupPlan = Effect.fn("Drizzle.cleanupPlan")(function* <A>(
|
|
1627
|
-
mapping: Mapping,
|
|
1628
|
-
input: { readonly moduleId: string; readonly limit: number },
|
|
1629
|
-
prepare: PreparePasswordCommit<{ readonly removed: number; readonly hasMore: boolean }, A>,
|
|
1630
|
-
) {
|
|
1631
|
-
const database = yield* CurrentD1PlanningDatabase;
|
|
1632
|
-
const journal = yield* CurrentCommitJournal;
|
|
1633
|
-
|
|
1634
|
-
const now = yield* readEngineNowMillis(mapping);
|
|
1635
|
-
const nativeNow = mapping.encodeInstant(now);
|
|
1636
|
-
const a = attemptColumns(mapping);
|
|
1637
|
-
|
|
1638
|
-
const attempts = yield* database
|
|
1639
|
-
.select({ attemptId: a.attemptId })
|
|
1640
|
-
.from(mapping.attempt.table)
|
|
1641
|
-
.where(and(eq(a.moduleId, input.moduleId), lte(a.retentionUntil, nativeNow)))
|
|
1642
|
-
.limit(input.limit + 1);
|
|
1643
|
-
|
|
1644
|
-
const selectedAttempts = attempts.slice(0, input.limit);
|
|
1645
|
-
const hasMore = attempts.length > selectedAttempts.length;
|
|
1646
|
-
const marker = `effect-auth-password-guard:cleanup:${input.moduleId}:${now}`;
|
|
1647
|
-
const statements: Statement<any>[] = [];
|
|
1648
|
-
|
|
1649
|
-
for (const row of selectedAttempts) {
|
|
1650
|
-
const condition = and(
|
|
1651
|
-
eq(a.moduleId, input.moduleId),
|
|
1652
|
-
eq(a.attemptId, row.attemptId),
|
|
1653
|
-
lte(a.retentionUntil, mapping.d1.engineNow),
|
|
1654
|
-
)!;
|
|
1655
|
-
|
|
1656
|
-
statements.push(
|
|
1657
|
-
yield* assertion(
|
|
1658
|
-
sql`exists(select 1 from ${mapping.attempt.table} where ${condition})`,
|
|
1659
|
-
marker,
|
|
1660
|
-
),
|
|
1661
|
-
yield* statement(database.delete(mapping.attempt.table).where(condition)),
|
|
1662
|
-
);
|
|
1663
|
-
}
|
|
1664
|
-
|
|
1665
|
-
return {
|
|
1666
|
-
receipt: prepare(
|
|
1667
|
-
{
|
|
1668
|
-
removed: selectedAttempts.length,
|
|
1669
|
-
hasMore,
|
|
1670
|
-
},
|
|
1671
|
-
journal,
|
|
1672
|
-
),
|
|
1673
|
-
statements,
|
|
1674
|
-
retryable: (cause: unknown) => isGuardFailure(cause, marker),
|
|
1675
|
-
};
|
|
1676
|
-
});
|
|
1677
|
-
|
|
1678
1369
|
export const makeD1PasswordPersistenceServices = Effect.fnUntraced(function* <
|
|
1679
1370
|
S extends AnySQLiteTable,
|
|
1680
1371
|
I extends AnySQLiteTable,
|
|
1681
1372
|
C extends AnySQLiteTable,
|
|
1682
1373
|
AC extends AnySQLiteTable,
|
|
1683
|
-
A extends AnySQLiteTable,
|
|
1684
1374
|
M extends AnySQLiteTable,
|
|
1685
1375
|
NativeId,
|
|
1686
1376
|
>(
|
|
1687
|
-
mapping: D1PasswordPersistenceMapping<S, I, C, AC,
|
|
1377
|
+
mapping: D1PasswordPersistenceMapping<S, I, C, AC, M, NativeId>,
|
|
1688
1378
|
proofMapping?: D1ProofPersistenceMapping<
|
|
1689
1379
|
any,
|
|
1690
1380
|
any,
|
|
@@ -1726,21 +1416,13 @@ export const makeD1PasswordPersistenceServices = Effect.fnUntraced(function* <
|
|
|
1726
1416
|
);
|
|
1727
1417
|
|
|
1728
1418
|
const service: PasswordPersistence["Service"] = {
|
|
1729
|
-
|
|
1419
|
+
findCredential: (input) =>
|
|
1730
1420
|
standalone.pipe(
|
|
1731
|
-
Effect.andThen(plans.
|
|
1732
|
-
Effect.map((planned): PasswordAttemptPreparation =>
|
|
1733
|
-
Object.freeze({
|
|
1734
|
-
...(planned.credential === undefined ? {} : { credential: planned.credential }),
|
|
1735
|
-
admit: <A>(prepare: PreparePasswordCommit<PasswordAttemptAdmission, A>) =>
|
|
1736
|
-
planned.claim.pipe(Effect.andThen(run(planned.admit(prepare))), translateFailure),
|
|
1737
|
-
}),
|
|
1738
|
-
),
|
|
1421
|
+
Effect.andThen(plans.findCredential(input)),
|
|
1739
1422
|
Effect.provideService(CurrentD1PlanningDatabase, database),
|
|
1740
1423
|
translateFailure,
|
|
1741
1424
|
),
|
|
1742
|
-
|
|
1743
|
-
run(plans.settleAttempt(input, prepare)).pipe(translateFailure),
|
|
1425
|
+
rehashIfCurrent: (input) => run(plans.rehashIfCurrent(input)).pipe(translateFailure),
|
|
1744
1426
|
readForSubject: (input) =>
|
|
1745
1427
|
plans
|
|
1746
1428
|
.readForSubject(input)
|
|
@@ -1770,8 +1452,6 @@ export const makeD1PasswordPersistenceServices = Effect.fnUntraced(function* <
|
|
|
1770
1452
|
),
|
|
1771
1453
|
resetWithProof: (input, prepare) =>
|
|
1772
1454
|
run(plans.resetWithProof(input, prepare)).pipe(translateFailure),
|
|
1773
|
-
cleanupAttempts: (input, prepare) =>
|
|
1774
|
-
run(plans.cleanupAttempts(input, prepare)).pipe(translateFailure),
|
|
1775
1455
|
};
|
|
1776
1456
|
|
|
1777
1457
|
return { passwordPersistence: service };
|
|
@@ -1789,7 +1469,6 @@ export function coordinateD1PasswordPersistence<
|
|
|
1789
1469
|
I extends AnySQLiteTable,
|
|
1790
1470
|
C extends AnySQLiteTable,
|
|
1791
1471
|
AC extends AnySQLiteTable,
|
|
1792
|
-
At extends AnySQLiteTable,
|
|
1793
1472
|
M extends AnySQLiteTable,
|
|
1794
1473
|
NativeId,
|
|
1795
1474
|
A,
|
|
@@ -1800,7 +1479,7 @@ export function coordinateD1PasswordPersistence<
|
|
|
1800
1479
|
>(
|
|
1801
1480
|
acquire: Effect.Effect<Database, DatabaseError, DatabaseRequirements>,
|
|
1802
1481
|
options: {
|
|
1803
|
-
readonly mapping: D1PasswordPersistenceMapping<S, I, C, AC,
|
|
1482
|
+
readonly mapping: D1PasswordPersistenceMapping<S, I, C, AC, M, NativeId>;
|
|
1804
1483
|
readonly proofMapping?:
|
|
1805
1484
|
| D1ProofPersistenceMapping<any, any, any, any, any, any, any, any, any, any, any, any>
|
|
1806
1485
|
| undefined;
|
|
@@ -1864,29 +1543,17 @@ export function coordinateD1PasswordPersistence<
|
|
|
1864
1543
|
);
|
|
1865
1544
|
|
|
1866
1545
|
const service: PasswordPersistence["Service"] = {
|
|
1867
|
-
|
|
1546
|
+
findCredential: (input) =>
|
|
1868
1547
|
owner.run(
|
|
1869
|
-
plans
|
|
1870
|
-
|
|
1871
|
-
|
|
1872
|
-
|
|
1873
|
-
|
|
1874
|
-
: { credential: planned.credential }),
|
|
1875
|
-
admit: <A>(prepare: PreparePasswordCommit<PasswordAttemptAdmission, A>) =>
|
|
1876
|
-
owner.run(
|
|
1877
|
-
planned.claim.pipe(
|
|
1878
|
-
Effect.andThen(run(planned.admit(prepare))),
|
|
1879
|
-
translateFailure,
|
|
1880
|
-
),
|
|
1881
|
-
),
|
|
1882
|
-
}),
|
|
1548
|
+
plans
|
|
1549
|
+
.findCredential(input)
|
|
1550
|
+
.pipe(
|
|
1551
|
+
Effect.provideService(CurrentD1PlanningDatabase, database),
|
|
1552
|
+
translateFailure,
|
|
1883
1553
|
),
|
|
1884
|
-
Effect.provideService(CurrentD1PlanningDatabase, database),
|
|
1885
|
-
translateFailure,
|
|
1886
|
-
),
|
|
1887
1554
|
),
|
|
1888
|
-
|
|
1889
|
-
owner.run(run(plans.
|
|
1555
|
+
rehashIfCurrent: (input) =>
|
|
1556
|
+
owner.run(run(plans.rehashIfCurrent(input)).pipe(translateFailure)),
|
|
1890
1557
|
readForSubject: (input) =>
|
|
1891
1558
|
owner.run(
|
|
1892
1559
|
plans
|
|
@@ -1923,8 +1590,6 @@ export function coordinateD1PasswordPersistence<
|
|
|
1923
1590
|
),
|
|
1924
1591
|
resetWithProof: (input, prepare) =>
|
|
1925
1592
|
owner.run(run(plans.resetWithProof(input, prepare)).pipe(translateFailure)),
|
|
1926
|
-
cleanupAttempts: (input, prepare) =>
|
|
1927
|
-
owner.run(run(plans.cleanupAttempts(input, prepare)).pipe(translateFailure)),
|
|
1928
1593
|
};
|
|
1929
1594
|
|
|
1930
1595
|
const provided = Context.make(PasswordPersistence, service).pipe(
|