@yielded/auth-persistence 0.1.0-beta.30 → 0.1.0-beta.32

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.
Files changed (130) hide show
  1. package/README.md +11 -7
  2. package/dist/Adapter.d.mts +1 -1
  3. package/dist/Adapter.mjs +8 -8
  4. package/dist/OAuthPersistence.mjs +10 -5
  5. package/dist/OAuthPersistence.mjs.map +1 -1
  6. package/dist/internal/configuration.d.mts +49 -13
  7. package/dist/internal/configuration.mjs.map +1 -1
  8. package/dist/internal/email-native.mjs +10 -2
  9. package/dist/internal/email-native.mjs.map +1 -1
  10. package/dist/internal/email-policy.mjs +3 -2
  11. package/dist/internal/email-policy.mjs.map +1 -1
  12. package/dist/internal/models/oauth-model.d.mts +4 -2
  13. package/dist/internal/models/oauth-model.mjs.map +1 -1
  14. package/dist/internal/models/password-model.d.mts +2 -1
  15. package/dist/internal/models/password-model.mjs.map +1 -1
  16. package/dist/internal/oauth/native-accounts.d.mts +1 -1
  17. package/dist/internal/oauth/native-accounts.mjs +6 -6
  18. package/dist/internal/oauth/native-accounts.mjs.map +1 -1
  19. package/dist/internal/oauth/native-connected.d.mts +1 -1
  20. package/dist/internal/oauth/native-connected.mjs +1 -1
  21. package/dist/internal/oauth/native-registration.mjs +19 -8
  22. package/dist/internal/oauth/native-registration.mjs.map +1 -1
  23. package/dist/internal/oauth/native-sign-in.d.mts +1 -1
  24. package/dist/internal/oauth/native-sign-in.mjs +1 -1
  25. package/dist/internal/oauth/native-state.mjs +21 -11
  26. package/dist/internal/oauth/native-state.mjs.map +1 -1
  27. package/dist/internal/oauth/state.d.mts +1 -1
  28. package/dist/internal/oauth/state.mjs +1 -1
  29. package/dist/internal/oauth-managed.mjs +182 -0
  30. package/dist/internal/oauth-managed.mjs.map +1 -0
  31. package/dist/internal/passkey-managed.mjs +5 -3
  32. package/dist/internal/passkey-managed.mjs.map +1 -1
  33. package/dist/internal/passkey-native-registration.mjs +1 -1
  34. package/dist/internal/passkey-native-state.mjs +33 -23
  35. package/dist/internal/passkey-native-state.mjs.map +1 -1
  36. package/dist/internal/passkey-native-write.mjs +3 -3
  37. package/dist/internal/passkey-native-write.mjs.map +1 -1
  38. package/dist/internal/passkey-native.d.mts +15 -7
  39. package/dist/internal/passkey-native.mjs +2 -1
  40. package/dist/internal/passkey-native.mjs.map +1 -1
  41. package/dist/internal/passkey-policy.mjs +9 -7
  42. package/dist/internal/passkey-policy.mjs.map +1 -1
  43. package/dist/internal/password-native.mjs +22 -5
  44. package/dist/internal/password-native.mjs.map +1 -1
  45. package/dist/internal/password-policy.mjs +7 -6
  46. package/dist/internal/password-policy.mjs.map +1 -1
  47. package/dist/internal/password-registration-native.d.mts +1 -1
  48. package/dist/internal/persistence.d.mts +3 -0
  49. package/dist/internal/persistence.mjs +99 -42
  50. package/dist/internal/persistence.mjs.map +1 -1
  51. package/dist/internal/phone-native.mjs +1 -1
  52. package/dist/internal/phone-native.mjs.map +1 -1
  53. package/dist/internal/registration.mjs +17 -8
  54. package/dist/internal/registration.mjs.map +1 -1
  55. package/dist/internal/session-native-authority.mjs +8 -6
  56. package/dist/internal/session-native-authority.mjs.map +1 -1
  57. package/dist/internal/session-native-login.d.mts +2 -2
  58. package/dist/internal/session-native-login.mjs +4 -2
  59. package/dist/internal/session-native-login.mjs.map +1 -1
  60. package/dist/internal/session-native-pending-read.mjs +26 -20
  61. package/dist/internal/session-native-pending-read.mjs.map +1 -1
  62. package/dist/internal/session-native-record.mjs +6 -4
  63. package/dist/internal/session-native-record.mjs.map +1 -1
  64. package/dist/internal/session-native-state.mjs +24 -8
  65. package/dist/internal/session-native-state.mjs.map +1 -1
  66. package/dist/internal/session-native-stateful.d.mts +2 -2
  67. package/dist/internal/session-native-stateful.mjs +67 -38
  68. package/dist/internal/session-native-stateful.mjs.map +1 -1
  69. package/dist/internal/session-native-step-up.d.mts +2 -2
  70. package/dist/internal/session-native-step-up.mjs +17 -19
  71. package/dist/internal/session-native-step-up.mjs.map +1 -1
  72. package/dist/internal/session-native-validity.mjs +3 -1
  73. package/dist/internal/session-native-validity.mjs.map +1 -1
  74. package/dist/internal/sql-authority.mjs +5 -1
  75. package/dist/internal/sql-authority.mjs.map +1 -1
  76. package/dist/internal/sql-storage-validation.mjs +2 -1
  77. package/dist/internal/sql-storage-validation.mjs.map +1 -1
  78. package/dist/internal/sql-table.d.mts +1 -0
  79. package/dist/internal/sql-table.mjs.map +1 -1
  80. package/dist/internal/sqlite-policy-guard.mjs +23 -0
  81. package/dist/internal/sqlite-policy-guard.mjs.map +1 -0
  82. package/dist/internal/step-up-state.mjs +19 -6
  83. package/dist/internal/step-up-state.mjs.map +1 -1
  84. package/dist/internal/storage-mapping.d.mts +9 -5
  85. package/dist/internal/storage-mapping.mjs +17 -5
  86. package/dist/internal/storage-mapping.mjs.map +1 -1
  87. package/dist/internal/storage-tables.d.mts +237 -0
  88. package/dist/internal/storage-tables.mjs +68 -0
  89. package/dist/internal/storage-tables.mjs.map +1 -1
  90. package/dist/internal/storage-validation.d.mts +3 -1
  91. package/dist/internal/storage-validation.mjs +70 -17
  92. package/dist/internal/storage-validation.mjs.map +1 -1
  93. package/dist/internal/totp-native.mjs +1 -1
  94. package/package.json +1 -1
  95. package/src/OAuthPersistence.ts +7 -2
  96. package/src/internal/configuration.ts +72 -15
  97. package/src/internal/email-native.ts +16 -6
  98. package/src/internal/email-policy.ts +12 -3
  99. package/src/internal/models/oauth-model.ts +7 -1
  100. package/src/internal/models/password-model.ts +2 -1
  101. package/src/internal/oauth/native-accounts.ts +3 -3
  102. package/src/internal/oauth/native-registration.ts +17 -6
  103. package/src/internal/oauth/native-state.ts +38 -18
  104. package/src/internal/oauth-managed.ts +277 -0
  105. package/src/internal/passkey-managed.ts +8 -2
  106. package/src/internal/passkey-native-state.ts +59 -52
  107. package/src/internal/passkey-native-write.ts +2 -2
  108. package/src/internal/passkey-native.ts +4 -2
  109. package/src/internal/passkey-policy.ts +13 -9
  110. package/src/internal/password-native.ts +45 -11
  111. package/src/internal/password-policy.ts +16 -8
  112. package/src/internal/persistence.ts +360 -204
  113. package/src/internal/phone-native.ts +1 -1
  114. package/src/internal/registration.ts +53 -40
  115. package/src/internal/session-native-authority.ts +26 -8
  116. package/src/internal/session-native-login.ts +9 -4
  117. package/src/internal/session-native-pending-read.ts +46 -33
  118. package/src/internal/session-native-record.ts +6 -4
  119. package/src/internal/session-native-state.ts +32 -10
  120. package/src/internal/session-native-stateful.ts +147 -52
  121. package/src/internal/session-native-step-up.ts +31 -24
  122. package/src/internal/session-native-validity.ts +3 -1
  123. package/src/internal/sql-authority.ts +5 -1
  124. package/src/internal/sql-storage-validation.ts +53 -46
  125. package/src/internal/sql-table.ts +1 -0
  126. package/src/internal/sqlite-policy-guard.ts +34 -0
  127. package/src/internal/step-up-state.ts +43 -6
  128. package/src/internal/storage-mapping.ts +40 -4
  129. package/src/internal/storage-tables.ts +76 -0
  130. package/src/internal/storage-validation.ts +127 -27
@@ -4,7 +4,9 @@ import { requireStandalone } from "./standalone.mjs";
4
4
  import { SqlBatchCommit } from "./sql-commit.mjs";
5
5
  import { makeNativeProofServices } from "./proof-native.mjs";
6
6
  import { makeNativeEmailAddressServices } from "./email-native.mjs";
7
+ import { validateStorageBatch, withStorageValidation } from "./storage-validation.mjs";
7
8
  import { storageTables, tableDefinition } from "./storage-tables.mjs";
9
+ import { makeManagedOAuth } from "./oauth-managed.mjs";
8
10
  import { makeManagedPasskeys } from "./passkey-managed.mjs";
9
11
  import { makeNativePasswordServices } from "./password-native.mjs";
10
12
  import { makeComposedPhoneTargets } from "./phone-composed.mjs";
@@ -15,14 +17,14 @@ import { makeNativePendingAuthenticationServices } from "./session-native-login.
15
17
  import { makeNativeStatefulSessionServices } from "./session-native-stateful.mjs";
16
18
  import { makeNativeSessionStepUpServices } from "./session-native-step-up.mjs";
17
19
  import { makeMappings } from "./storage-mapping.mjs";
18
- import { validateStorageBatch, withStorageValidation } from "./storage-validation.mjs";
19
20
  import { Context, Effect, Layer, Schema } from "effect";
20
21
  import { SqlClient } from "effect/sql";
21
22
  import { EmailAddressPersistence, EmailUnavailable } from "@yielded/auth/Email";
22
23
  import { hasCommitScope } from "@yielded/auth/Hooks";
24
+ import { OAuthConnectedPersistence, OAuthConnectedRevocations, OAuthSignInPersistence, OAuthUnavailable } from "@yielded/auth/OAuth";
23
25
  import { PasskeyCredentials, PasskeyManagementPersistence, PasskeyPersistence, PasskeyUnavailable } from "@yielded/auth/Passkey";
24
26
  import { PasswordPersistence, PasswordUnavailable } from "@yielded/auth/Password";
25
- import { hooksLayer } from "@yielded/auth/Persistence";
27
+ import { hooksLayer, reportAuthDiagnostic } from "@yielded/auth/Persistence";
26
28
  import { PhoneOtpUnavailable, PhoneSignInTargets } from "@yielded/auth/PhoneOtp";
27
29
  import { ProofPersistence, ProofUnavailable } from "@yielded/auth/Proofs";
28
30
  import { AuthenticationAuthority, SessionUnavailable } from "@yielded/auth/Sessions";
@@ -45,27 +47,37 @@ const timestampKeys = /* @__PURE__ */ new Set([
45
47
  "admittedAt",
46
48
  "deadline",
47
49
  "occurredAt",
48
- "dedupUntil"
50
+ "dedupUntil",
51
+ "binderExpiresAt",
52
+ "refreshClaimedAt",
53
+ "refreshClaimExpiresAt",
54
+ "claimedAt",
55
+ "claimExpiresAt"
49
56
  ]);
50
57
  const createPersistence = (backend) => {
51
58
  const make = (auth) => {
52
- const features = Object.values(auth.strategies).map((strategy) => strategy.persistence);
53
- const phone = features.some((feature) => feature?.kind === "phone");
54
- const password = features.some((feature) => feature?.kind === "password");
55
- const passkeys = features.filter((feature) => feature?.kind === "passkey");
56
- const management = features.some((feature) => feature?.kind === "password" && feature.management);
57
- const email = features.some((feature) => feature?.kind === "email" && feature.addresses);
59
+ const features = Object.values(auth.strategies).flatMap((strategy) => strategy.persistence === void 0 ? [] : [strategy.persistence]);
60
+ const phone = features.some((feature) => feature.kind === "phone");
61
+ const password = features.some((feature) => feature.kind === "password");
62
+ const passkeys = features.filter((feature) => feature.kind === "passkey");
63
+ const oauth = features.filter((feature) => feature?.kind === "oauth");
64
+ const oauthSignIn = oauth.some((feature) => feature.signIn);
65
+ const oauthConnected = oauth.some((feature) => feature.connected !== void 0);
66
+ const stateful = auth.sessionMode === "stateful";
67
+ const stateless = auth.sessionMode === "stateless" && features.length > 0 && features.every((feature) => feature?.kind === "oauth");
68
+ const management = features.some((feature) => feature.kind === "password" && feature.management);
69
+ const email = features.some((feature) => feature.kind === "email" && feature.addresses);
58
70
  const proofs = phone || management || email;
59
- const roles = [
60
- "identifiers",
61
- "credentials",
62
- "sessions",
63
- "pending"
64
- ];
71
+ const roles = ["identifiers", "credentials"];
72
+ if (stateful) roles.push("sessions");
73
+ roles.push("pending");
65
74
  if (password) roles.push("passwords");
66
75
  if (email) roles.push("emailCredentials");
67
76
  if (passkeys.length > 0) roles.push("passkeyCredentials", "passkeyFlows");
68
77
  if (proofs) roles.push("proofs");
78
+ if (oauth.length > 0) roles.push("oauthIdentities", "oauthCredentials");
79
+ if (oauthSignIn) roles.push("oauthSignInFlows");
80
+ if (oauthConnected) roles.push("oauthConnectedFlows", "oauthConnectedGrants", "oauthConnectedRevocations");
69
81
  const ConfigKey = Context.Service()(`@yielded/auth-persistence/${auth.namespace}/Config`);
70
82
  const Config = Object.assign(ConfigKey, { layer: (value) => Layer.succeed(ConfigKey, value) });
71
83
  const ProvisioningKey = Context.Service()(`@yielded/auth-persistence/${auth.namespace}/Provisioning`);
@@ -122,18 +134,15 @@ const createPersistence = (backend) => {
122
134
  decodeInstantSync
123
135
  });
124
136
  };
125
- const services = Layer.effectContext(Effect.gen(function* () {
137
+ const services = Layer.effectContext(Effect.flatMap(backend.acquire, (database) => Effect.gen(function* () {
126
138
  const storage = yield* ConfigKey;
127
- const client = yield* SqlClient.SqlClient;
128
- const database = yield* backend.acquire;
129
- const dialect = client.onDialectOrElse({
139
+ const dialect = (yield* SqlClient.SqlClient).onDialectOrElse({
130
140
  pg: () => "pg",
131
141
  sqlite: () => "sqlite",
132
142
  orElse: () => void 0
133
143
  });
134
144
  if (dialect === void 0) return yield* configError("Use an explicit adapter for this SQL dialect");
135
- if (auth.sessionMode !== "stateful") return yield* configError("The composed layer currently requires stateful sessions");
136
- if (features.some((feature) => feature === void 0 || "lifecycle" in feature && feature.lifecycle || feature.kind === "email" && !feature.addresses)) return yield* configError("Use explicit services for strategies without composed persistence support");
145
+ if (features.some((feature) => "lifecycle" in feature && feature.lifecycle || feature.kind === "email" && !feature.addresses)) return yield* configError("Use explicit services for strategies without composed persistence support");
137
146
  if (storage.namespace !== auth.namespace) return yield* configError("Persistence configuration belongs to a different Auth definition");
138
147
  const validations = [];
139
148
  for (const role of roles) {
@@ -152,16 +161,21 @@ const createPersistence = (backend) => {
152
161
  required: [[storage.subjects.id]]
153
162
  });
154
163
  yield* validateStorageBatch(dialect, validations);
155
- const mappings = yield* makeMappings(storage);
156
164
  const nativeTables = backend.nativeTables(database);
157
- const sessionMapping = mappings.sessions(auth.claims, auth.sessions.moduleId);
165
+ const mappings = yield* makeMappings(storage, nativeTables);
166
+ const sessionMapping = stateful ? mappings.sessions(auth.claims, auth.sessions.moduleId) : void 0;
158
167
  const pendingMapping = mappings.pending(auth.claims, auth.sessions.moduleId);
159
- const sessionServices = yield* makeNativeStatefulSessionServices(nativeTables, sessionMapping);
160
- const { authenticationAuthority } = yield* makeNativeAuthenticationAuthorityServices(nativeTables, sessionMapping);
168
+ const { authenticationAuthority } = yield* makeNativeAuthenticationAuthorityServices(nativeTables, sessionMapping ?? {
169
+ ...pendingMapping,
170
+ pending: {
171
+ pending: pendingMapping.pending,
172
+ login: pendingMapping.login
173
+ }
174
+ });
161
175
  const { pendingAuthentication } = yield* makeNativePendingAuthenticationServices(nativeTables, pendingMapping);
162
176
  const { sessionStepUpPersistence } = yield* makeNativeSessionStepUpServices(nativeTables, {
163
177
  ...pendingMapping,
164
- source: {
178
+ source: sessionMapping === void 0 ? { kind: "StatelessSigned" } : {
165
179
  kind: "Stateful",
166
180
  session: sessionMapping.session,
167
181
  sessionId: sessionMapping.sessionId,
@@ -169,7 +183,11 @@ const createPersistence = (backend) => {
169
183
  }
170
184
  });
171
185
  const { sessionCleanup } = yield* makeNativeSessionCleanupServices(nativeTables, pendingMapping);
172
- let context = Context.make(AuthenticationAuthority, authenticationAuthority).pipe(Context.add(auth.sessions.StatefulSessionPersistence, sessionServices.statefulSessionPersistence), Context.add(auth.sessions.SessionRepository, sessionServices.sessionRepository), Context.add(auth.sessions.PendingAuthentication, pendingAuthentication), Context.add(auth.sessions.SessionStepUpPersistence, sessionStepUpPersistence), Context.add(auth.sessions.SessionCleanup, sessionCleanup));
186
+ let context = Context.make(AuthenticationAuthority, authenticationAuthority).pipe(Context.add(auth.sessions.PendingAuthentication, pendingAuthentication), Context.add(auth.sessions.SessionStepUpPersistence, sessionStepUpPersistence), Context.add(auth.sessions.SessionCleanup, sessionCleanup));
187
+ if (sessionMapping !== void 0) {
188
+ const sessionServices = yield* makeNativeStatefulSessionServices(nativeTables, sessionMapping);
189
+ context = context.pipe(Context.add(auth.sessions.StatefulSessionPersistence, sessionServices.statefulSessionPersistence), Context.add(auth.sessions.SessionRepository, sessionServices.sessionRepository));
190
+ }
173
191
  const proofMapping = proofs ? mappings.proofs() : void 0;
174
192
  if (proofMapping !== void 0) {
175
193
  const services = yield* makeNativeProofServices(backend.nativeTables(database), proofMapping);
@@ -188,23 +206,28 @@ const createPersistence = (backend) => {
188
206
  context = Context.add(context, key, registration);
189
207
  }
190
208
  if (email) context = Context.add(context, EmailAddressPersistence, (yield* makeNativeEmailAddressServices(backend.nativeTables(database), mappings.emails(), proofMapping)).emailAddressPersistence);
191
- if (phone) context = Context.add(context, PhoneSignInTargets, yield* makeComposedPhoneTargets(backend.nativeTables(database), storage, mappings.proofs(), features.flatMap((feature) => feature?.kind === "phone" ? [feature.moduleId] : [])));
209
+ if (phone) context = Context.add(context, PhoneSignInTargets, yield* makeComposedPhoneTargets(backend.nativeTables(database), storage, mappings.proofs(), features.flatMap((feature) => feature.kind === "phone" ? [feature.moduleId] : [])));
192
210
  if (passkeys.length > 0) {
193
211
  const services = makeManagedPasskeys({
194
212
  storage,
195
213
  namespace: auth.namespace,
196
214
  dialect,
197
215
  features: passkeys,
198
- passwordModules: features.flatMap((feature) => feature?.kind === "password" ? [feature.moduleId] : [])
216
+ passwordModules: features.flatMap((feature) => feature.kind === "password" ? [feature.moduleId] : [])
199
217
  }, backend.nativeTables(database));
200
218
  context = Context.merge(context, yield* services);
201
219
  }
220
+ if (oauth.length > 0) context = Context.merge(context, yield* makeManagedOAuth(storage, nativeTables, oauth));
202
221
  return context;
203
- }).pipe(Effect.provideService(SqlBatchCommit, void 0), withStorageValidation, Effect.mapError((error) => Schema.is(PersistenceConfigurationError)(error) ? error : configError("Cannot acquire SQL persistence")))).pipe(Layer.provide(hooksLayer));
222
+ }).pipe(Effect.provideService(SqlBatchCommit, backend.batch?.(database)))).pipe(withStorageValidation)).pipe(Layer.provide(hooksLayer));
204
223
  return {
205
224
  Config,
206
225
  Provisioning: ProvisioningKey,
207
226
  layer: Layer.effectContext(Effect.gen(function* () {
227
+ if (!stateful && !stateless) {
228
+ if (auth.sessionMode === "stateless") return yield* configError("Composed stateless sessions support only OAuth strategies; use explicit persistence for other strategies");
229
+ return yield* configError("Composed persistence supports stateful or OAuth-only stateless sessions; state-assisted validity and other session modes require explicit persistence");
230
+ }
208
231
  const scope = yield* Effect.scope;
209
232
  const captured = yield* Effect.context();
210
233
  const client = Context.get(captured, SqlClient.SqlClient);
@@ -214,16 +237,13 @@ const createPersistence = (backend) => {
214
237
  if (yield* hasCommitScope) return yield* Effect.fail(unavailable());
215
238
  yield* requireStandalone(unavailable, client.transactionService);
216
239
  }
217
- const acquired = yield* initialize.pipe(Effect.mapError(unavailable));
240
+ const acquired = yield* initialize.pipe(Effect.tapError((error) => reportAuthDiagnostic("persistence-initialization", Schema.is(PersistenceConfigurationError)(error) ? "configuration" : Schema.is(PersistenceMappingError)(error) ? "mapping" : "unavailable")), Effect.mapError(unavailable));
218
241
  const value = Context.getOrUndefined(acquired, key);
219
242
  return value === void 0 ? yield* Effect.fail(unavailable()) : value;
220
243
  });
221
244
  const sessionUnavailable = () => SessionUnavailable.make({});
222
245
  const authority = service(AuthenticationAuthority, sessionUnavailable, false);
223
246
  const authorityMutation = service(AuthenticationAuthority, sessionUnavailable);
224
- const sessions = service(auth.sessions.StatefulSessionPersistence, sessionUnavailable, false);
225
- const sessionMutations = service(auth.sessions.StatefulSessionPersistence, sessionUnavailable);
226
- const repository = service(auth.sessions.SessionRepository, sessionUnavailable, false);
227
247
  const pendingRead = service(auth.sessions.PendingAuthentication, sessionUnavailable, false);
228
248
  const pendingMutation = service(auth.sessions.PendingAuthentication, sessionUnavailable);
229
249
  const stepUpRead = service(auth.sessions.SessionStepUpPersistence, sessionUnavailable, false);
@@ -233,14 +253,7 @@ const createPersistence = (backend) => {
233
253
  capture: (subjectId, credentialIds) => Effect.flatMap(authority, (s) => s.capture(subjectId, credentialIds)),
234
254
  requirements: (evidence) => Effect.flatMap(authority, (s) => s.requirements(evidence)),
235
255
  approve: (input, prepare) => Effect.flatMap(authorityMutation, (s) => s.approve(input, prepare))
236
- }).pipe(Context.add(auth.sessions.StatefulSessionPersistence, {
237
- establish: (input, prepare) => Effect.flatMap(sessionMutations, (s) => s.establish(input, prepare)),
238
- verify: (input) => Effect.flatMap(sessions, (s) => s.verify(input)),
239
- rotate: (input, prepare) => Effect.flatMap(sessionMutations, (s) => s.rotate(input, prepare)),
240
- revokeDigest: (digest, prepare) => Effect.flatMap(sessionMutations, (s) => s.revokeDigest(digest, prepare)),
241
- revoke: (input, prepare) => Effect.flatMap(sessionMutations, (s) => s.revoke(input, prepare)),
242
- revokeAll: (input, prepare) => Effect.flatMap(sessionMutations, (s) => s.revokeAll(input, prepare))
243
- }), Context.add(auth.sessions.SessionRepository, { list: (input) => Effect.flatMap(repository, (s) => s.list(input)) }), Context.add(auth.sessions.PendingAuthentication, {
256
+ }).pipe(Context.add(auth.sessions.PendingAuthentication, {
244
257
  create: (input, now, prepare) => Effect.flatMap(pendingMutation, (s) => s.create(input, now, prepare)),
245
258
  read: (input) => Effect.flatMap(pendingRead, (s) => s.read(input)),
246
259
  reject: (input, prepare) => Effect.flatMap(pendingMutation, (s) => s.reject(input, prepare))
@@ -250,6 +263,19 @@ const createPersistence = (backend) => {
250
263
  reject: (input, prepare) => Effect.flatMap(stepUpMutation, (s) => s.reject(input, prepare)),
251
264
  complete: (plan, prepare) => Effect.flatMap(stepUpMutation, (s) => s.complete(plan, prepare))
252
265
  }), Context.add(auth.sessions.SessionCleanup, { cleanup: (input) => Effect.flatMap(cleanup, (s) => s.cleanup(input)) }));
266
+ if (stateful) {
267
+ const sessions = service(auth.sessions.StatefulSessionPersistence, sessionUnavailable, false);
268
+ const sessionMutations = service(auth.sessions.StatefulSessionPersistence, sessionUnavailable);
269
+ const repository = service(auth.sessions.SessionRepository, sessionUnavailable, false);
270
+ context = context.pipe(Context.add(auth.sessions.StatefulSessionPersistence, {
271
+ establish: (input, prepare) => Effect.flatMap(sessionMutations, (s) => s.establish(input, prepare)),
272
+ verify: (input) => Effect.flatMap(sessions, (s) => s.verify(input)),
273
+ rotate: (input, prepare) => Effect.flatMap(sessionMutations, (s) => s.rotate(input, prepare)),
274
+ revokeDigest: (digest, prepare) => Effect.flatMap(sessionMutations, (s) => s.revokeDigest(digest, prepare)),
275
+ revoke: (input, prepare) => Effect.flatMap(sessionMutations, (s) => s.revoke(input, prepare)),
276
+ revokeAll: (input, prepare) => Effect.flatMap(sessionMutations, (s) => s.revokeAll(input, prepare))
277
+ }), Context.add(auth.sessions.SessionRepository, { list: (input) => Effect.flatMap(repository, (s) => s.list(input)) }));
278
+ }
253
279
  if (proofs) {
254
280
  const persistence = service(ProofPersistence, () => ProofUnavailable.make({}));
255
281
  context = Context.add(context, ProofPersistence, {
@@ -315,6 +341,37 @@ const createPersistence = (backend) => {
315
341
  }));
316
342
  }
317
343
  }
344
+ const oauthUnavailable = () => OAuthUnavailable.make({});
345
+ function oauthService(key, moduleId, capability) {
346
+ return oauth.some((feature) => feature.moduleId === moduleId && (capability === "signIn" ? feature.signIn : feature.connected !== void 0)) ? service(key, oauthUnavailable) : Effect.fail(oauthUnavailable());
347
+ }
348
+ if (oauthSignIn) {
349
+ const persistence = (moduleId) => oauthService(OAuthSignInPersistence, moduleId, "signIn");
350
+ context = Context.add(context, OAuthSignInPersistence, {
351
+ issue: (input, prepare) => Effect.flatMap(persistence(input.context.moduleId), (s) => s.issue(input, prepare)),
352
+ consume: (input, prepare) => Effect.flatMap(persistence(input.moduleId), (s) => s.consume(input, prepare)),
353
+ resolve: (input) => Effect.flatMap(persistence(input.moduleId), (s) => s.resolve(input)),
354
+ cleanup: (input, prepare) => Effect.flatMap(persistence(input.moduleId), (s) => s.cleanup(input, prepare))
355
+ });
356
+ }
357
+ if (oauthConnected) {
358
+ const persistence = (moduleId) => oauthService(OAuthConnectedPersistence, moduleId, "connected");
359
+ const revocations = (moduleId) => oauthService(OAuthConnectedRevocations, moduleId, "connected");
360
+ context = context.pipe(Context.add(OAuthConnectedPersistence, {
361
+ read: (input) => Effect.flatMap(persistence(input.moduleId), (s) => s.read(input)),
362
+ issue: (input, prepare) => Effect.flatMap(persistence(input.context.moduleId), (s) => s.issue(input, prepare)),
363
+ consume: (input, prepare) => Effect.flatMap(persistence(input.moduleId), (s) => s.consume(input, prepare)),
364
+ settle: (input, prepare) => Effect.flatMap(persistence(input.grant.context.moduleId), (s) => s.settle(input, prepare)),
365
+ list: (input) => Effect.flatMap(persistence(input.authorization.moduleId), (s) => s.list(input)),
366
+ disconnect: (input, prepare) => Effect.flatMap(persistence(input.key.moduleId), (s) => s.disconnect(input, prepare)),
367
+ claimRefresh: (input, prepare) => Effect.flatMap(persistence(input.grant.context.moduleId), (s) => s.claimRefresh(input, prepare)),
368
+ settleRefresh: (input, prepare) => Effect.flatMap(persistence(input.claim.grant.context.moduleId), (s) => s.settleRefresh(input, prepare)),
369
+ cleanup: (input, prepare) => Effect.flatMap(persistence(input.moduleId), (s) => s.cleanup(input, prepare))
370
+ }), Context.add(OAuthConnectedRevocations, {
371
+ claim: (input, prepare) => Effect.flatMap(revocations(input.moduleId), (s) => s.claim(input, prepare)),
372
+ settle: (input, prepare) => Effect.flatMap(revocations(input.claim.job.grant.context.moduleId), (s) => s.settle(input, prepare))
373
+ }));
374
+ }
318
375
  return context;
319
376
  })),
320
377
  managed: (options) => layout(options, true),
@@ -1 +1 @@
1
- {"version":3,"file":"persistence.mjs","names":[],"sources":["../../src/internal/persistence.ts"],"sourcesContent":["import { EmailAddressPersistence, EmailUnavailable } from \"@yielded/auth/Email\";\nimport type { LifecycleHooks } from \"@yielded/auth/Hooks\";\nimport { hasCommitScope } from \"@yielded/auth/Hooks\";\nimport {\n PasskeyCredentials,\n PasskeyManagementPersistence,\n PasskeyPersistence,\n PasskeyUnavailable,\n} from \"@yielded/auth/Passkey\";\nimport { PasswordPersistence, PasswordUnavailable } from \"@yielded/auth/Password\";\nimport { hooksLayer } from \"@yielded/auth/Persistence\";\nimport { PhoneSignInTargets, PhoneOtpUnavailable } from \"@yielded/auth/PhoneOtp\";\nimport { ProofPersistence, ProofUnavailable } from \"@yielded/auth/Proofs\";\nimport { AuthenticationAuthority, SessionUnavailable } from \"@yielded/auth/Sessions\";\nimport { Context, type Crypto, Effect, Layer, Schema } from \"effect\";\nimport { SqlClient } from \"effect/sql\";\n\nimport {\n PersistenceConfigurationError,\n type ClaimsCodec,\n type ConfigId,\n type Definition,\n type PersistenceApi,\n type Ports,\n type Roles,\n type Provisioning,\n type ProvisioningRequirement,\n type StorageLayout,\n type SubjectMapping,\n type SubjectOptions,\n type PasskeyFeature,\n type PasskeyRequirement,\n} from \"./configuration\";\nimport { makeNativeEmailAddressServices } from \"./email-native\";\nimport { PersistenceMappingError } from \"./mapping-error\";\nimport type { NativeSqlTables } from \"./native-sql-table\";\nimport { makeManagedPasskeys } from \"./passkey-managed\";\nimport { makeNativePasswordServices } from \"./password-native\";\nimport { makeComposedPhoneTargets } from \"./phone-composed\";\nimport { makeNativeProofServices } from \"./proof-native\";\nimport { makeRegistrationAuthority } from \"./registration\";\nimport type { PasswordRegistrationAuthority } from \"./registration-contract\";\nimport { makeNativeAuthenticationAuthorityServices } from \"./session-native-authority\";\nimport { makeNativeSessionCleanupServices } from \"./session-native-cleanup\";\nimport { makeNativePendingAuthenticationServices } from \"./session-native-login\";\nimport { makeNativeStatefulSessionServices } from \"./session-native-stateful\";\nimport { makeNativeSessionStepUpServices } from \"./session-native-step-up\";\nimport { SqlBatchCommit } from \"./sql-commit\";\nimport { requireStandalone } from \"./standalone\";\nimport { makeMappings } from \"./storage-mapping\";\nimport {\n tableDefinition,\n storageTables,\n type StorageRole,\n type StorageTable,\n} from \"./storage-tables\";\nimport {\n validateStorageBatch,\n withStorageValidation,\n type StorageValidation,\n} from \"./storage-validation\";\n\nexport interface Backend<T extends object, R, Database extends object = object> {\n readonly makeTable: (definition: StorageTable) => T;\n readonly describe: (table: T) => StorageTable;\n readonly acquire: Effect.Effect<Database, PersistenceConfigurationError, R | SqlClient.SqlClient>;\n readonly nativeTables: (database: Database) => NativeSqlTables;\n}\n\nconst configError = (reason: string) => PersistenceConfigurationError.make({ reason });\n\nconst mappingError = (cause: unknown) =>\n PersistenceMappingError.make({ operation: \"mapping\", cause });\n\nconst timestampKeys = new Set([\n \"verifiedAt\",\n \"createdAt\",\n \"lastIssueAt\",\n \"issuedAt\",\n \"expiresAt\",\n \"absoluteExpiresAt\",\n \"retentionUntil\",\n \"claimDeadline\",\n \"retryAt\",\n \"admittedAt\",\n \"deadline\",\n \"occurredAt\",\n \"dedupUntil\",\n]);\n\nexport const createPersistence = <T extends object, R, Database extends object = object>(\n backend: Backend<T, R, Database>,\n): PersistenceApi<T, R> => {\n const make = <C extends ClaimsCodec, const Id extends string, const A extends Definition<C, Id>>(\n auth: A & Definition<C, Id>,\n ) => {\n const features = Object.values(auth.strategies).map((strategy) => strategy.persistence);\n const phone = features.some((feature) => feature?.kind === \"phone\");\n const password = features.some((feature) => feature?.kind === \"password\");\n\n const passkeys = features.filter(\n (feature): feature is PasskeyFeature => feature?.kind === \"passkey\",\n );\n\n const management = features.some(\n (feature) => feature?.kind === \"password\" && feature.management,\n );\n\n const email = features.some((feature) => feature?.kind === \"email\" && feature.addresses);\n const proofs = phone || management || email;\n\n const roles: StorageRole[] = [\"identifiers\", \"credentials\", \"sessions\", \"pending\"];\n\n if (password) roles.push(\"passwords\");\n if (email) roles.push(\"emailCredentials\");\n if (passkeys.length > 0) roles.push(\"passkeyCredentials\", \"passkeyFlows\");\n if (proofs) roles.push(\"proofs\");\n\n const ConfigKey = Context.Service<\n ConfigId<A[\"namespace\"]>,\n StorageLayout<T, Roles<C, Id, A>>\n >()(`@yielded/auth-persistence/${auth.namespace}/Config`);\n\n const Config = Object.assign(ConfigKey, {\n layer: (value: StorageLayout<T, Roles<C, Id, A>>) => Layer.succeed(ConfigKey, value),\n });\n\n const ProvisioningKey = Context.Service<ProvisioningRequirement<A>, Provisioning<A>>()(\n `@yielded/auth-persistence/${auth.namespace}/Provisioning`,\n );\n\n const layout = <N, Instant>(\n options: {\n readonly subjects: SubjectOptions<T, N>;\n readonly tables?: Partial<Record<StorageRole, T>>;\n readonly prefix?: string;\n readonly timestamps?: {\n readonly type: \"text\" | \"integer\";\n readonly codec: Schema.Codec<number, Instant>;\n };\n },\n managed: boolean,\n ): StorageLayout<T, Roles<C, Id, A>> => {\n const subject = options.subjects;\n\n if (passkeys.length > 0 && options.timestamps !== undefined)\n throw configError(\n \"Composed passkey storage uses integer milliseconds; use an explicit passkey adapter for a custom timestamp representation\",\n );\n const description = backend.describe(subject.table);\n const idColumn = description.columns[subject.id];\n\n for (const key of [subject.id, subject.status, subject.securityRevision]) {\n if (description.columns[key] === undefined)\n throw configError(`Missing subject column ${key}`);\n }\n if (subject.activeValue === undefined)\n throw configError(\"An explicit active subject value is required\");\n\n if (idColumn === undefined || idColumn.type === \"boolean\")\n throw configError(\"Subject ID must map a text or integer column\");\n\n const prefix = options.prefix;\n\n if (managed && (prefix === undefined || !/^[A-Za-z_][A-Za-z0-9_]{0,100}$/.test(prefix)))\n throw configError(\"Managed persistence requires an explicit SQL table prefix\");\n\n const schema: Partial<Record<StorageRole, T>> = { ...options.tables };\n\n for (const role of roles) {\n if (schema[role] === undefined && managed) {\n const definition = tableDefinition(role, `${prefix}_${role}`, idColumn.type);\n\n const adjusted =\n options.timestamps === undefined\n ? definition\n : {\n ...definition,\n columns: Object.fromEntries(\n Object.entries(definition.columns).map(([key, column]) => [\n key,\n timestampKeys.has(key)\n ? { ...column, type: options.timestamps?.type ?? column.type }\n : column,\n ]),\n ),\n };\n\n schema[role] = backend.makeTable(adjusted);\n }\n }\n for (const role of roles) {\n if (schema[role] === undefined) throw configError(`Missing ${role} table`);\n }\n const instantCodec = options.timestamps?.codec;\n\n const decodeInstant =\n instantCodec === undefined\n ? Schema.decodeUnknownEffect(Schema.Int)\n : Schema.decodeUnknownEffect(instantCodec);\n\n const decodeInstantSync =\n instantCodec === undefined\n ? Schema.decodeUnknownSync(Schema.Int)\n : Schema.decodeUnknownSync(instantCodec);\n\n const subjects: SubjectMapping = {\n table: subject.table,\n id: subject.id,\n status: subject.status,\n securityRevision: subject.securityRevision,\n activeValue: subject.activeValue,\n requirements: subject.requirements,\n actionRequirements: subject.actionRequirements ?? subject.requirements,\n toSubject: (id) =>\n Schema.decodeUnknownEffect(subject.idCodec)(id).pipe(Effect.mapError(mappingError)),\n toNative: (id) =>\n Schema.encodeEffect(subject.idCodec)(id).pipe(Effect.mapError(mappingError)),\n toSubjectSync: Schema.decodeUnknownSync(subject.idCodec),\n toNativeSync: Schema.encodeSync(subject.idCodec),\n };\n\n return Object.freeze({\n namespace: auth.namespace,\n schema: Object.freeze(schema) as Readonly<Record<Roles<C, Id, A>, T>>,\n tables: schema,\n subjects,\n encodeInstant:\n instantCodec === undefined ? (millis: number) => millis : Schema.encodeSync(instantCodec),\n decodeInstant: (value: unknown) => decodeInstant(value).pipe(Effect.mapError(mappingError)),\n decodeInstantSync,\n });\n };\n\n const services = Layer.effectContext(\n Effect.gen(function* () {\n const storage = yield* ConfigKey;\n const client = yield* SqlClient.SqlClient;\n const database = yield* backend.acquire;\n\n const dialect = client.onDialectOrElse({\n pg: () => \"pg\" as const,\n sqlite: () => \"sqlite\" as const,\n orElse: () => undefined,\n });\n\n if (dialect === undefined)\n return yield* configError(\"Use an explicit adapter for this SQL dialect\");\n if (auth.sessionMode !== \"stateful\")\n return yield* configError(\"The composed layer currently requires stateful sessions\");\n if (\n features.some(\n (feature) =>\n feature === undefined ||\n (\"lifecycle\" in feature && feature.lifecycle) ||\n (feature.kind === \"email\" && !feature.addresses),\n )\n )\n return yield* configError(\n \"Use explicit services for strategies without composed persistence support\",\n );\n if (storage.namespace !== auth.namespace)\n return yield* configError(\n \"Persistence configuration belongs to a different Auth definition\",\n );\n const validations: StorageValidation[] = [];\n\n for (const role of roles) {\n const table = (storage.schema as Partial<Record<StorageRole, T>>)[role];\n\n if (table === undefined) return yield* configError(`Missing ${role} table`);\n const description = backend.describe(table);\n const columns = description.columns;\n\n for (const name of Object.keys(storageTables[role].columns)) {\n if (columns[name] === undefined)\n return yield* configError(`Missing ${role}.${name} column`);\n }\n validations.push({ table: description, required: storageTables[role].unique });\n }\n validations.push({\n table: backend.describe(storage.subjects.table as T),\n required: [[storage.subjects.id]],\n });\n yield* validateStorageBatch(dialect, validations);\n const mappings = yield* makeMappings(storage);\n\n const nativeTables = backend.nativeTables(database);\n const sessionMapping = mappings.sessions(auth.claims, auth.sessions.moduleId);\n const pendingMapping = mappings.pending(auth.claims, auth.sessions.moduleId);\n\n const sessionServices = yield* makeNativeStatefulSessionServices(\n nativeTables,\n sessionMapping,\n );\n\n const { authenticationAuthority } = yield* makeNativeAuthenticationAuthorityServices(\n nativeTables,\n sessionMapping,\n );\n\n const { pendingAuthentication } = yield* makeNativePendingAuthenticationServices(\n nativeTables,\n pendingMapping,\n );\n\n const { sessionStepUpPersistence } = yield* makeNativeSessionStepUpServices(nativeTables, {\n ...pendingMapping,\n source: {\n kind: \"Stateful\",\n session: sessionMapping.session,\n sessionId: sessionMapping.sessionId,\n constraints: { sessionDigest: \"unique(session.digest)\" },\n },\n });\n\n const { sessionCleanup } = yield* makeNativeSessionCleanupServices(\n nativeTables,\n pendingMapping,\n );\n\n let context: Context.Context<never> = Context.make(\n AuthenticationAuthority,\n authenticationAuthority,\n ).pipe(\n Context.add(\n auth.sessions.StatefulSessionPersistence,\n sessionServices.statefulSessionPersistence,\n ),\n Context.add(auth.sessions.SessionRepository, sessionServices.sessionRepository),\n Context.add(auth.sessions.PendingAuthentication, pendingAuthentication),\n Context.add(auth.sessions.SessionStepUpPersistence, sessionStepUpPersistence),\n Context.add(auth.sessions.SessionCleanup, sessionCleanup),\n );\n\n const proofMapping = proofs ? mappings.proofs() : undefined;\n\n if (proofMapping !== undefined) {\n const services = yield* makeNativeProofServices(\n backend.nativeTables(database),\n proofMapping,\n );\n\n context = Context.add(context, ProofPersistence, services.proofPersistence);\n }\n\n if (password) {\n const mapping = mappings.passwords();\n\n const services = yield* makeNativePasswordServices(\n backend.nativeTables(database),\n mapping,\n proofMapping,\n );\n\n context = Context.add(context, PasswordPersistence, services.passwordPersistence);\n }\n for (const [name, strategy] of Object.entries(auth.strategies)) {\n if (strategy.persistence?.kind !== \"password\" || !strategy.persistence.management)\n continue;\n const key = strategy.RegistrationAuthority;\n\n if (key === undefined)\n return yield* configError(`Missing subject provisioning for ${name}`);\n\n const registration = yield* makeRegistrationAuthority(\n backend.nativeTables(database),\n mappings.passwords(),\n ProvisioningKey,\n name,\n );\n\n context = Context.add(context, key, registration);\n }\n if (email)\n context = Context.add(\n context,\n EmailAddressPersistence,\n (yield* makeNativeEmailAddressServices(\n backend.nativeTables(database),\n mappings.emails(),\n proofMapping,\n )).emailAddressPersistence,\n );\n\n if (phone)\n context = Context.add(\n context,\n PhoneSignInTargets,\n yield* makeComposedPhoneTargets(\n backend.nativeTables(database),\n storage,\n mappings.proofs(),\n features.flatMap((feature) => (feature?.kind === \"phone\" ? [feature.moduleId] : [])),\n ),\n );\n\n if (passkeys.length > 0) {\n // Auth capability metadata determines whether PasskeyConfig is required.\n const services = makeManagedPasskeys(\n {\n storage,\n namespace: auth.namespace,\n dialect,\n features: passkeys,\n passwordModules: features.flatMap((feature) =>\n feature?.kind === \"password\" ? [feature.moduleId] : [],\n ),\n },\n backend.nativeTables(database),\n ) as Effect.Effect<\n Context.Context<never>,\n PersistenceConfigurationError,\n PasskeyRequirement<A> | Crypto.Crypto | LifecycleHooks | SqlClient.SqlClient\n >;\n\n context = Context.merge(context, yield* services);\n }\n\n // The checked capability metadata above determines exactly these service keys.\n return context as Context.Context<Ports<C, Id, A>>;\n }).pipe(\n Effect.provideService(SqlBatchCommit, undefined),\n withStorageValidation,\n Effect.mapError((error) =>\n Schema.is(PersistenceConfigurationError)(error)\n ? error\n : configError(\"Cannot acquire SQL persistence\"),\n ),\n ),\n ).pipe(Layer.provide(hooksLayer));\n\n const layer = Layer.effectContext(\n Effect.gen(function* () {\n const scope = yield* Effect.scope;\n const captured = yield* Effect.context<Layer.Services<typeof services>>();\n const client = Context.get(captured, SqlClient.SqlClient);\n\n // Construction uses the layer's exact environment and lifetime, never the\n // first operation's SQL transaction, service overrides, or request scope.\n // Cache the full exit: concurrent callers share failures/interruption too,\n // and cannot retry partially completed setup within this acquired layer.\n const initialize = yield* Effect.cached(\n Layer.buildWithScope(services, scope).pipe(Effect.setContext(captured)),\n );\n\n const service = Effect.fnUntraced(function* <I, S, Failure>(\n key: Context.Key<I, S>,\n unavailable: () => Failure,\n standalone = true,\n ): Effect.fn.Return<S, Failure> {\n // Reject unsupported ownership before setup can perform any writes.\n // Session/authority reads retain their existing ambient-read semantics.\n if (standalone) {\n if (yield* hasCommitScope) return yield* Effect.fail(unavailable());\n yield* requireStandalone(unavailable, client.transactionService);\n }\n const acquired = yield* initialize.pipe(Effect.mapError(unavailable));\n const value = Context.getOrUndefined(acquired, key);\n\n return value === undefined ? yield* Effect.fail(unavailable()) : value;\n });\n\n const sessionUnavailable = () => SessionUnavailable.make({});\n const authority = service(AuthenticationAuthority, sessionUnavailable, false);\n const authorityMutation = service(AuthenticationAuthority, sessionUnavailable);\n\n const sessions = service(\n auth.sessions.StatefulSessionPersistence,\n sessionUnavailable,\n false,\n );\n\n const sessionMutations = service(\n auth.sessions.StatefulSessionPersistence,\n sessionUnavailable,\n );\n\n const repository = service(auth.sessions.SessionRepository, sessionUnavailable, false);\n const pendingRead = service(auth.sessions.PendingAuthentication, sessionUnavailable, false);\n const pendingMutation = service(auth.sessions.PendingAuthentication, sessionUnavailable);\n\n const stepUpRead = service(\n auth.sessions.SessionStepUpPersistence,\n sessionUnavailable,\n false,\n );\n\n const stepUpMutation = service(auth.sessions.SessionStepUpPersistence, sessionUnavailable);\n const cleanup = service(auth.sessions.SessionCleanup, sessionUnavailable);\n\n let context: Context.Context<never> = Context.make(AuthenticationAuthority, {\n capture: (subjectId, credentialIds) =>\n Effect.flatMap(authority, (s) => s.capture(subjectId, credentialIds)),\n requirements: (evidence) => Effect.flatMap(authority, (s) => s.requirements(evidence)),\n approve: (input, prepare) =>\n Effect.flatMap(authorityMutation, (s) => s.approve(input, prepare)),\n }).pipe(\n Context.add(auth.sessions.StatefulSessionPersistence, {\n establish: (input, prepare) =>\n Effect.flatMap(sessionMutations, (s) => s.establish(input, prepare)),\n verify: (input) => Effect.flatMap(sessions, (s) => s.verify(input)),\n rotate: (input, prepare) =>\n Effect.flatMap(sessionMutations, (s) => s.rotate(input, prepare)),\n revokeDigest: (digest, prepare) =>\n Effect.flatMap(sessionMutations, (s) => s.revokeDigest(digest, prepare)),\n revoke: (input, prepare) =>\n Effect.flatMap(sessionMutations, (s) => s.revoke(input, prepare)),\n revokeAll: (input, prepare) =>\n Effect.flatMap(sessionMutations, (s) => s.revokeAll(input, prepare)),\n }),\n Context.add(auth.sessions.SessionRepository, {\n list: (input) => Effect.flatMap(repository, (s) => s.list(input)),\n }),\n Context.add(auth.sessions.PendingAuthentication, {\n create: (input, now, prepare) =>\n Effect.flatMap(pendingMutation, (s) => s.create(input, now, prepare)),\n read: (input) => Effect.flatMap(pendingRead, (s) => s.read(input)),\n reject: (input, prepare) =>\n Effect.flatMap(pendingMutation, (s) => s.reject(input, prepare)),\n }),\n Context.add(auth.sessions.SessionStepUpPersistence, {\n create: (input, now, prepare) =>\n Effect.flatMap(stepUpMutation, (s) => s.create(input, now, prepare)),\n read: (input) => Effect.flatMap(stepUpRead, (s) => s.read(input)),\n reject: (input, prepare) =>\n Effect.flatMap(stepUpMutation, (s) => s.reject(input, prepare)),\n complete: (plan, prepare) =>\n Effect.flatMap(stepUpMutation, (s) => s.complete(plan, prepare)),\n }),\n Context.add(auth.sessions.SessionCleanup, {\n cleanup: (input) => Effect.flatMap(cleanup, (s) => s.cleanup(input)),\n }),\n );\n\n if (proofs) {\n const persistence = service(ProofPersistence, () => ProofUnavailable.make({}));\n\n context = Context.add(context, ProofPersistence, {\n issue: (input, prepare) => Effect.flatMap(persistence, (s) => s.issue(input, prepare)),\n redeem: (input, prepare) =>\n Effect.flatMap(persistence, (s) => s.redeem(input, prepare)),\n cancel: (input, prepare) =>\n Effect.flatMap(persistence, (s) => s.cancel(input, prepare)),\n cleanup: (input, prepare) =>\n Effect.flatMap(persistence, (s) => s.cleanup(input, prepare)),\n });\n }\n if (password) {\n const persistence = service(PasswordPersistence, () => PasswordUnavailable.make({}));\n\n context = Context.add(context, PasswordPersistence, {\n findCredential: (input) => Effect.flatMap(persistence, (s) => s.findCredential(input)),\n rehashIfCurrent: (input) =>\n Effect.flatMap(persistence, (s) => s.rehashIfCurrent(input)),\n readForSubject: (input) => Effect.flatMap(persistence, (s) => s.readForSubject(input)),\n recoveryTarget: (input) => Effect.flatMap(persistence, (s) => s.recoveryTarget(input)),\n addIfAbsent: (input, prepare) =>\n Effect.flatMap(persistence, (s) => s.addIfAbsent(input, prepare)),\n replaceIfCurrent: (input, prepare) =>\n Effect.flatMap(persistence, (s) => s.replaceIfCurrent(input, prepare)),\n resetWithProof: (input, prepare) =>\n Effect.flatMap(persistence, (s) => s.resetWithProof(input, prepare)),\n });\n }\n for (const [name, strategy] of Object.entries(auth.strategies)) {\n if (strategy.persistence?.kind !== \"password\" || !strategy.persistence.management)\n continue;\n const key = strategy.RegistrationAuthority;\n\n if (key === undefined)\n return yield* configError(`Missing subject provisioning for ${name}`);\n\n // The heterogeneous strategy table erases the registration input type;\n // its decoded value is forwarded unchanged to the same authority key.\n const registration = service(\n key as Context.Key<unknown, PasswordRegistrationAuthority<unknown>>,\n () => PasswordUnavailable.make({}),\n );\n\n context = Context.add(context, key, {\n register: (input, prepare) =>\n Effect.flatMap(registration, (s) => s.register(input, prepare)),\n } satisfies PasswordRegistrationAuthority<unknown>);\n }\n if (email) {\n const persistence = service(EmailAddressPersistence, () => EmailUnavailable.make({}));\n\n context = Context.add(context, EmailAddressPersistence, {\n target: (input) => Effect.flatMap(persistence, (s) => s.target(input)),\n verifyWithProof: (input, prepare) =>\n Effect.flatMap(persistence, (s) => s.verifyWithProof(input, prepare)),\n changeWithProof: (input, prepare) =>\n Effect.flatMap(persistence, (s) => s.changeWithProof(input, prepare)),\n });\n }\n if (phone) {\n const unavailable = () => PhoneOtpUnavailable.make({});\n const targets = service(PhoneSignInTargets, unavailable);\n\n context = context.pipe(\n Context.add(PhoneSignInTargets, {\n lookup: (input) => Effect.flatMap(targets, (s) => s.lookup(input)),\n }),\n );\n }\n if (passkeys.length > 0) {\n const unavailable = () => PasskeyUnavailable.make({});\n const credentials = service(PasskeyCredentials, unavailable);\n const persistence = service(PasskeyPersistence, unavailable);\n\n context = context.pipe(\n Context.add(PasskeyCredentials, {\n lookup: (input) => Effect.flatMap(credentials, (s) => s.lookup(input)),\n listForSubject: (input) =>\n Effect.flatMap(credentials, (s) => s.listForSubject(input)),\n }),\n Context.add(PasskeyPersistence, {\n issue: (input, prepare) =>\n Effect.flatMap(persistence, (s) => s.issue(input, prepare)),\n context: (input) => Effect.flatMap(persistence, (s) => s.context(input)),\n consume: (input, prepare) =>\n Effect.flatMap(persistence, (s) => s.consume(input, prepare)),\n cleanup: (input, prepare) =>\n Effect.flatMap(persistence, (s) => s.cleanup(input, prepare)),\n }),\n );\n if (passkeys.some((feature) => feature.management)) {\n const manager = service(PasskeyManagementPersistence, unavailable);\n\n context = context.pipe(\n Context.add(PasskeyManagementPersistence, {\n list: (input) => Effect.flatMap(manager, (s) => s.list(input)),\n completeEnrollment: (input, prepare) =>\n Effect.flatMap(manager, (s) => s.completeEnrollment(input, prepare)),\n inspectRemove: (input) => Effect.flatMap(manager, (s) => s.inspectRemove(input)),\n remove: (input, prepare) =>\n Effect.flatMap(manager, (s) => s.remove(input, prepare)),\n rename: (input, prepare) =>\n Effect.flatMap(manager, (s) => s.rename(input, prepare)),\n }),\n );\n }\n }\n\n // Match the same capability-selected service keys as the acquired graph.\n return context as Context.Context<Ports<C, Id, A>>;\n }),\n );\n\n return {\n Config,\n Provisioning: ProvisioningKey,\n layer,\n managed: <N, Instant = number>(options: {\n readonly subjects: SubjectOptions<T, N>;\n readonly tables?: Partial<Record<Roles<C, Id, A>, T>>;\n readonly prefix?: string;\n readonly timestamps?: {\n readonly type: \"text\" | \"integer\";\n readonly codec: Schema.Codec<number, Instant>;\n };\n }) => layout(options, true),\n map: <N, Instant = number>(options: {\n readonly subjects: SubjectOptions<T, N>;\n readonly tables: Partial<Record<StorageRole, T>>;\n readonly timestamps?: {\n readonly type: \"text\" | \"integer\";\n readonly codec: Schema.Codec<number, Instant>;\n };\n }) => layout(options, false),\n };\n };\n\n return { make };\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"persistence.mjs","names":[],"sources":["../../src/internal/persistence.ts"],"sourcesContent":["import { EmailAddressPersistence, EmailUnavailable } from \"@yielded/auth/Email\";\nimport type { LifecycleHooks } from \"@yielded/auth/Hooks\";\nimport { hasCommitScope } from \"@yielded/auth/Hooks\";\nimport {\n OAuthConnectedPersistence,\n OAuthConnectedRevocations,\n OAuthSignInPersistence,\n OAuthUnavailable,\n} from \"@yielded/auth/OAuth\";\nimport {\n PasskeyCredentials,\n PasskeyManagementPersistence,\n PasskeyPersistence,\n PasskeyUnavailable,\n} from \"@yielded/auth/Passkey\";\nimport { PasswordPersistence, PasswordUnavailable } from \"@yielded/auth/Password\";\nimport { hooksLayer, reportAuthDiagnostic } from \"@yielded/auth/Persistence\";\nimport { PhoneSignInTargets, PhoneOtpUnavailable } from \"@yielded/auth/PhoneOtp\";\nimport { ProofPersistence, ProofUnavailable } from \"@yielded/auth/Proofs\";\nimport { AuthenticationAuthority, SessionUnavailable } from \"@yielded/auth/Sessions\";\nimport { Context, type Crypto, Effect, Layer, Schema } from \"effect\";\nimport { SqlClient } from \"effect/sql\";\n\nimport {\n PersistenceConfigurationError,\n type ClaimsCodec,\n type ConfigId,\n type Definition,\n type PersistenceApi,\n type Ports,\n type Roles,\n type Provisioning,\n type ProvisioningRequirement,\n type StorageLayout,\n type SubjectMapping,\n type SubjectOptions,\n type PasskeyFeature,\n type PasskeyRequirement,\n type OAuthFeature,\n} from \"./configuration\";\nimport { makeNativeEmailAddressServices } from \"./email-native\";\nimport { PersistenceMappingError } from \"./mapping-error\";\nimport type { NativeSqlTables } from \"./native-sql-table\";\nimport { makeManagedOAuth } from \"./oauth-managed\";\nimport { makeManagedPasskeys } from \"./passkey-managed\";\nimport { makeNativePasswordServices } from \"./password-native\";\nimport { makeComposedPhoneTargets } from \"./phone-composed\";\nimport { makeNativeProofServices } from \"./proof-native\";\nimport { makeRegistrationAuthority } from \"./registration\";\nimport type { PasswordRegistrationAuthority } from \"./registration-contract\";\nimport { makeNativeAuthenticationAuthorityServices } from \"./session-native-authority\";\nimport { makeNativeSessionCleanupServices } from \"./session-native-cleanup\";\nimport { makeNativePendingAuthenticationServices } from \"./session-native-login\";\nimport { makeNativeStatefulSessionServices } from \"./session-native-stateful\";\nimport { makeNativeSessionStepUpServices } from \"./session-native-step-up\";\nimport { SqlBatchCommit } from \"./sql-commit\";\nimport { requireStandalone } from \"./standalone\";\nimport { makeMappings } from \"./storage-mapping\";\nimport {\n tableDefinition,\n storageTables,\n type StorageRole,\n type StorageTable,\n} from \"./storage-tables\";\nimport {\n validateStorageBatch,\n withStorageValidation,\n type StorageValidation,\n} from \"./storage-validation\";\n\nexport interface Backend<T extends object, R, Database extends object = object> {\n readonly makeTable: (definition: StorageTable) => T;\n readonly describe: (table: T) => StorageTable;\n readonly acquire: Effect.Effect<Database, PersistenceConfigurationError, R | SqlClient.SqlClient>;\n readonly nativeTables: (database: Database) => NativeSqlTables;\n /** Fixed atomic batches replace interactive transactions on backends such as D1. */\n readonly batch?: (database: Database) => NonNullable<SqlBatchCommit[\"Service\"]>;\n}\n\nconst configError = (reason: string) => PersistenceConfigurationError.make({ reason });\n\nconst mappingError = (cause: unknown) =>\n PersistenceMappingError.make({ operation: \"mapping\", cause });\n\nconst timestampKeys = new Set([\n \"verifiedAt\",\n \"createdAt\",\n \"lastIssueAt\",\n \"issuedAt\",\n \"expiresAt\",\n \"absoluteExpiresAt\",\n \"retentionUntil\",\n \"claimDeadline\",\n \"retryAt\",\n \"admittedAt\",\n \"deadline\",\n \"occurredAt\",\n \"dedupUntil\",\n \"binderExpiresAt\",\n \"refreshClaimedAt\",\n \"refreshClaimExpiresAt\",\n \"claimedAt\",\n \"claimExpiresAt\",\n]);\n\nexport const createPersistence = <T extends object, R, Database extends object = object>(\n backend: Backend<T, R, Database>,\n): PersistenceApi<T, R> => {\n const make = <C extends ClaimsCodec, const Id extends string, const A extends Definition<C, Id>>(\n auth: A & Definition<C, Id>,\n ) => {\n const features = Object.values(auth.strategies).flatMap((strategy) =>\n strategy.persistence === undefined ? [] : [strategy.persistence],\n );\n\n const phone = features.some((feature) => feature.kind === \"phone\");\n const password = features.some((feature) => feature.kind === \"password\");\n\n const passkeys = features.filter(\n (feature): feature is PasskeyFeature => feature.kind === \"passkey\",\n );\n\n const oauth = features.filter((feature): feature is OAuthFeature => feature?.kind === \"oauth\");\n const oauthSignIn = oauth.some((feature) => feature.signIn);\n const oauthConnected = oauth.some((feature) => feature.connected !== undefined);\n const stateful = auth.sessionMode === \"stateful\";\n\n const stateless =\n auth.sessionMode === \"stateless\" &&\n features.length > 0 &&\n features.every((feature) => feature?.kind === \"oauth\");\n\n const management = features.some(\n (feature) => feature.kind === \"password\" && feature.management,\n );\n\n const email = features.some((feature) => feature.kind === \"email\" && feature.addresses);\n const proofs = phone || management || email;\n\n const roles: StorageRole[] = [\"identifiers\", \"credentials\"];\n\n if (stateful) roles.push(\"sessions\");\n roles.push(\"pending\");\n if (password) roles.push(\"passwords\");\n if (email) roles.push(\"emailCredentials\");\n if (passkeys.length > 0) roles.push(\"passkeyCredentials\", \"passkeyFlows\");\n if (proofs) roles.push(\"proofs\");\n if (oauth.length > 0) roles.push(\"oauthIdentities\", \"oauthCredentials\");\n if (oauthSignIn) roles.push(\"oauthSignInFlows\");\n if (oauthConnected)\n roles.push(\"oauthConnectedFlows\", \"oauthConnectedGrants\", \"oauthConnectedRevocations\");\n\n const ConfigKey = Context.Service<\n ConfigId<A[\"namespace\"]>,\n StorageLayout<T, Roles<C, Id, A>>\n >()(`@yielded/auth-persistence/${auth.namespace}/Config`);\n\n const Config = Object.assign(ConfigKey, {\n layer: (value: StorageLayout<T, Roles<C, Id, A>>) => Layer.succeed(ConfigKey, value),\n });\n\n const ProvisioningKey = Context.Service<ProvisioningRequirement<A>, Provisioning<A>>()(\n `@yielded/auth-persistence/${auth.namespace}/Provisioning`,\n );\n\n const layout = <N, Instant>(\n options: {\n readonly subjects: SubjectOptions<T, N>;\n readonly tables?: Partial<Record<StorageRole, T>>;\n readonly prefix?: string;\n readonly timestamps?: {\n readonly type: \"text\" | \"integer\";\n readonly codec: Schema.Codec<number, Instant>;\n };\n },\n managed: boolean,\n ): StorageLayout<T, Roles<C, Id, A>> => {\n const subject = options.subjects;\n\n if (passkeys.length > 0 && options.timestamps !== undefined)\n throw configError(\n \"Composed passkey storage uses integer milliseconds; use an explicit passkey adapter for a custom timestamp representation\",\n );\n const description = backend.describe(subject.table);\n const idColumn = description.columns[subject.id];\n\n for (const key of [subject.id, subject.status, subject.securityRevision]) {\n if (description.columns[key] === undefined)\n throw configError(`Missing subject column ${key}`);\n }\n if (subject.activeValue === undefined)\n throw configError(\"An explicit active subject value is required\");\n\n if (idColumn === undefined || idColumn.type === \"boolean\")\n throw configError(\"Subject ID must map a text or integer column\");\n\n const prefix = options.prefix;\n\n if (managed && (prefix === undefined || !/^[A-Za-z_][A-Za-z0-9_]{0,100}$/.test(prefix)))\n throw configError(\"Managed persistence requires an explicit SQL table prefix\");\n\n const schema: Partial<Record<StorageRole, T>> = { ...options.tables };\n\n for (const role of roles) {\n if (schema[role] === undefined && managed) {\n const definition = tableDefinition(role, `${prefix}_${role}`, idColumn.type);\n\n const adjusted =\n options.timestamps === undefined\n ? definition\n : {\n ...definition,\n columns: Object.fromEntries(\n Object.entries(definition.columns).map(([key, column]) => [\n key,\n timestampKeys.has(key)\n ? { ...column, type: options.timestamps?.type ?? column.type }\n : column,\n ]),\n ),\n };\n\n schema[role] = backend.makeTable(adjusted);\n }\n }\n for (const role of roles) {\n if (schema[role] === undefined) throw configError(`Missing ${role} table`);\n }\n const instantCodec = options.timestamps?.codec;\n\n const decodeInstant =\n instantCodec === undefined\n ? Schema.decodeUnknownEffect(Schema.Int)\n : Schema.decodeUnknownEffect(instantCodec);\n\n const decodeInstantSync =\n instantCodec === undefined\n ? Schema.decodeUnknownSync(Schema.Int)\n : Schema.decodeUnknownSync(instantCodec);\n\n const subjects: SubjectMapping = {\n table: subject.table,\n id: subject.id,\n status: subject.status,\n securityRevision: subject.securityRevision,\n activeValue: subject.activeValue,\n requirements: subject.requirements,\n actionRequirements: subject.actionRequirements ?? subject.requirements,\n toSubject: (id) =>\n Schema.decodeUnknownEffect(subject.idCodec)(id).pipe(Effect.mapError(mappingError)),\n toNative: (id) =>\n Schema.encodeEffect(subject.idCodec)(id).pipe(Effect.mapError(mappingError)),\n toSubjectSync: Schema.decodeUnknownSync(subject.idCodec),\n toNativeSync: Schema.encodeSync(subject.idCodec),\n };\n\n return Object.freeze({\n namespace: auth.namespace,\n schema: Object.freeze(schema) as Readonly<Record<Roles<C, Id, A>, T>>,\n tables: schema,\n subjects,\n encodeInstant:\n instantCodec === undefined ? (millis: number) => millis : Schema.encodeSync(instantCodec),\n decodeInstant: (value: unknown) => decodeInstant(value).pipe(Effect.mapError(mappingError)),\n decodeInstantSync,\n });\n };\n\n const services = Layer.effectContext(\n Effect.flatMap(backend.acquire, (database) =>\n Effect.gen(function* () {\n const storage = yield* ConfigKey;\n const client = yield* SqlClient.SqlClient;\n\n const dialect = client.onDialectOrElse({\n pg: () => \"pg\" as const,\n sqlite: () => \"sqlite\" as const,\n orElse: () => undefined,\n });\n\n if (dialect === undefined)\n return yield* configError(\"Use an explicit adapter for this SQL dialect\");\n if (\n features.some(\n (feature) =>\n (\"lifecycle\" in feature && feature.lifecycle) ||\n (feature.kind === \"email\" && !feature.addresses),\n )\n )\n return yield* configError(\n \"Use explicit services for strategies without composed persistence support\",\n );\n if (storage.namespace !== auth.namespace)\n return yield* configError(\n \"Persistence configuration belongs to a different Auth definition\",\n );\n const validations: StorageValidation[] = [];\n\n for (const role of roles) {\n const table = (storage.schema as Partial<Record<StorageRole, T>>)[role];\n\n if (table === undefined) return yield* configError(`Missing ${role} table`);\n const description = backend.describe(table);\n const columns = description.columns;\n\n for (const name of Object.keys(storageTables[role].columns)) {\n if (columns[name] === undefined)\n return yield* configError(`Missing ${role}.${name} column`);\n }\n validations.push({ table: description, required: storageTables[role].unique });\n }\n validations.push({\n table: backend.describe(storage.subjects.table as T),\n required: [[storage.subjects.id]],\n });\n yield* validateStorageBatch(dialect, validations);\n const nativeTables = backend.nativeTables(database);\n const mappings = yield* makeMappings(storage, nativeTables);\n\n const sessionMapping = stateful\n ? mappings.sessions(auth.claims, auth.sessions.moduleId)\n : undefined;\n\n const pendingMapping = mappings.pending(auth.claims, auth.sessions.moduleId);\n\n const { authenticationAuthority } = yield* makeNativeAuthenticationAuthorityServices(\n nativeTables,\n sessionMapping ?? {\n ...pendingMapping,\n pending: { pending: pendingMapping.pending, login: pendingMapping.login },\n },\n );\n\n const { pendingAuthentication } = yield* makeNativePendingAuthenticationServices(\n nativeTables,\n pendingMapping,\n );\n\n const { sessionStepUpPersistence } = yield* makeNativeSessionStepUpServices(\n nativeTables,\n {\n ...pendingMapping,\n source:\n sessionMapping === undefined\n ? { kind: \"StatelessSigned\" }\n : {\n kind: \"Stateful\",\n session: sessionMapping.session,\n sessionId: sessionMapping.sessionId,\n constraints: { sessionDigest: \"unique(session.digest)\" },\n },\n },\n );\n\n const { sessionCleanup } = yield* makeNativeSessionCleanupServices(\n nativeTables,\n pendingMapping,\n );\n\n let context: Context.Context<never> = Context.make(\n AuthenticationAuthority,\n authenticationAuthority,\n ).pipe(\n Context.add(auth.sessions.PendingAuthentication, pendingAuthentication),\n Context.add(auth.sessions.SessionStepUpPersistence, sessionStepUpPersistence),\n Context.add(auth.sessions.SessionCleanup, sessionCleanup),\n );\n\n if (sessionMapping !== undefined) {\n const sessionServices = yield* makeNativeStatefulSessionServices(\n nativeTables,\n sessionMapping,\n );\n\n context = context.pipe(\n Context.add(\n auth.sessions.StatefulSessionPersistence,\n sessionServices.statefulSessionPersistence,\n ),\n Context.add(auth.sessions.SessionRepository, sessionServices.sessionRepository),\n );\n }\n\n const proofMapping = proofs ? mappings.proofs() : undefined;\n\n if (proofMapping !== undefined) {\n const services = yield* makeNativeProofServices(\n backend.nativeTables(database),\n proofMapping,\n );\n\n context = Context.add(context, ProofPersistence, services.proofPersistence);\n }\n\n if (password) {\n const mapping = mappings.passwords();\n\n const services = yield* makeNativePasswordServices(\n backend.nativeTables(database),\n mapping,\n proofMapping,\n );\n\n context = Context.add(context, PasswordPersistence, services.passwordPersistence);\n }\n for (const [name, strategy] of Object.entries(auth.strategies)) {\n if (strategy.persistence?.kind !== \"password\" || !strategy.persistence.management)\n continue;\n const key = strategy.RegistrationAuthority;\n\n if (key === undefined)\n return yield* configError(`Missing subject provisioning for ${name}`);\n\n const registration = yield* makeRegistrationAuthority(\n backend.nativeTables(database),\n mappings.passwords(),\n ProvisioningKey,\n name,\n );\n\n context = Context.add(context, key, registration);\n }\n if (email)\n context = Context.add(\n context,\n EmailAddressPersistence,\n (yield* makeNativeEmailAddressServices(\n backend.nativeTables(database),\n mappings.emails(),\n proofMapping,\n )).emailAddressPersistence,\n );\n\n if (phone)\n context = Context.add(\n context,\n PhoneSignInTargets,\n yield* makeComposedPhoneTargets(\n backend.nativeTables(database),\n storage,\n mappings.proofs(),\n features.flatMap((feature) => (feature.kind === \"phone\" ? [feature.moduleId] : [])),\n ),\n );\n\n if (passkeys.length > 0) {\n // Auth capability metadata determines whether PasskeyConfig is required.\n const services = makeManagedPasskeys(\n {\n storage,\n namespace: auth.namespace,\n dialect,\n features: passkeys,\n passwordModules: features.flatMap((feature) =>\n feature.kind === \"password\" ? [feature.moduleId] : [],\n ),\n },\n backend.nativeTables(database),\n ) as Effect.Effect<\n Context.Context<never>,\n PersistenceConfigurationError,\n | PasskeyRequirement<A>\n | Crypto.Crypto\n | LifecycleHooks\n | SqlClient.SqlClient\n | SqlBatchCommit\n >;\n\n context = Context.merge(context, yield* services);\n }\n\n if (oauth.length > 0)\n context = Context.merge(context, yield* makeManagedOAuth(storage, nativeTables, oauth));\n\n // The checked capability metadata above determines exactly these service keys.\n return context as Context.Context<Ports<C, Id, A>>;\n }).pipe(Effect.provideService(SqlBatchCommit, backend.batch?.(database))),\n ).pipe(withStorageValidation),\n ).pipe(Layer.provide(hooksLayer));\n\n const layer = Layer.effectContext(\n Effect.gen(function* () {\n if (!stateful && !stateless) {\n if (auth.sessionMode === \"stateless\")\n return yield* configError(\n \"Composed stateless sessions support only OAuth strategies; use explicit persistence for other strategies\",\n );\n\n return yield* configError(\n \"Composed persistence supports stateful or OAuth-only stateless sessions; state-assisted validity and other session modes require explicit persistence\",\n );\n }\n const scope = yield* Effect.scope;\n const captured = yield* Effect.context<Layer.Services<typeof services>>();\n const client = Context.get(captured, SqlClient.SqlClient);\n\n // Construction uses the layer's exact environment and lifetime, never the\n // first operation's SQL transaction, service overrides, or request scope.\n // Cache the full exit: concurrent callers share failures/interruption too,\n // and cannot retry partially completed setup within this acquired layer.\n const initialize = yield* Effect.cached(\n Layer.buildWithScope(services, scope).pipe(Effect.setContext(captured)),\n );\n\n const service = Effect.fnUntraced(function* <I, S, Failure>(\n key: Context.Key<I, S>,\n unavailable: () => Failure,\n standalone = true,\n ): Effect.fn.Return<S, Failure> {\n // Reject unsupported ownership before setup can perform any writes.\n // Session/authority reads retain their existing ambient-read semantics.\n if (standalone) {\n if (yield* hasCommitScope) return yield* Effect.fail(unavailable());\n yield* requireStandalone(unavailable, client.transactionService);\n }\n\n // Observe the cached failure in this invocation, not the captured setup context.\n const acquired = yield* initialize.pipe(\n Effect.tapError((error) =>\n reportAuthDiagnostic(\n \"persistence-initialization\",\n Schema.is(PersistenceConfigurationError)(error)\n ? \"configuration\"\n : Schema.is(PersistenceMappingError)(error)\n ? \"mapping\"\n : \"unavailable\",\n ),\n ),\n Effect.mapError(unavailable),\n );\n\n const value = Context.getOrUndefined(acquired, key);\n\n return value === undefined ? yield* Effect.fail(unavailable()) : value;\n });\n\n const sessionUnavailable = () => SessionUnavailable.make({});\n const authority = service(AuthenticationAuthority, sessionUnavailable, false);\n const authorityMutation = service(AuthenticationAuthority, sessionUnavailable);\n\n const pendingRead = service(auth.sessions.PendingAuthentication, sessionUnavailable, false);\n const pendingMutation = service(auth.sessions.PendingAuthentication, sessionUnavailable);\n\n const stepUpRead = service(\n auth.sessions.SessionStepUpPersistence,\n sessionUnavailable,\n false,\n );\n\n const stepUpMutation = service(auth.sessions.SessionStepUpPersistence, sessionUnavailable);\n const cleanup = service(auth.sessions.SessionCleanup, sessionUnavailable);\n\n let context: Context.Context<never> = Context.make(AuthenticationAuthority, {\n capture: (subjectId, credentialIds) =>\n Effect.flatMap(authority, (s) => s.capture(subjectId, credentialIds)),\n requirements: (evidence) => Effect.flatMap(authority, (s) => s.requirements(evidence)),\n approve: (input, prepare) =>\n Effect.flatMap(authorityMutation, (s) => s.approve(input, prepare)),\n }).pipe(\n Context.add(auth.sessions.PendingAuthentication, {\n create: (input, now, prepare) =>\n Effect.flatMap(pendingMutation, (s) => s.create(input, now, prepare)),\n read: (input) => Effect.flatMap(pendingRead, (s) => s.read(input)),\n reject: (input, prepare) =>\n Effect.flatMap(pendingMutation, (s) => s.reject(input, prepare)),\n }),\n Context.add(auth.sessions.SessionStepUpPersistence, {\n create: (input, now, prepare) =>\n Effect.flatMap(stepUpMutation, (s) => s.create(input, now, prepare)),\n read: (input) => Effect.flatMap(stepUpRead, (s) => s.read(input)),\n reject: (input, prepare) =>\n Effect.flatMap(stepUpMutation, (s) => s.reject(input, prepare)),\n complete: (plan, prepare) =>\n Effect.flatMap(stepUpMutation, (s) => s.complete(plan, prepare)),\n }),\n Context.add(auth.sessions.SessionCleanup, {\n cleanup: (input) => Effect.flatMap(cleanup, (s) => s.cleanup(input)),\n }),\n );\n\n if (stateful) {\n const sessions = service(\n auth.sessions.StatefulSessionPersistence,\n sessionUnavailable,\n false,\n );\n\n const sessionMutations = service(\n auth.sessions.StatefulSessionPersistence,\n sessionUnavailable,\n );\n\n const repository = service(auth.sessions.SessionRepository, sessionUnavailable, false);\n\n context = context.pipe(\n Context.add(auth.sessions.StatefulSessionPersistence, {\n establish: (input, prepare) =>\n Effect.flatMap(sessionMutations, (s) => s.establish(input, prepare)),\n verify: (input) => Effect.flatMap(sessions, (s) => s.verify(input)),\n rotate: (input, prepare) =>\n Effect.flatMap(sessionMutations, (s) => s.rotate(input, prepare)),\n revokeDigest: (digest, prepare) =>\n Effect.flatMap(sessionMutations, (s) => s.revokeDigest(digest, prepare)),\n revoke: (input, prepare) =>\n Effect.flatMap(sessionMutations, (s) => s.revoke(input, prepare)),\n revokeAll: (input, prepare) =>\n Effect.flatMap(sessionMutations, (s) => s.revokeAll(input, prepare)),\n }),\n Context.add(auth.sessions.SessionRepository, {\n list: (input) => Effect.flatMap(repository, (s) => s.list(input)),\n }),\n );\n }\n\n if (proofs) {\n const persistence = service(ProofPersistence, () => ProofUnavailable.make({}));\n\n context = Context.add(context, ProofPersistence, {\n issue: (input, prepare) => Effect.flatMap(persistence, (s) => s.issue(input, prepare)),\n redeem: (input, prepare) =>\n Effect.flatMap(persistence, (s) => s.redeem(input, prepare)),\n cancel: (input, prepare) =>\n Effect.flatMap(persistence, (s) => s.cancel(input, prepare)),\n cleanup: (input, prepare) =>\n Effect.flatMap(persistence, (s) => s.cleanup(input, prepare)),\n });\n }\n if (password) {\n const persistence = service(PasswordPersistence, () => PasswordUnavailable.make({}));\n\n context = Context.add(context, PasswordPersistence, {\n findCredential: (input) => Effect.flatMap(persistence, (s) => s.findCredential(input)),\n rehashIfCurrent: (input) =>\n Effect.flatMap(persistence, (s) => s.rehashIfCurrent(input)),\n readForSubject: (input) => Effect.flatMap(persistence, (s) => s.readForSubject(input)),\n recoveryTarget: (input) => Effect.flatMap(persistence, (s) => s.recoveryTarget(input)),\n addIfAbsent: (input, prepare) =>\n Effect.flatMap(persistence, (s) => s.addIfAbsent(input, prepare)),\n replaceIfCurrent: (input, prepare) =>\n Effect.flatMap(persistence, (s) => s.replaceIfCurrent(input, prepare)),\n resetWithProof: (input, prepare) =>\n Effect.flatMap(persistence, (s) => s.resetWithProof(input, prepare)),\n });\n }\n for (const [name, strategy] of Object.entries(auth.strategies)) {\n if (strategy.persistence?.kind !== \"password\" || !strategy.persistence.management)\n continue;\n const key = strategy.RegistrationAuthority;\n\n if (key === undefined)\n return yield* configError(`Missing subject provisioning for ${name}`);\n\n // The heterogeneous strategy table erases the registration input type;\n // its decoded value is forwarded unchanged to the same authority key.\n const registration = service(\n key as Context.Key<unknown, PasswordRegistrationAuthority<unknown>>,\n () => PasswordUnavailable.make({}),\n );\n\n context = Context.add(context, key, {\n register: (input, prepare) =>\n Effect.flatMap(registration, (s) => s.register(input, prepare)),\n } satisfies PasswordRegistrationAuthority<unknown>);\n }\n if (email) {\n const persistence = service(EmailAddressPersistence, () => EmailUnavailable.make({}));\n\n context = Context.add(context, EmailAddressPersistence, {\n target: (input) => Effect.flatMap(persistence, (s) => s.target(input)),\n verifyWithProof: (input, prepare) =>\n Effect.flatMap(persistence, (s) => s.verifyWithProof(input, prepare)),\n changeWithProof: (input, prepare) =>\n Effect.flatMap(persistence, (s) => s.changeWithProof(input, prepare)),\n });\n }\n if (phone) {\n const unavailable = () => PhoneOtpUnavailable.make({});\n const targets = service(PhoneSignInTargets, unavailable);\n\n context = context.pipe(\n Context.add(PhoneSignInTargets, {\n lookup: (input) => Effect.flatMap(targets, (s) => s.lookup(input)),\n }),\n );\n }\n if (passkeys.length > 0) {\n const unavailable = () => PasskeyUnavailable.make({});\n const credentials = service(PasskeyCredentials, unavailable);\n const persistence = service(PasskeyPersistence, unavailable);\n\n context = context.pipe(\n Context.add(PasskeyCredentials, {\n lookup: (input) => Effect.flatMap(credentials, (s) => s.lookup(input)),\n listForSubject: (input) =>\n Effect.flatMap(credentials, (s) => s.listForSubject(input)),\n }),\n Context.add(PasskeyPersistence, {\n issue: (input, prepare) =>\n Effect.flatMap(persistence, (s) => s.issue(input, prepare)),\n context: (input) => Effect.flatMap(persistence, (s) => s.context(input)),\n consume: (input, prepare) =>\n Effect.flatMap(persistence, (s) => s.consume(input, prepare)),\n cleanup: (input, prepare) =>\n Effect.flatMap(persistence, (s) => s.cleanup(input, prepare)),\n }),\n );\n if (passkeys.some((feature) => feature.management)) {\n const manager = service(PasskeyManagementPersistence, unavailable);\n\n context = context.pipe(\n Context.add(PasskeyManagementPersistence, {\n list: (input) => Effect.flatMap(manager, (s) => s.list(input)),\n completeEnrollment: (input, prepare) =>\n Effect.flatMap(manager, (s) => s.completeEnrollment(input, prepare)),\n inspectRemove: (input) => Effect.flatMap(manager, (s) => s.inspectRemove(input)),\n remove: (input, prepare) =>\n Effect.flatMap(manager, (s) => s.remove(input, prepare)),\n rename: (input, prepare) =>\n Effect.flatMap(manager, (s) => s.rename(input, prepare)),\n }),\n );\n }\n }\n\n const oauthUnavailable = () => OAuthUnavailable.make({});\n\n function oauthService<I, S>(\n key: Context.Key<I, S>,\n moduleId: string,\n capability: \"signIn\" | \"connected\",\n ): Effect.Effect<S, OAuthUnavailable> {\n const enabled = oauth.some(\n (feature) =>\n feature.moduleId === moduleId &&\n (capability === \"signIn\" ? feature.signIn : feature.connected !== undefined),\n );\n\n return enabled ? service(key, oauthUnavailable) : Effect.fail(oauthUnavailable());\n }\n\n if (oauthSignIn) {\n const persistence = (moduleId: string) =>\n oauthService(OAuthSignInPersistence, moduleId, \"signIn\");\n\n context = Context.add(context, OAuthSignInPersistence, {\n issue: (input, prepare) =>\n Effect.flatMap(persistence(input.context.moduleId), (s) => s.issue(input, prepare)),\n consume: (input, prepare) =>\n Effect.flatMap(persistence(input.moduleId), (s) => s.consume(input, prepare)),\n resolve: (input) =>\n Effect.flatMap(persistence(input.moduleId), (s) => s.resolve(input)),\n cleanup: (input, prepare) =>\n Effect.flatMap(persistence(input.moduleId), (s) => s.cleanup(input, prepare)),\n });\n }\n if (oauthConnected) {\n const persistence = (moduleId: string) =>\n oauthService(OAuthConnectedPersistence, moduleId, \"connected\");\n\n const revocations = (moduleId: string) =>\n oauthService(OAuthConnectedRevocations, moduleId, \"connected\");\n\n context = context.pipe(\n Context.add(OAuthConnectedPersistence, {\n read: (input) => Effect.flatMap(persistence(input.moduleId), (s) => s.read(input)),\n issue: (input, prepare) =>\n Effect.flatMap(persistence(input.context.moduleId), (s) => s.issue(input, prepare)),\n consume: (input, prepare) =>\n Effect.flatMap(persistence(input.moduleId), (s) => s.consume(input, prepare)),\n settle: (input, prepare) =>\n Effect.flatMap(persistence(input.grant.context.moduleId), (s) =>\n s.settle(input, prepare),\n ),\n list: (input) =>\n Effect.flatMap(persistence(input.authorization.moduleId), (s) => s.list(input)),\n disconnect: (input, prepare) =>\n Effect.flatMap(persistence(input.key.moduleId), (s) =>\n s.disconnect(input, prepare),\n ),\n claimRefresh: (input, prepare) =>\n Effect.flatMap(persistence(input.grant.context.moduleId), (s) =>\n s.claimRefresh(input, prepare),\n ),\n settleRefresh: (input, prepare) =>\n Effect.flatMap(persistence(input.claim.grant.context.moduleId), (s) =>\n s.settleRefresh(input, prepare),\n ),\n cleanup: (input, prepare) =>\n Effect.flatMap(persistence(input.moduleId), (s) => s.cleanup(input, prepare)),\n }),\n Context.add(OAuthConnectedRevocations, {\n claim: (input, prepare) =>\n Effect.flatMap(revocations(input.moduleId), (s) => s.claim(input, prepare)),\n settle: (input, prepare) =>\n Effect.flatMap(revocations(input.claim.job.grant.context.moduleId), (s) =>\n s.settle(input, prepare),\n ),\n }),\n );\n }\n\n // Match the same capability-selected service keys as the acquired graph.\n return context as Context.Context<Ports<C, Id, A>>;\n }),\n );\n\n return {\n Config,\n Provisioning: ProvisioningKey,\n layer,\n managed: <N, Instant = number>(options: {\n readonly subjects: SubjectOptions<T, N>;\n readonly tables?: Partial<Record<Roles<C, Id, A>, T>>;\n readonly prefix?: string;\n readonly timestamps?: {\n readonly type: \"text\" | \"integer\";\n readonly codec: Schema.Codec<number, Instant>;\n };\n }) => layout(options, true),\n map: <N, Instant = number>(options: {\n readonly subjects: SubjectOptions<T, N>;\n readonly tables: Partial<Record<StorageRole, T>>;\n readonly timestamps?: {\n readonly type: \"text\" | \"integer\";\n readonly codec: Schema.Codec<number, Instant>;\n };\n }) => layout(options, false),\n };\n };\n\n return { make };\n};\n"],"mappings":"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"}
@@ -187,7 +187,7 @@ const makeNativePhoneServices = Effect.fnUntraced(function* (tables, mapping) {
187
187
  ];
188
188
  for (const originalRequirement of requirements) {
189
189
  const requirement = yield* Schema.decodeEffect(AuthenticationRequirement)(originalRequirement);
190
- if (!passwordEvidenceSatisfiedAt(evidence, requirement, captured.now)) return yield* rejected();
190
+ if (!(yield* passwordEvidenceSatisfiedAt(evidence, requirement, captured.now))) return yield* rejected();
191
191
  }
192
192
  if (evidence.proofs.length === 0) return yield* rejected();
193
193
  for (const proof of evidence.proofs) {