@yielded/auth-persistence 0.1.0-beta.23 → 0.1.0-beta.25

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 (182) hide show
  1. package/README.md +11 -0
  2. package/dist/Adapter.d.mts +12 -6
  3. package/dist/Adapter.mjs +8 -3
  4. package/dist/OAuthPersistence.d.mts +87 -0
  5. package/dist/OAuthPersistence.mjs +125 -0
  6. package/dist/OAuthPersistence.mjs.map +1 -0
  7. package/dist/_virtual/_rolldown/runtime.mjs +13 -0
  8. package/dist/index.d.mts +3 -1
  9. package/dist/index.mjs +3 -1
  10. package/dist/internal/configuration.d.mts +1 -1
  11. package/dist/internal/configuration.mjs.map +1 -1
  12. package/dist/internal/email-kernel.d.mts +1 -1
  13. package/dist/internal/email-kernel.mjs +1 -1
  14. package/dist/internal/email-kernel.mjs.map +1 -1
  15. package/dist/internal/models/oauth-connected-model.d.mts +294 -0
  16. package/dist/internal/models/oauth-connected-model.mjs +22 -0
  17. package/dist/internal/models/oauth-connected-model.mjs.map +1 -0
  18. package/dist/internal/models/oauth-model.d.mts +467 -0
  19. package/dist/internal/models/oauth-model.mjs +49 -0
  20. package/dist/internal/models/oauth-model.mjs.map +1 -0
  21. package/dist/internal/models/password-model.d.mts +6 -48
  22. package/dist/internal/models/password-model.mjs +0 -1
  23. package/dist/internal/models/password-model.mjs.map +1 -1
  24. package/dist/internal/native-sql-table.d.mts +4 -0
  25. package/dist/internal/native-sql-table.mjs +7 -0
  26. package/dist/internal/native-sql-table.mjs.map +1 -1
  27. package/dist/internal/oauth/accounts.d.mts +8 -0
  28. package/dist/internal/oauth/accounts.mjs +379 -0
  29. package/dist/internal/oauth/accounts.mjs.map +1 -0
  30. package/dist/internal/oauth/connected-access.d.mts +9 -0
  31. package/dist/internal/oauth/connected-access.mjs +229 -0
  32. package/dist/internal/oauth/connected-access.mjs.map +1 -0
  33. package/dist/internal/oauth/connected-collection.d.mts +7 -0
  34. package/dist/internal/oauth/connected-collection.mjs +214 -0
  35. package/dist/internal/oauth/connected-collection.mjs.map +1 -0
  36. package/dist/internal/oauth/connected-custody.d.mts +6 -0
  37. package/dist/internal/oauth/connected-custody.mjs +165 -0
  38. package/dist/internal/oauth/connected-custody.mjs.map +1 -0
  39. package/dist/internal/oauth/connected-flow.d.mts +7 -0
  40. package/dist/internal/oauth/connected-flow.mjs +324 -0
  41. package/dist/internal/oauth/connected-flow.mjs.map +1 -0
  42. package/dist/internal/oauth/connected-input.mjs +122 -0
  43. package/dist/internal/oauth/connected-input.mjs.map +1 -0
  44. package/dist/internal/oauth/connected-keys.d.mts +2 -0
  45. package/dist/internal/oauth/connected-keys.mjs +22 -0
  46. package/dist/internal/oauth/connected-keys.mjs.map +1 -0
  47. package/dist/internal/oauth/connected-maintenance.d.mts +9 -0
  48. package/dist/internal/oauth/connected-maintenance.mjs +226 -0
  49. package/dist/internal/oauth/connected-maintenance.mjs.map +1 -0
  50. package/dist/internal/oauth/connected-management.d.mts +9 -0
  51. package/dist/internal/oauth/connected-management.mjs +243 -0
  52. package/dist/internal/oauth/connected-management.mjs.map +1 -0
  53. package/dist/internal/oauth/connected-reference.mjs +63 -0
  54. package/dist/internal/oauth/connected-reference.mjs.map +1 -0
  55. package/dist/internal/oauth/connected-settlement.d.mts +8 -0
  56. package/dist/internal/oauth/connected-settlement.mjs +141 -0
  57. package/dist/internal/oauth/connected-settlement.mjs.map +1 -0
  58. package/dist/internal/oauth/connected-sign-in.d.mts +10 -0
  59. package/dist/internal/oauth/connected-sign-in.mjs +281 -0
  60. package/dist/internal/oauth/connected-sign-in.mjs.map +1 -0
  61. package/dist/internal/oauth/connected-state.d.mts +14 -0
  62. package/dist/internal/oauth/connected-state.mjs +469 -0
  63. package/dist/internal/oauth/connected-state.mjs.map +1 -0
  64. package/dist/internal/oauth/connected-target.d.mts +21 -0
  65. package/dist/internal/oauth/connected-target.mjs +117 -0
  66. package/dist/internal/oauth/connected-target.mjs.map +1 -0
  67. package/dist/internal/oauth/flow.d.mts +5 -0
  68. package/dist/internal/oauth/flow.mjs +279 -0
  69. package/dist/internal/oauth/flow.mjs.map +1 -0
  70. package/dist/internal/oauth/input.mjs +127 -0
  71. package/dist/internal/oauth/input.mjs.map +1 -0
  72. package/dist/internal/oauth/owner.d.mts +10 -0
  73. package/dist/internal/oauth/owner.mjs +10 -0
  74. package/dist/internal/oauth/owner.mjs.map +1 -0
  75. package/dist/internal/oauth/query-compiler.d.mts +7 -0
  76. package/dist/internal/oauth/query-compiler.mjs +9 -0
  77. package/dist/internal/oauth/query-compiler.mjs.map +1 -0
  78. package/dist/internal/oauth/registration.d.mts +7 -0
  79. package/dist/internal/oauth/registration.mjs +393 -0
  80. package/dist/internal/oauth/registration.mjs.map +1 -0
  81. package/dist/internal/oauth/state.mjs +107 -0
  82. package/dist/internal/oauth/state.mjs.map +1 -0
  83. package/dist/internal/oauth/target.d.mts +31 -0
  84. package/dist/internal/oauth/target.mjs +273 -0
  85. package/dist/internal/oauth/target.mjs.map +1 -0
  86. package/dist/internal/oauth-kernel.d.mts +1423 -0
  87. package/dist/internal/oauth-kernel.mjs +187 -0
  88. package/dist/internal/oauth-kernel.mjs.map +1 -0
  89. package/dist/internal/oauth-proxy.d.mts +31 -0
  90. package/dist/internal/oauth-proxy.mjs +129 -0
  91. package/dist/internal/oauth-proxy.mjs.map +1 -0
  92. package/dist/internal/passkey/write-state.mjs +9 -1
  93. package/dist/internal/passkey/write-state.mjs.map +1 -1
  94. package/dist/internal/passkey-kernel.d.mts +9 -9
  95. package/dist/internal/{password-attempts.d.mts → password-credentials.d.mts} +3 -4
  96. package/dist/internal/password-credentials.mjs +121 -0
  97. package/dist/internal/password-credentials.mjs.map +1 -0
  98. package/dist/internal/password-kernel.d.mts +8 -24
  99. package/dist/internal/password-kernel.mjs +5 -43
  100. package/dist/internal/password-kernel.mjs.map +1 -1
  101. package/dist/internal/persistence.d.mts +1 -1
  102. package/dist/internal/persistence.mjs +2 -2
  103. package/dist/internal/persistence.mjs.map +1 -1
  104. package/dist/internal/query-operations.d.mts +2 -0
  105. package/dist/internal/session-kernel.d.mts +2 -2
  106. package/dist/internal/session-kernel.mjs +74 -18
  107. package/dist/internal/session-kernel.mjs.map +1 -1
  108. package/dist/internal/sql-oauth-connected-model.d.mts +29 -0
  109. package/dist/internal/sql-oauth-connected-model.mjs +7 -0
  110. package/dist/internal/sql-oauth-connected-model.mjs.map +1 -0
  111. package/dist/internal/sql-oauth-model.d.mts +60 -0
  112. package/dist/internal/sql-oauth-model.mjs +10 -0
  113. package/dist/internal/sql-oauth-model.mjs.map +1 -0
  114. package/dist/internal/sql-query.d.mts +12 -0
  115. package/dist/internal/sql-query.mjs +15 -18
  116. package/dist/internal/sql-query.mjs.map +1 -1
  117. package/dist/internal/sql-storage-validation.mjs +54 -0
  118. package/dist/internal/sql-storage-validation.mjs.map +1 -0
  119. package/dist/internal/storage-mapping.mjs +1 -37
  120. package/dist/internal/storage-mapping.mjs.map +1 -1
  121. package/dist/internal/storage-plans.d.mts +7 -0
  122. package/dist/internal/storage-plans.mjs +189 -0
  123. package/dist/internal/storage-plans.mjs.map +1 -0
  124. package/dist/internal/storage-tables.d.mts +0 -56
  125. package/dist/internal/storage-tables.mjs +0 -17
  126. package/dist/internal/storage-tables.mjs.map +1 -1
  127. package/dist/internal/storage-validation.d.mts +6 -1
  128. package/dist/internal/storage-validation.mjs +42 -1
  129. package/dist/internal/storage-validation.mjs.map +1 -1
  130. package/dist/internal/transaction-kernel.mjs +3 -2
  131. package/dist/internal/transaction-kernel.mjs.map +1 -1
  132. package/package.json +1 -1
  133. package/src/Adapter.ts +89 -5
  134. package/src/OAuthPersistence.ts +427 -0
  135. package/src/index.ts +3 -0
  136. package/src/internal/configuration.ts +1 -3
  137. package/src/internal/email-kernel.ts +2 -1
  138. package/src/internal/models/oauth-connected-model.ts +396 -0
  139. package/src/internal/models/oauth-model.ts +708 -0
  140. package/src/internal/models/password-model.ts +2 -57
  141. package/src/internal/native-sql-table.ts +14 -0
  142. package/src/internal/oauth/accounts.ts +839 -0
  143. package/src/internal/oauth/connected-access.ts +388 -0
  144. package/src/internal/oauth/connected-collection.ts +345 -0
  145. package/src/internal/oauth/connected-custody.ts +308 -0
  146. package/src/internal/oauth/connected-flow.ts +562 -0
  147. package/src/internal/oauth/connected-input.ts +147 -0
  148. package/src/internal/oauth/connected-keys.ts +31 -0
  149. package/src/internal/oauth/connected-maintenance.ts +379 -0
  150. package/src/internal/oauth/connected-management.ts +391 -0
  151. package/src/internal/oauth/connected-reference.ts +135 -0
  152. package/src/internal/oauth/connected-settlement.ts +278 -0
  153. package/src/internal/oauth/connected-sign-in.ts +472 -0
  154. package/src/internal/oauth/connected-state.ts +924 -0
  155. package/src/internal/oauth/connected-target.ts +307 -0
  156. package/src/internal/oauth/flow.ts +505 -0
  157. package/src/internal/oauth/input.ts +201 -0
  158. package/src/internal/oauth/owner.ts +22 -0
  159. package/src/internal/oauth/query-compiler.ts +15 -0
  160. package/src/internal/oauth/registration.ts +676 -0
  161. package/src/internal/oauth/state.ts +218 -0
  162. package/src/internal/oauth/target.ts +803 -0
  163. package/src/internal/oauth-kernel.ts +294 -0
  164. package/src/internal/oauth-proxy.ts +176 -0
  165. package/src/internal/passkey/write-state.ts +18 -4
  166. package/src/internal/password-credentials.ts +245 -0
  167. package/src/internal/password-kernel.ts +7 -99
  168. package/src/internal/persistence.ts +1 -1
  169. package/src/internal/query-operations.ts +2 -0
  170. package/src/internal/session-kernel.ts +143 -55
  171. package/src/internal/sql-oauth-connected-model.ts +145 -0
  172. package/src/internal/sql-oauth-model.ts +263 -0
  173. package/src/internal/sql-query.ts +16 -13
  174. package/src/internal/sql-storage-validation.ts +64 -0
  175. package/src/internal/storage-mapping.ts +0 -37
  176. package/src/internal/storage-plans.ts +218 -0
  177. package/src/internal/storage-tables.ts +0 -20
  178. package/src/internal/storage-validation.ts +58 -0
  179. package/src/internal/transaction-kernel.ts +6 -2
  180. package/dist/internal/password-attempts.mjs +0 -197
  181. package/dist/internal/password-attempts.mjs.map +0 -1
  182. package/src/internal/password-attempts.ts +0 -466
@@ -0,0 +1,187 @@
1
+ import { requireStandalone } from "./standalone.mjs";
2
+ import { makeTransactionKernel } from "./transaction-kernel.mjs";
3
+ import { makeTransactionExecutionKernel } from "./transaction-execution-kernel.mjs";
4
+ import { OAuthTransactionExecution } from "./oauth/owner.mjs";
5
+ import { OAuthQueryCompiler } from "./oauth/query-compiler.mjs";
6
+ import { captureOAuthMapping, unavailable } from "./oauth/state.mjs";
7
+ import { OAuthFlow } from "./oauth/flow.mjs";
8
+ import { OAuthRegistration } from "./oauth/registration.mjs";
9
+ import { OAuthAccounts } from "./oauth/accounts.mjs";
10
+ import { OAuthConnectedState } from "./oauth/connected-state.mjs";
11
+ import { OAuthConnectedCustody } from "./oauth/connected-custody.mjs";
12
+ import { OAuthConnectedFlow } from "./oauth/connected-flow.mjs";
13
+ import { OAuthConnectedSettlement } from "./oauth/connected-settlement.mjs";
14
+ import { OAuthConnectedAccess } from "./oauth/connected-access.mjs";
15
+ import { OAuthConnectedCollection } from "./oauth/connected-collection.mjs";
16
+ import { OAuthConnectedMaintenance } from "./oauth/connected-maintenance.mjs";
17
+ import { OAuthConnectedManagement } from "./oauth/connected-management.mjs";
18
+ import { makeOAuthConnectedReferenceKernel } from "./oauth/connected-reference.mjs";
19
+ import { OAuthConnectedSignIn } from "./oauth/connected-sign-in.mjs";
20
+ import { OAuthTarget, oauthAccountsPersistenceLayer, oauthRegistrationAuthorityLayer, oauthRegistrationIntentsLayer, oauthSignInPersistenceLayer } from "./oauth/target.mjs";
21
+ import { OAuthConnectedTarget, oauthConnectedPersistenceLayer, oauthConnectedRevocationsLayer } from "./oauth/connected-target.mjs";
22
+ import { Effect, Layer } from "effect";
23
+ //#region src/internal/oauth-kernel.ts
24
+ /** Adapter composition root. Shared operation Layers acquire their dependencies;
25
+ * database and transaction services are still resolved by each operation. */
26
+ const makeOAuthKernel = (operations, dialect) => {
27
+ const transactions = makeTransactionKernel(operations);
28
+ const connectedReference = makeOAuthConnectedReferenceKernel(operations, dialect);
29
+ const compilerLive = Layer.succeed(OAuthQueryCompiler, {
30
+ ...operations,
31
+ ...transactions.makeTransactionRows(unavailable),
32
+ both: transactions.both,
33
+ connectedReferenceCondition: connectedReference.connectedReferenceCondition
34
+ });
35
+ const executionLive = Layer.succeed(OAuthTransactionExecution, makeTransactionExecutionKernel(transactions));
36
+ const flowLive = OAuthFlow.layer.pipe(Layer.provide([compilerLive]));
37
+ const registrationLive = OAuthRegistration.layer.pipe(Layer.provide([compilerLive, flowLive]));
38
+ const accountsLive = OAuthAccounts.layer.pipe(Layer.provide([
39
+ compilerLive,
40
+ flowLive,
41
+ registrationLive
42
+ ]));
43
+ const targetLive = OAuthTarget.layer.pipe(Layer.provide([
44
+ compilerLive,
45
+ accountsLive,
46
+ flowLive,
47
+ registrationLive,
48
+ executionLive
49
+ ]));
50
+ const connectedStateLive = OAuthConnectedState.layer.pipe(Layer.provide([compilerLive, flowLive]));
51
+ const connectedFlowLive = OAuthConnectedFlow.layer.pipe(Layer.provide([
52
+ compilerLive,
53
+ connectedStateLive,
54
+ registrationLive
55
+ ]));
56
+ const connectedCustodyLive = OAuthConnectedCustody.layer.pipe(Layer.provide([compilerLive, connectedStateLive]));
57
+ const connectedCollectionLive = OAuthConnectedCollection.layer.pipe(Layer.provide([
58
+ compilerLive,
59
+ connectedCustodyLive,
60
+ connectedFlowLive,
61
+ connectedStateLive
62
+ ]));
63
+ const connectedSettlementLive = OAuthConnectedSettlement.layer.pipe(Layer.provide([
64
+ compilerLive,
65
+ connectedCustodyLive,
66
+ connectedFlowLive,
67
+ connectedStateLive
68
+ ]));
69
+ const connectedAccessLive = OAuthConnectedAccess.layer.pipe(Layer.provide([
70
+ compilerLive,
71
+ connectedCustodyLive,
72
+ connectedFlowLive,
73
+ connectedSettlementLive,
74
+ connectedStateLive
75
+ ]));
76
+ const connectedManagementLive = OAuthConnectedManagement.layer.pipe(Layer.provide([
77
+ compilerLive,
78
+ connectedAccessLive,
79
+ connectedCustodyLive,
80
+ connectedFlowLive,
81
+ connectedStateLive
82
+ ]));
83
+ const connectedMaintenanceLive = OAuthConnectedMaintenance.layer.pipe(Layer.provide([
84
+ compilerLive,
85
+ connectedCollectionLive,
86
+ connectedCustodyLive,
87
+ connectedFlowLive,
88
+ connectedStateLive
89
+ ]));
90
+ const connectedSignInLive = OAuthConnectedSignIn.layer.pipe(Layer.provide([
91
+ compilerLive,
92
+ connectedCustodyLive,
93
+ connectedFlowLive,
94
+ connectedSettlementLive,
95
+ connectedStateLive,
96
+ flowLive
97
+ ]));
98
+ const connectedTargetLive = OAuthConnectedTarget.layer.pipe(Layer.provide([
99
+ connectedAccessLive,
100
+ connectedFlowLive,
101
+ connectedMaintenanceLive,
102
+ connectedManagementLive,
103
+ connectedSettlementLive,
104
+ connectedSignInLive,
105
+ connectedStateLive,
106
+ targetLive
107
+ ]));
108
+ const makeTargetOAuthSignInServices = (mapping, configuration) => {
109
+ const captured = captureOAuthMapping(mapping);
110
+ return Effect.flatMap(OAuthTarget, (service) => service.makeTargetOAuthSignInServices(captured, configuration)).pipe(Effect.provide(targetLive, { local: true }));
111
+ };
112
+ const makeTargetOAuthRegistrationIntentServices = (mapping, configuration) => {
113
+ const captured = captureOAuthMapping(mapping);
114
+ return Effect.flatMap(OAuthTarget, (service) => service.makeTargetOAuthRegistrationIntentServices(captured, configuration)).pipe(Effect.provide(targetLive, { local: true }));
115
+ };
116
+ const makeTargetOAuthRegistrationServices = (mapping, configuration) => {
117
+ const captured = captureOAuthMapping(mapping);
118
+ return Effect.flatMap(OAuthTarget, (service) => service.makeTargetOAuthRegistrationServices(captured, configuration)).pipe(Effect.provide(targetLive, { local: true }));
119
+ };
120
+ const makeTargetOAuthAccountsServices = (mapping, configuration) => {
121
+ const captured = captureOAuthMapping(mapping);
122
+ return Effect.flatMap(OAuthTarget, (service) => service.makeTargetOAuthAccountsServices(captured, configuration)).pipe(Effect.provide(targetLive, { local: true }));
123
+ };
124
+ const coordinateTargetOAuthRegistration = (database, mapping, configuration, owner) => {
125
+ const captured = captureOAuthMapping(mapping);
126
+ return Effect.flatMap(OAuthTarget, (service) => service.coordinateTargetOAuthRegistration(database, captured, configuration, owner)).pipe(Effect.provide(targetLive, { local: true }));
127
+ };
128
+ const coordinateTargetOAuthSignIn = (database, mapping, configuration, owner) => {
129
+ const captured = captureOAuthMapping(mapping);
130
+ return Effect.flatMap(OAuthTarget, (service) => service.coordinateTargetOAuthSignIn(database, captured, configuration, owner)).pipe(Effect.provide(targetLive, { local: true }));
131
+ };
132
+ const coordinateTargetOAuthRegistrationIntents = (database, mapping, configuration, owner) => {
133
+ const captured = captureOAuthMapping(mapping);
134
+ return Effect.flatMap(OAuthTarget, (service) => service.coordinateTargetOAuthRegistrationIntents(database, captured, configuration, owner)).pipe(Effect.provide(targetLive, { local: true }));
135
+ };
136
+ const coordinateTargetOAuthAccounts = (database, mapping, configuration, owner) => {
137
+ const captured = captureOAuthMapping(mapping);
138
+ return Effect.flatMap(OAuthTarget, (service) => service.coordinateTargetOAuthAccounts(database, captured, configuration, owner)).pipe(Effect.provide(targetLive, { local: true }));
139
+ };
140
+ const makeTargetOAuthConnectedServices = (mapping, configuration) => {
141
+ const captured = captureOAuthMapping(mapping);
142
+ return Effect.flatMap(OAuthConnectedTarget, (service) => service.makeTargetOAuthConnectedServices(captured, configuration)).pipe(Effect.provide(connectedTargetLive, { local: true }));
143
+ };
144
+ const makeTargetOAuthConnectedRevocationServices = (mapping, configuration) => {
145
+ const captured = captureOAuthMapping(mapping);
146
+ return Effect.flatMap(OAuthConnectedTarget, (service) => service.makeTargetOAuthConnectedRevocationServices(captured, configuration)).pipe(Effect.provide(connectedTargetLive, { local: true }));
147
+ };
148
+ const coordinateTargetOAuthConnected = (database, mapping, configuration, owner) => {
149
+ const captured = captureOAuthMapping(mapping);
150
+ return Effect.flatMap(OAuthConnectedTarget, (service) => service.coordinateTargetOAuthConnected(database, captured, configuration, owner)).pipe(Effect.provide(connectedTargetLive, { local: true }));
151
+ };
152
+ const coordinateTargetOAuthConnectedRevocations = (database, mapping, configuration, owner) => {
153
+ const captured = captureOAuthMapping(mapping);
154
+ return Effect.flatMap(OAuthConnectedTarget, (service) => service.coordinateTargetOAuthConnectedRevocations(database, captured, configuration, owner)).pipe(Effect.provide(connectedTargetLive, { local: true }));
155
+ };
156
+ const sqlClientOAuthStandaloneGuard = (service) => requireStandalone(unavailable, service);
157
+ return {
158
+ target: {
159
+ makeTargetOAuthSignInServices,
160
+ makeTargetOAuthRegistrationIntentServices,
161
+ makeTargetOAuthRegistrationServices,
162
+ makeTargetOAuthAccountsServices,
163
+ coordinateTargetOAuthRegistration,
164
+ coordinateTargetOAuthSignIn,
165
+ coordinateTargetOAuthRegistrationIntents,
166
+ coordinateTargetOAuthAccounts,
167
+ sqlClientOAuthStandaloneGuard,
168
+ oauthAccountsPersistenceLayer,
169
+ oauthSignInPersistenceLayer,
170
+ oauthRegistrationIntentsLayer,
171
+ oauthRegistrationAuthorityLayer
172
+ },
173
+ connectedTarget: {
174
+ makeTargetOAuthConnectedServices,
175
+ makeTargetOAuthConnectedRevocationServices,
176
+ coordinateTargetOAuthConnected,
177
+ coordinateTargetOAuthConnectedRevocations,
178
+ oauthConnectedPersistenceLayer,
179
+ oauthConnectedRevocationsLayer
180
+ },
181
+ connectedReference
182
+ };
183
+ };
184
+ //#endregion
185
+ export { makeOAuthKernel };
186
+
187
+ //# sourceMappingURL=oauth-kernel.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"oauth-kernel.mjs","names":[],"sources":["../../src/internal/oauth-kernel.ts"],"sourcesContent":["import { Effect, Layer } from \"effect\";\nimport type { SqlClient } from \"effect/sql/SqlClient\";\n\nimport { OAuthAccounts } from \"./oauth/accounts\";\nimport { OAuthConnectedAccess } from \"./oauth/connected-access\";\nimport { OAuthConnectedCollection } from \"./oauth/connected-collection\";\nimport { OAuthConnectedCustody } from \"./oauth/connected-custody\";\nimport { OAuthConnectedFlow } from \"./oauth/connected-flow\";\nimport { OAuthConnectedMaintenance } from \"./oauth/connected-maintenance\";\nimport { OAuthConnectedManagement } from \"./oauth/connected-management\";\nimport { makeOAuthConnectedReferenceKernel } from \"./oauth/connected-reference\";\nimport { OAuthConnectedSettlement } from \"./oauth/connected-settlement\";\nimport { OAuthConnectedSignIn } from \"./oauth/connected-sign-in\";\nimport { OAuthConnectedState } from \"./oauth/connected-state\";\nimport {\n OAuthConnectedTarget,\n oauthConnectedPersistenceLayer,\n oauthConnectedRevocationsLayer,\n} from \"./oauth/connected-target\";\nimport { OAuthFlow } from \"./oauth/flow\";\nimport { OAuthTransactionExecution } from \"./oauth/owner\";\nimport { OAuthQueryCompiler } from \"./oauth/query-compiler\";\nimport { OAuthRegistration } from \"./oauth/registration\";\nimport { captureOAuthMapping, unavailable } from \"./oauth/state\";\nimport {\n OAuthTarget,\n oauthAccountsPersistenceLayer,\n oauthSignInPersistenceLayer,\n oauthRegistrationIntentsLayer,\n oauthRegistrationAuthorityLayer,\n} from \"./oauth/target\";\nimport type { QueryOperations } from \"./query-operations\";\nimport { requireStandalone } from \"./standalone\";\nimport { makeTransactionExecutionKernel } from \"./transaction-execution-kernel\";\nimport { makeTransactionKernel } from \"./transaction-kernel\";\n\nexport type OAuthKernel = ReturnType<typeof makeOAuthKernel>;\n\n/** Adapter composition root. Shared operation Layers acquire their dependencies;\n * database and transaction services are still resolved by each operation. */\nexport const makeOAuthKernel = (\n operations: QueryOperations,\n dialect: (table: object) => \"pg\" | \"sqlite\" | \"mysql\",\n) => {\n const transactions = makeTransactionKernel(operations);\n const connectedReference = makeOAuthConnectedReferenceKernel(operations, dialect);\n\n const compilerLive = Layer.succeed(OAuthQueryCompiler, {\n ...operations,\n ...transactions.makeTransactionRows(unavailable),\n both: transactions.both,\n connectedReferenceCondition: connectedReference.connectedReferenceCondition,\n });\n\n const executionLive = Layer.succeed(\n OAuthTransactionExecution,\n makeTransactionExecutionKernel(transactions),\n );\n\n const flowLive = OAuthFlow.layer.pipe(Layer.provide([compilerLive]));\n const registrationLive = OAuthRegistration.layer.pipe(Layer.provide([compilerLive, flowLive]));\n\n const accountsLive = OAuthAccounts.layer.pipe(\n Layer.provide([compilerLive, flowLive, registrationLive]),\n );\n\n const targetLive = OAuthTarget.layer.pipe(\n Layer.provide([compilerLive, accountsLive, flowLive, registrationLive, executionLive]),\n );\n\n const connectedStateLive = OAuthConnectedState.layer.pipe(\n Layer.provide([compilerLive, flowLive]),\n );\n\n const connectedFlowLive = OAuthConnectedFlow.layer.pipe(\n Layer.provide([compilerLive, connectedStateLive, registrationLive]),\n );\n\n const connectedCustodyLive = OAuthConnectedCustody.layer.pipe(\n Layer.provide([compilerLive, connectedStateLive]),\n );\n\n const connectedCollectionLive = OAuthConnectedCollection.layer.pipe(\n Layer.provide([compilerLive, connectedCustodyLive, connectedFlowLive, connectedStateLive]),\n );\n\n const connectedSettlementLive = OAuthConnectedSettlement.layer.pipe(\n Layer.provide([compilerLive, connectedCustodyLive, connectedFlowLive, connectedStateLive]),\n );\n\n const connectedAccessLive = OAuthConnectedAccess.layer.pipe(\n Layer.provide([\n compilerLive,\n connectedCustodyLive,\n connectedFlowLive,\n connectedSettlementLive,\n connectedStateLive,\n ]),\n );\n\n const connectedManagementLive = OAuthConnectedManagement.layer.pipe(\n Layer.provide([\n compilerLive,\n connectedAccessLive,\n connectedCustodyLive,\n connectedFlowLive,\n connectedStateLive,\n ]),\n );\n\n const connectedMaintenanceLive = OAuthConnectedMaintenance.layer.pipe(\n Layer.provide([\n compilerLive,\n connectedCollectionLive,\n connectedCustodyLive,\n connectedFlowLive,\n connectedStateLive,\n ]),\n );\n\n const connectedSignInLive = OAuthConnectedSignIn.layer.pipe(\n Layer.provide([\n compilerLive,\n connectedCustodyLive,\n connectedFlowLive,\n connectedSettlementLive,\n connectedStateLive,\n flowLive,\n ]),\n );\n\n const connectedTargetLive = OAuthConnectedTarget.layer.pipe(\n Layer.provide([\n connectedAccessLive,\n connectedFlowLive,\n connectedMaintenanceLive,\n connectedManagementLive,\n connectedSettlementLive,\n connectedSignInLive,\n connectedStateLive,\n targetLive,\n ]),\n );\n\n // Keep shared operation Layers local to this adapter compiler, even inside another\n // coordinator. Preserve constructor-time snapshots before deferred acquisition.\n const makeTargetOAuthSignInServices: OAuthTarget[\"Service\"][\"makeTargetOAuthSignInServices\"] = (\n mapping,\n configuration,\n ) => {\n const captured = captureOAuthMapping(mapping);\n\n return Effect.flatMap(OAuthTarget, (service) =>\n service.makeTargetOAuthSignInServices(captured, configuration),\n ).pipe(Effect.provide(targetLive, { local: true }));\n };\n\n const makeTargetOAuthRegistrationIntentServices: OAuthTarget[\"Service\"][\"makeTargetOAuthRegistrationIntentServices\"] =\n (mapping, configuration) => {\n const captured = captureOAuthMapping(mapping);\n\n return Effect.flatMap(OAuthTarget, (service) =>\n service.makeTargetOAuthRegistrationIntentServices(captured, configuration),\n ).pipe(Effect.provide(targetLive, { local: true }));\n };\n\n const makeTargetOAuthRegistrationServices: OAuthTarget[\"Service\"][\"makeTargetOAuthRegistrationServices\"] =\n (mapping, configuration) => {\n const captured = captureOAuthMapping(mapping);\n\n return Effect.flatMap(OAuthTarget, (service) =>\n service.makeTargetOAuthRegistrationServices(captured, configuration),\n ).pipe(Effect.provide(targetLive, { local: true }));\n };\n\n const makeTargetOAuthAccountsServices: OAuthTarget[\"Service\"][\"makeTargetOAuthAccountsServices\"] =\n (mapping, configuration) => {\n const captured = captureOAuthMapping(mapping);\n\n return Effect.flatMap(OAuthTarget, (service) =>\n service.makeTargetOAuthAccountsServices(captured, configuration),\n ).pipe(Effect.provide(targetLive, { local: true }));\n };\n\n const coordinateTargetOAuthRegistration: OAuthTarget[\"Service\"][\"coordinateTargetOAuthRegistration\"] =\n (database, mapping, configuration, owner) => {\n const captured = captureOAuthMapping(mapping);\n\n return Effect.flatMap(OAuthTarget, (service) =>\n service.coordinateTargetOAuthRegistration(database, captured, configuration, owner),\n ).pipe(Effect.provide(targetLive, { local: true }));\n };\n\n const coordinateTargetOAuthSignIn: OAuthTarget[\"Service\"][\"coordinateTargetOAuthSignIn\"] = (\n database,\n mapping,\n configuration,\n owner,\n ) => {\n const captured = captureOAuthMapping(mapping);\n\n return Effect.flatMap(OAuthTarget, (service) =>\n service.coordinateTargetOAuthSignIn(database, captured, configuration, owner),\n ).pipe(Effect.provide(targetLive, { local: true }));\n };\n\n const coordinateTargetOAuthRegistrationIntents: OAuthTarget[\"Service\"][\"coordinateTargetOAuthRegistrationIntents\"] =\n (database, mapping, configuration, owner) => {\n const captured = captureOAuthMapping(mapping);\n\n return Effect.flatMap(OAuthTarget, (service) =>\n service.coordinateTargetOAuthRegistrationIntents(database, captured, configuration, owner),\n ).pipe(Effect.provide(targetLive, { local: true }));\n };\n\n const coordinateTargetOAuthAccounts: OAuthTarget[\"Service\"][\"coordinateTargetOAuthAccounts\"] = (\n database,\n mapping,\n configuration,\n owner,\n ) => {\n const captured = captureOAuthMapping(mapping);\n\n return Effect.flatMap(OAuthTarget, (service) =>\n service.coordinateTargetOAuthAccounts(database, captured, configuration, owner),\n ).pipe(Effect.provide(targetLive, { local: true }));\n };\n\n const makeTargetOAuthConnectedServices: OAuthConnectedTarget[\"Service\"][\"makeTargetOAuthConnectedServices\"] =\n (mapping, configuration) => {\n const captured = captureOAuthMapping(mapping);\n\n return Effect.flatMap(OAuthConnectedTarget, (service) =>\n service.makeTargetOAuthConnectedServices(captured, configuration),\n ).pipe(Effect.provide(connectedTargetLive, { local: true }));\n };\n\n const makeTargetOAuthConnectedRevocationServices: OAuthConnectedTarget[\"Service\"][\"makeTargetOAuthConnectedRevocationServices\"] =\n (mapping, configuration) => {\n const captured = captureOAuthMapping(mapping);\n\n return Effect.flatMap(OAuthConnectedTarget, (service) =>\n service.makeTargetOAuthConnectedRevocationServices(captured, configuration),\n ).pipe(Effect.provide(connectedTargetLive, { local: true }));\n };\n\n const coordinateTargetOAuthConnected: OAuthConnectedTarget[\"Service\"][\"coordinateTargetOAuthConnected\"] =\n (database, mapping, configuration, owner) => {\n const captured = captureOAuthMapping(mapping);\n\n return Effect.flatMap(OAuthConnectedTarget, (service) =>\n service.coordinateTargetOAuthConnected(database, captured, configuration, owner),\n ).pipe(Effect.provide(connectedTargetLive, { local: true }));\n };\n\n const coordinateTargetOAuthConnectedRevocations: OAuthConnectedTarget[\"Service\"][\"coordinateTargetOAuthConnectedRevocations\"] =\n (database, mapping, configuration, owner) => {\n const captured = captureOAuthMapping(mapping);\n\n return Effect.flatMap(OAuthConnectedTarget, (service) =>\n service.coordinateTargetOAuthConnectedRevocations(database, captured, configuration, owner),\n ).pipe(Effect.provide(connectedTargetLive, { local: true }));\n };\n\n const sqlClientOAuthStandaloneGuard = (service: SqlClient[\"transactionService\"] | undefined) =>\n requireStandalone(unavailable, service);\n\n return {\n target: {\n makeTargetOAuthSignInServices,\n makeTargetOAuthRegistrationIntentServices,\n makeTargetOAuthRegistrationServices,\n makeTargetOAuthAccountsServices,\n coordinateTargetOAuthRegistration,\n coordinateTargetOAuthSignIn,\n coordinateTargetOAuthRegistrationIntents,\n coordinateTargetOAuthAccounts,\n sqlClientOAuthStandaloneGuard,\n oauthAccountsPersistenceLayer,\n oauthSignInPersistenceLayer,\n oauthRegistrationIntentsLayer,\n oauthRegistrationAuthorityLayer,\n },\n connectedTarget: {\n makeTargetOAuthConnectedServices,\n makeTargetOAuthConnectedRevocationServices,\n coordinateTargetOAuthConnected,\n coordinateTargetOAuthConnectedRevocations,\n oauthConnectedPersistenceLayer,\n oauthConnectedRevocationsLayer,\n },\n connectedReference,\n };\n};\n"],"mappings":"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"}
@@ -0,0 +1,31 @@
1
+ import { Effect, Layer } from "effect";
2
+ import { SqlClient } from "effect/sql";
3
+ import { Persistence, Record, Unavailable } from "@yielded/auth/OAuthProxy";
4
+ //#region src/internal/oauth-proxy.d.ts
5
+ export declare const oauthProxyColumns: {
6
+ readonly namespace: "namespace";
7
+ readonly flowId: "flow_id";
8
+ readonly version: "version";
9
+ readonly stage: "stage";
10
+ readonly context: "context";
11
+ readonly expiresAtMillis: "expires_at_millis";
12
+ readonly handoffExpiresAtMillis: "handoff_expires_at_millis";
13
+ readonly payload: "payload";
14
+ };
15
+ /** Plain text and integer-millisecond storage; adapters supply physical names. */
16
+ export interface OAuthProxySqlTable {
17
+ readonly name: string;
18
+ readonly schema?: string;
19
+ readonly columns: { readonly [K in keyof typeof oauthProxyColumns]: string; };
20
+ }
21
+ export declare const makeOAuthProxyPersistence: (table: OAuthProxySqlTable) => Effect.Effect<{
22
+ readonly get: (namespace: string, id: string) => Effect.Effect<Record | undefined, Unavailable>;
23
+ readonly insert: (namespace: string, record: Record) => Effect.Effect<boolean, Unavailable>;
24
+ readonly compareAndSet: (namespace: string, version: string, record: Record) => Effect.Effect<boolean, Unavailable>;
25
+ }, Unavailable, SqlClient.SqlClient>;
26
+ export declare const OAuthProxyPersistence: {
27
+ migration: string;
28
+ layer: Layer.Layer<Persistence, Unavailable, SqlClient.SqlClient>;
29
+ };
30
+ //#endregion
31
+ //# sourceMappingURL=oauth-proxy.d.mts.map
@@ -0,0 +1,129 @@
1
+ import { identifier } from "./sql-table.mjs";
2
+ import { requireStandalone } from "./standalone.mjs";
3
+ import { Effect, Layer, Schema } from "effect";
4
+ import { SqlClient } from "effect/sql";
5
+ import { FlowContext, Persistence, Record, Unavailable } from "@yielded/auth/OAuthProxy";
6
+ //#region src/internal/oauth-proxy.ts
7
+ const oauthProxyColumns = {
8
+ namespace: "namespace",
9
+ flowId: "flow_id",
10
+ version: "version",
11
+ stage: "stage",
12
+ context: "context",
13
+ expiresAtMillis: "expires_at_millis",
14
+ handoffExpiresAtMillis: "handoff_expires_at_millis",
15
+ payload: "payload"
16
+ };
17
+ const codec = Schema.fromJsonString(Record);
18
+ const contextCodec = Schema.fromJsonString(FlowContext);
19
+ const Row = Schema.Struct({
20
+ payload: Schema.String,
21
+ version: Schema.String,
22
+ stage: Schema.String,
23
+ context: Schema.String,
24
+ expiry: Schema.String,
25
+ deadline: Schema.NullOr(Schema.String)
26
+ });
27
+ /** SQLite/D1 and PostgreSQL; apply once through application migrations.
28
+ * Retain terminal records until expires_at_millis, then expired rows may be deleted.
29
+ * Context and stage columns guard each standalone transition without a prior read.
30
+ */
31
+ const migration = `CREATE TABLE yielded_oauth_proxy (
32
+ namespace TEXT NOT NULL,
33
+ flow_id TEXT NOT NULL,
34
+ version TEXT NOT NULL,
35
+ stage TEXT NOT NULL CHECK (stage IN ('Pending', 'Exchanging', 'Ready', 'Consumed')),
36
+ context TEXT NOT NULL,
37
+ expires_at_millis BIGINT NOT NULL,
38
+ handoff_expires_at_millis BIGINT,
39
+ payload TEXT NOT NULL,
40
+ PRIMARY KEY (namespace, flow_id),
41
+ CHECK ((stage = 'Ready' AND handoff_expires_at_millis IS NOT NULL)
42
+ OR (stage <> 'Ready' AND handoff_expires_at_millis IS NULL))
43
+ )`;
44
+ const makeOAuthProxyPersistence = Effect.fnUntraced(function* (table) {
45
+ const sql = (yield* SqlClient.SqlClient).withoutTransforms();
46
+ if (!sql.onDialectOrElse({
47
+ sqlite: () => true,
48
+ pg: () => true,
49
+ orElse: () => false
50
+ })) return yield* Unavailable.make({});
51
+ const names = Object.values(table.columns);
52
+ if ([
53
+ table.name,
54
+ table.schema ?? "main",
55
+ ...names
56
+ ].some((name) => !name || name.includes("\0")) || new Set(names).size !== names.length) return yield* Unavailable.make({});
57
+ const name = sql.literal((table.schema === void 0 ? "" : `${identifier(table.schema)}.`) + identifier(table.name));
58
+ const column = (key) => sql.literal(identifier(table.columns[key]));
59
+ const standalone = requireStandalone(() => Unavailable.make({}), sql.transactionService);
60
+ const failure = (effect) => effect.pipe(Effect.mapError(() => Unavailable.make({})));
61
+ const clock = sql.onDialectOrElse({
62
+ sqlite: () => sql.literal("CAST((julianday('now') - 2440587.5) * 86400000 AS INTEGER)"),
63
+ orElse: () => sql.literal("CAST(EXTRACT(EPOCH FROM clock_timestamp()) * 1000 AS BIGINT)")
64
+ });
65
+ return Persistence.of({
66
+ get: Effect.fnUntraced(function* (namespace, id) {
67
+ yield* standalone;
68
+ const rows = yield* sql`SELECT ${column("payload")} AS payload,
69
+ ${column("version")} AS version, ${column("stage")} AS stage, ${column("context")} AS context,
70
+ CAST(${column("expiresAtMillis")} AS TEXT) AS expiry,
71
+ CAST(${column("handoffExpiresAtMillis")} AS TEXT) AS deadline
72
+ FROM ${name} WHERE ${column("namespace")} = ${namespace} AND ${column("flowId")} = ${id}`;
73
+ if (rows.length === 0) return void 0;
74
+ if (rows.length !== 1) return yield* Unavailable.make({});
75
+ const row = yield* Schema.decodeUnknownEffect(Row)(rows[0]);
76
+ const record = yield* Schema.decodeEffect(codec)(row.payload);
77
+ const context = yield* Schema.encodeEffect(contextCodec)(record.context);
78
+ if (record.context.id !== id || record.version !== row.version || record._tag !== row.stage || context !== row.context || String(record.context.expiresAtMillis) !== row.expiry || (record._tag === "Ready" ? String(record.handoffExpiresAtMillis) : null) !== row.deadline) return yield* Unavailable.make({});
79
+ return record;
80
+ }, failure),
81
+ insert: Effect.fnUntraced(function* (namespace, record) {
82
+ yield* standalone;
83
+ if (record._tag !== "Pending") return yield* Unavailable.make({});
84
+ const payload = yield* Schema.encodeEffect(codec)(record);
85
+ const context = yield* Schema.encodeEffect(contextCodec)(record.context);
86
+ return (yield* sql`INSERT INTO ${name}
87
+ (${column("namespace")}, ${column("flowId")}, ${column("version")}, ${column("stage")},
88
+ ${column("context")}, ${column("expiresAtMillis")}, ${column("payload")})
89
+ SELECT ${namespace}, ${record.context.id}, ${record.version}, ${record._tag},
90
+ ${context}, ${record.context.expiresAtMillis}, ${payload}
91
+ WHERE ${record.context.expiresAtMillis} > ${clock}
92
+ ON CONFLICT (${column("namespace")}, ${column("flowId")}) DO NOTHING
93
+ RETURNING ${column("version")}`).length === 1;
94
+ }, failure),
95
+ compareAndSet: Effect.fnUntraced(function* (namespace, version, record) {
96
+ yield* standalone;
97
+ if (version === record.version || record._tag === "Pending") return yield* Unavailable.make({});
98
+ const payload = yield* Schema.encodeEffect(codec)(record._tag === "Ready" ? record : {
99
+ _tag: record._tag,
100
+ version: record.version,
101
+ context: record.context
102
+ });
103
+ const context = yield* Schema.encodeEffect(contextCodec)(record.context);
104
+ const previous = record._tag === "Exchanging" ? "Pending" : record._tag === "Ready" ? "Exchanging" : "Ready";
105
+ const deadline = record._tag === "Ready" ? record.handoffExpiresAtMillis : null;
106
+ const consume = record._tag === "Consumed" ? sql`AND ${column("handoffExpiresAtMillis")} > ${clock}` : sql.literal("");
107
+ return (yield* sql`UPDATE ${name}
108
+ SET ${column("version")} = ${record.version}, ${column("stage")} = ${record._tag},
109
+ ${column("handoffExpiresAtMillis")} = ${deadline}, ${column("payload")} = ${payload}
110
+ WHERE ${column("namespace")} = ${namespace} AND ${column("flowId")} = ${record.context.id}
111
+ AND ${column("version")} = ${version} AND ${column("stage")} = ${previous}
112
+ AND ${column("context")} = ${context}
113
+ AND ${column("expiresAtMillis")} = ${record.context.expiresAtMillis}
114
+ AND ${column("expiresAtMillis")} > ${clock} ${consume}
115
+ RETURNING ${column("version")}`).length === 1;
116
+ }, failure)
117
+ });
118
+ });
119
+ const OAuthProxyPersistence = {
120
+ migration,
121
+ layer: Layer.effect(Persistence, makeOAuthProxyPersistence({
122
+ name: "yielded_oauth_proxy",
123
+ columns: oauthProxyColumns
124
+ }))
125
+ };
126
+ //#endregion
127
+ export { OAuthProxyPersistence, makeOAuthProxyPersistence, oauthProxyColumns };
128
+
129
+ //# sourceMappingURL=oauth-proxy.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"oauth-proxy.mjs","names":[],"sources":["../../src/internal/oauth-proxy.ts"],"sourcesContent":["import { FlowContext, Persistence, Record, Unavailable } from \"@yielded/auth/OAuthProxy\";\nimport { Effect, Layer, Schema } from \"effect\";\nimport { SqlClient } from \"effect/sql\";\n\nimport { identifier } from \"./sql-table\";\nimport { requireStandalone } from \"./standalone\";\n\nexport const oauthProxyColumns = {\n namespace: \"namespace\",\n flowId: \"flow_id\",\n version: \"version\",\n stage: \"stage\",\n context: \"context\",\n expiresAtMillis: \"expires_at_millis\",\n handoffExpiresAtMillis: \"handoff_expires_at_millis\",\n payload: \"payload\",\n} as const;\n\n/** Plain text and integer-millisecond storage; adapters supply physical names. */\nexport interface OAuthProxySqlTable {\n readonly name: string;\n readonly schema?: string;\n readonly columns: { readonly [K in keyof typeof oauthProxyColumns]: string };\n}\n\nconst codec = Schema.fromJsonString(Record);\nconst contextCodec = Schema.fromJsonString(FlowContext);\n\nconst Row = Schema.Struct({\n payload: Schema.String,\n version: Schema.String,\n stage: Schema.String,\n context: Schema.String,\n expiry: Schema.String,\n deadline: Schema.NullOr(Schema.String),\n});\n\n/** SQLite/D1 and PostgreSQL; apply once through application migrations.\n * Retain terminal records until expires_at_millis, then expired rows may be deleted.\n * Context and stage columns guard each standalone transition without a prior read.\n */\nconst migration = `CREATE TABLE yielded_oauth_proxy (\n namespace TEXT NOT NULL,\n flow_id TEXT NOT NULL,\n version TEXT NOT NULL,\n stage TEXT NOT NULL CHECK (stage IN ('Pending', 'Exchanging', 'Ready', 'Consumed')),\n context TEXT NOT NULL,\n expires_at_millis BIGINT NOT NULL,\n handoff_expires_at_millis BIGINT,\n payload TEXT NOT NULL,\n PRIMARY KEY (namespace, flow_id),\n CHECK ((stage = 'Ready' AND handoff_expires_at_millis IS NOT NULL)\n OR (stage <> 'Ready' AND handoff_expires_at_millis IS NULL))\n)`;\n\nexport const makeOAuthProxyPersistence = Effect.fnUntraced(function* (table: OAuthProxySqlTable) {\n const sql = (yield* SqlClient.SqlClient).withoutTransforms();\n\n if (!sql.onDialectOrElse({ sqlite: () => true, pg: () => true, orElse: () => false }))\n return yield* Unavailable.make({});\n\n const names = Object.values(table.columns);\n\n if (\n [table.name, table.schema ?? \"main\", ...names].some((name) => !name || name.includes(\"\\0\")) ||\n new Set(names).size !== names.length\n )\n return yield* Unavailable.make({});\n\n const name = sql.literal(\n (table.schema === undefined ? \"\" : `${identifier(table.schema)}.`) + identifier(table.name),\n );\n\n const column = (key: keyof typeof oauthProxyColumns) =>\n sql.literal(identifier(table.columns[key]));\n\n const standalone = requireStandalone(() => Unavailable.make({}), sql.transactionService);\n\n const failure = <A, E, R>(effect: Effect.Effect<A, E, R>) =>\n effect.pipe(Effect.mapError(() => Unavailable.make({})));\n\n const clock = sql.onDialectOrElse({\n sqlite: () => sql.literal(\"CAST((julianday('now') - 2440587.5) * 86400000 AS INTEGER)\"),\n orElse: () => sql.literal(\"CAST(EXTRACT(EPOCH FROM clock_timestamp()) * 1000 AS BIGINT)\"),\n });\n\n return Persistence.of({\n get: Effect.fnUntraced(function* (namespace, id) {\n yield* standalone;\n\n const rows = yield* sql`SELECT ${column(\"payload\")} AS payload,\n ${column(\"version\")} AS version, ${column(\"stage\")} AS stage, ${column(\"context\")} AS context,\n CAST(${column(\"expiresAtMillis\")} AS TEXT) AS expiry,\n CAST(${column(\"handoffExpiresAtMillis\")} AS TEXT) AS deadline\n FROM ${name} WHERE ${column(\"namespace\")} = ${namespace} AND ${column(\"flowId\")} = ${id}`;\n\n if (rows.length === 0) return undefined;\n if (rows.length !== 1) return yield* Unavailable.make({});\n const row = yield* Schema.decodeUnknownEffect(Row)(rows[0]);\n const record = yield* Schema.decodeEffect(codec)(row.payload);\n const context = yield* Schema.encodeEffect(contextCodec)(record.context);\n\n if (\n record.context.id !== id ||\n record.version !== row.version ||\n record._tag !== row.stage ||\n context !== row.context ||\n String(record.context.expiresAtMillis) !== row.expiry ||\n (record._tag === \"Ready\" ? String(record.handoffExpiresAtMillis) : null) !== row.deadline\n )\n return yield* Unavailable.make({});\n\n return record;\n }, failure),\n insert: Effect.fnUntraced(function* (namespace, record) {\n yield* standalone;\n if (record._tag !== \"Pending\") return yield* Unavailable.make({});\n const payload = yield* Schema.encodeEffect(codec)(record);\n const context = yield* Schema.encodeEffect(contextCodec)(record.context);\n\n const rows = yield* sql`INSERT INTO ${name}\n (${column(\"namespace\")}, ${column(\"flowId\")}, ${column(\"version\")}, ${column(\"stage\")},\n ${column(\"context\")}, ${column(\"expiresAtMillis\")}, ${column(\"payload\")})\n SELECT ${namespace}, ${record.context.id}, ${record.version}, ${record._tag},\n ${context}, ${record.context.expiresAtMillis}, ${payload}\n WHERE ${record.context.expiresAtMillis} > ${clock}\n ON CONFLICT (${column(\"namespace\")}, ${column(\"flowId\")}) DO NOTHING\n RETURNING ${column(\"version\")}`;\n\n return rows.length === 1;\n }, failure),\n compareAndSet: Effect.fnUntraced(function* (namespace, version, record) {\n yield* standalone;\n if (version === record.version || record._tag === \"Pending\")\n return yield* Unavailable.make({});\n\n // Explicitly omit private envelopes from both irreversible marker stages.\n const payload = yield* Schema.encodeEffect(codec)(\n record._tag === \"Ready\"\n ? record\n : { _tag: record._tag, version: record.version, context: record.context },\n );\n\n const context = yield* Schema.encodeEffect(contextCodec)(record.context);\n\n const previous =\n record._tag === \"Exchanging\" ? \"Pending\" : record._tag === \"Ready\" ? \"Exchanging\" : \"Ready\";\n\n const deadline = record._tag === \"Ready\" ? record.handoffExpiresAtMillis : null;\n\n const consume =\n record._tag === \"Consumed\"\n ? sql`AND ${column(\"handoffExpiresAtMillis\")} > ${clock}`\n : sql.literal(\"\");\n\n const rows = yield* sql`UPDATE ${name}\n SET ${column(\"version\")} = ${record.version}, ${column(\"stage\")} = ${record._tag},\n ${column(\"handoffExpiresAtMillis\")} = ${deadline}, ${column(\"payload\")} = ${payload}\n WHERE ${column(\"namespace\")} = ${namespace} AND ${column(\"flowId\")} = ${record.context.id}\n AND ${column(\"version\")} = ${version} AND ${column(\"stage\")} = ${previous}\n AND ${column(\"context\")} = ${context}\n AND ${column(\"expiresAtMillis\")} = ${record.context.expiresAtMillis}\n AND ${column(\"expiresAtMillis\")} > ${clock} ${consume}\n RETURNING ${column(\"version\")}`;\n\n return rows.length === 1;\n }, failure),\n });\n});\n\nconst layer = Layer.effect(\n Persistence,\n makeOAuthProxyPersistence({ name: \"yielded_oauth_proxy\", columns: oauthProxyColumns }),\n);\n\nexport const OAuthProxyPersistence = { migration, layer };\n"],"mappings":"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"}
@@ -184,7 +184,15 @@ const makePasskeyWriteStateKernel = (operations, state, transactions) => {
184
184
  owner.postconditions.push(condition);
185
185
  return true;
186
186
  });
187
- const invalidationMatches = (mapping, supplied, policy) => jsonStorage(SessionInvalidationWindow).encode(supplied) === jsonStorage(SessionInvalidationWindow).encode(mapping.invalidation.window) && (!policy.requireImmediateInvalidation || supplied.existingSessions === "immediate");
187
+ const invalidationMatches = (mapping, supplied, policy) => {
188
+ if (supplied.existingSessions === "cache-expiry" && supplied.maximumExposureMillis === 0) return false;
189
+ const authoritative = supplied.existingSessions === "cache-expiry" && mapping.invalidation.window.existingSessions === "immediate" ? {
190
+ ...supplied,
191
+ existingSessions: "immediate",
192
+ maximumExposureMillis: 0
193
+ } : supplied;
194
+ return jsonStorage(SessionInvalidationWindow).encode(authoritative) === jsonStorage(SessionInvalidationWindow).encode(mapping.invalidation.window) && (!policy.requireImmediateInvalidation || supplied.existingSessions === "immediate");
195
+ };
188
196
  const invalidate = Effect.fn("passkey.invalidateCredentialChange")(function* (mapping, subject, invalidation) {
189
197
  const owner = yield* CurrentPasskeyTransaction;
190
198
  const table = mapping.read.subject;
@@ -1 +1 @@
1
- {"version":3,"file":"write-state.mjs","names":["digest","digestText"],"sources":["../../../src/internal/passkey/write-state.ts"],"sourcesContent":["/* oxlint-disable no-explicit-any -- existing mapped-row bridge; public adapters preserve table, ID, and Effect types. */\n\nimport {\n type PasskeyActionAuthorization,\n type PasskeyCeremony,\n PasskeyBegin,\n PasskeyCredential,\n PasskeyCredentialSummary,\n PasskeyDescriptor,\n PasskeyLabel,\n PasskeyModuleId,\n PasskeyProfile,\n PasskeyRequirement,\n PasskeyRevision,\n PasskeyUserHandle,\n PasskeyManagementPolicy,\n snapshotPasskeySync,\n} from \"@yielded/auth/Passkey\";\nimport { type SubjectId } from \"@yielded/auth/Schema\";\nimport { SessionInvalidationWindow } from \"@yielded/auth/Sessions\";\nimport { DateTime, Effect, Schema } from \"effect\";\n\nimport { digest as digestText } from \"../crypto\";\nimport type { PersistenceMappingError } from \"../mapping-error\";\nimport type { QueryOperations } from \"../query-operations\";\nimport type { makeTransactionKernel } from \"../transaction-kernel\";\nimport { CurrentPasskeyTransaction } from \"./state\";\nimport type { makePasskeyStateKernel } from \"./state\";\n\nexport interface WriteSubject {\n readonly subjectId: SubjectId;\n readonly nativeId: any;\n readonly row: Record<string, any>;\n readonly revision: typeof PasskeyRevision.Type;\n}\n\nexport const makePasskeyWriteStateKernel = (\n operations: QueryOperations,\n state: Pick<\n ReturnType<typeof makePasskeyStateKernel>,\n | \"col\"\n | \"copiedRow\"\n | \"credentialKey\"\n | \"equal\"\n | \"handleKey\"\n | \"invariant\"\n | \"mappedColumns\"\n | \"sameCredential\"\n | \"sameRevision\"\n | \"subjectScope\"\n >,\n transactions: Pick<ReturnType<typeof makeTransactionKernel>, \"both\">,\n) => {\n const { sql } = operations;\n\n const {\n col,\n copiedRow,\n credentialKey,\n equal,\n handleKey,\n mappedColumns,\n sameCredential,\n sameRevision,\n subjectScope,\n } = state;\n\n const invariant: (value: unknown) => asserts value = state.invariant;\n const { both } = transactions;\n\n const jsonStorage = <S extends Schema.Codec<unknown, unknown, never, never>>(schema: S) => {\n const codec = Schema.fromJsonString(Schema.toCodecJson(Schema.toType(schema)));\n\n return {\n encode: (value: S[\"Type\"]) => Schema.encodeSync(codec)(snapshotPasskeySync(schema, value)),\n decode: (text: unknown): S[\"Type\"] => {\n // oxlint-disable-next-line no-restricted-properties -- persisted private JSON enters through its schema.\n return Schema.decodeUnknownSync(codec)(text);\n },\n };\n };\n\n const digest = <S extends Schema.Codec<unknown, unknown, never, never>>(\n schema: S,\n value: S[\"Type\"],\n ) => digestText(jsonStorage(schema).encode(value));\n\n const currentSubject = Effect.fn(\"passkey.currentWriteSubject\")(function* (\n mapping: any,\n subjectId: SubjectId,\n ) {\n const owner = yield* CurrentPasskeyTransaction;\n const read = mapping.read;\n const table = read.subject;\n const nativeId = read.subjectIds.toNative(subjectId);\n\n invariant(read.subjectIds.toSubject(nativeId) === subjectId);\n\n const row = (yield* owner.read(table.table, equal(table.table, { [table.id]: nativeId }), {\n limit: 1,\n columns: [\n ...new Set<string>([\n table.id,\n table.status,\n table.securityRevision,\n ...mapping.write.policy.subjectColumns,\n ]),\n ],\n })).rows[0];\n\n if (row === undefined || !table.isActiveStatus(row[table.status])) return undefined;\n invariant(read.subjectIds.equals(table.decodeId(copiedRow(row)), nativeId));\n const active = sql`exists(select 1 from ${table.table} where ${both(equal(table.table, { [table.id]: nativeId }), table.activeCondition)})`;\n\n if (!(yield* owner.check(active))) return undefined;\n owner.postconditions.push(active);\n const factor = read.authority;\n\n const factors = (yield* owner.read(\n factor.table,\n both(equal(factor.table, { [factor.subjectId]: nativeId }), factor.activeCondition),\n {\n limit: 64,\n columns: mappedColumns(factor),\n orderBy: col(factor.table, factor.credentialId),\n },\n )).rows;\n\n const revision = snapshotPasskeySync(PasskeyRevision, {\n subjectId,\n securityRevision: row[table.securityRevision],\n credentials: factors.map((value) => ({\n credentialId: value[factor.credentialId],\n revision: value[factor.revision],\n })),\n });\n\n invariant(\n new Set(revision.credentials.map((item) => item.credentialId)).size ===\n revision.credentials.length,\n );\n\n return { subjectId, nativeId, row, revision };\n });\n\n const credentialRows = Effect.fn(\"passkey.writeCredentialRows\")(function* (\n mapping: any,\n subject: WriteSubject,\n rpId?: string,\n ) {\n const owner = yield* CurrentPasskeyTransaction;\n const table = mapping.read.credential;\n\n return (yield* owner.read(\n table.table,\n both(\n equal(table.table, { [table.subjectId]: subject.nativeId }),\n table.activeCondition,\n rpId === undefined ? undefined : equal(table.table, { [table.rpId]: rpId }),\n ),\n { limit: 64, orderBy: col(table.table, table.credentialId) },\n )).rows;\n });\n\n const summary = (mapping: any, row: any) => {\n const table = mapping.read.credential;\n const write = mapping.write.credential;\n const decoded = table.decode(copiedRow(row));\n\n return snapshotPasskeySync(PasskeyCredentialSummary, {\n credentialId: decoded.credentialId,\n name: row[write.name],\n primarySignIn: decoded.primarySignIn,\n createdAtMillis: mapping.clock.decodeInstant(row[write.createdAt]),\n ...(row[mapping.telemetry.lastUsedAt] === null ||\n row[mapping.telemetry.lastUsedAt] === undefined\n ? {}\n : { lastUsedAtMillis: mapping.clock.decodeInstant(row[mapping.telemetry.lastUsedAt]) }),\n });\n };\n\n const ownedCredential = Effect.fn(\"passkey.ownedWriteCredential\")(function* (\n mapping: any,\n subject: WriteSubject,\n row: any,\n ) {\n const owner = yield* CurrentPasskeyTransaction;\n const read = mapping.read;\n const table = read.credential;\n\n const decoded = snapshotPasskeySync(PasskeyCredential, {\n ...table.decode(copiedRow(row)),\n revision: subject.revision,\n active: true,\n });\n\n invariant(\n decoded.credentialId === row[table.credentialId] &&\n decoded.profile.rpId === decoded.rpId &&\n read.subjectIds.equals(table.decodeSubjectId(copiedRow(row)), subject.nativeId),\n );\n const ownership = read.credentialOwnership;\n const key = yield* credentialKey(decoded.rpId, decoded.protocolCredentialId);\n\n const tuple = (yield* owner.read(\n ownership.table,\n equal(ownership.table, { [ownership.credentialKey]: key }),\n { limit: 1, columns: mappedColumns(ownership) },\n )).rows[0];\n\n if (\n tuple === undefined ||\n !ownership.isOwnedState(tuple[ownership.state]) ||\n !read.subjectIds.equals(ownership.decodeSubjectId(copiedRow(tuple)), subject.nativeId)\n )\n return undefined;\n invariant(\n tuple[ownership.rpId] === decoded.rpId &&\n tuple[ownership.protocolCredentialId] === decoded.protocolCredentialId &&\n tuple[ownership.credentialId] === decoded.credentialId &&\n row[table.credentialKey] === key,\n );\n const handle = read.handleOwnership;\n const hashedHandle = yield* handleKey(decoded.rpId, decoded.userHandle);\n\n const held = (yield* owner.read(\n handle.table,\n equal(handle.table, { [handle.handleKey]: hashedHandle }),\n { limit: 1, columns: mappedColumns(handle) },\n )).rows[0];\n\n if (\n held === undefined ||\n !handle.isOwnedState(held[handle.state]) ||\n !read.subjectIds.equals(handle.decodeSubjectId(copiedRow(held)), subject.nativeId)\n )\n return undefined;\n invariant(\n held[handle.rpId] === decoded.rpId &&\n held[handle.userHandle] === decoded.userHandle &&\n row[table.handleKey] === hashedHandle,\n );\n invariant(\n subject.revision.credentials.some(\n (item) =>\n item.credentialId === decoded.credentialId &&\n item.revision === row[table.credentialRevision],\n ),\n );\n\n return decoded;\n });\n\n const managementPolicy = (mapping: any, subject: WriteSubject) =>\n snapshotPasskeySync(\n PasskeyManagementPolicy,\n mapping.write.policy.management(copiedRow(subject.row)),\n );\n\n const metadataAllowed = Effect.fn(\"passkey.metadataAllowed\")(function* (\n mapping: any,\n subject: WriteSubject,\n ) {\n const owner = yield* CurrentPasskeyTransaction;\n const condition = mapping.write.policy.metadata(subject.nativeId);\n const allowed = yield* owner.check(condition);\n\n if (allowed) owner.postconditions.push(condition);\n\n return allowed;\n });\n\n const enrollmentDigest = (ceremony: PasskeyCeremony) => {\n invariant(ceremony.context._tag === \"Enrollment\");\n const context = ceremony.context;\n\n return digest(\n Schema.Tuple([\n PasskeyModuleId,\n Schema.Literal(\"enrollment\"),\n Schema.Struct({ ...PasskeyBegin.fields, name: PasskeyLabel }),\n PasskeyProfile,\n PasskeyRevision,\n PasskeyUserHandle,\n Schema.Array(PasskeyDescriptor),\n ]),\n [\n ceremony.moduleId,\n \"enrollment\",\n {\n flowId: ceremony.flowId,\n commandId: ceremony.commandId,\n profileId: ceremony.profile.profileId,\n name: context.name,\n },\n ceremony.profile,\n context.revision,\n context.userHandle,\n ceremony.allowedCredentials,\n ],\n );\n };\n\n const removeDigest = (moduleId: string, commandId: string, credential: PasskeyCredential) =>\n digest(\n Schema.Tuple([\n PasskeyModuleId,\n Schema.Literal(\"remove\"),\n PasskeyBegin.fields.commandId,\n PasskeyCredential,\n ]),\n [\n PasskeyModuleId.make(moduleId),\n \"remove\",\n PasskeyBegin.fields.commandId.make(commandId),\n credential,\n ],\n );\n\n const authorizeAction = Effect.fn(\"passkey.authorizeWriteAction\")(function* (\n mapping: any,\n subject: WriteSubject,\n authorization: PasskeyActionAuthorization,\n expected: {\n readonly action: PasskeyActionAuthorization[\"challenge\"][\"action\"];\n readonly commandId: string;\n readonly flowId: string;\n readonly bindingDigest: string;\n readonly revision: typeof PasskeyRevision.Type;\n },\n policy: PasskeyManagementPolicy,\n original?: typeof PasskeyRequirement.Type,\n ) {\n const owner = yield* CurrentPasskeyTransaction;\n const { challenge, evidence } = authorization;\n\n if (\n challenge.moduleId !== mapping.moduleId ||\n challenge.action !== expected.action ||\n challenge.commandId !== expected.commandId ||\n challenge.flowId !== expected.flowId ||\n challenge.bindingDigest !== expected.bindingDigest ||\n evidence.flowId !== expected.flowId ||\n evidence.bindingDigest !== expected.bindingDigest ||\n !sameRevision(challenge.revision, expected.revision) ||\n subject.revision.subjectId !== expected.revision.subjectId ||\n subject.revision.securityRevision !== expected.revision.securityRevision ||\n evidence.revision.subjectId !== subject.subjectId ||\n evidence.revision.securityRevision !== subject.revision.securityRevision\n )\n return false;\n for (const revision of [expected.revision, evidence.revision])\n if (\n revision.credentials.some(\n (item) =>\n !subject.revision.credentials.some(\n (current) =>\n current.credentialId === item.credentialId && current.revision === item.revision,\n ),\n )\n )\n return false;\n const now = yield* owner.now(mapping.clock);\n\n if (\n evidence.proofs.some(\n (proof) =>\n DateTime.toEpochMillis(proof.verifiedAt) > now ||\n !evidence.revision.credentials.some((item) => item.credentialId === proof.credentialId),\n )\n )\n return false;\n\n const currentRequirement: Effect.Effect<\n typeof PasskeyRequirement.Type,\n PersistenceMappingError\n > = mapping.write.policy.requirement(copiedRow(subject.row), expected.action);\n\n const current = snapshotPasskeySync(PasskeyRequirement, yield* currentRequirement);\n\n for (const requirement of [\n authorization.requirement,\n current,\n ...(original === undefined ? [] : [original]),\n ]) {\n const age = Math.min(policy.maximumEvidenceAgeMillis, requirement.maximumAgeMillis);\n\n const fresh = evidence.proofs.filter(\n (proof) => now - DateTime.toEpochMillis(proof.verifiedAt) < age,\n );\n\n const factors = new Set(fresh.flatMap((proof) => proof.factors));\n\n if (\n !requirement.alternatives.some(\n (alternative) =>\n alternative.factors.every((factor) => factors.has(factor)) &&\n new Set(fresh.map((proof) => proof.credentialId)).size >=\n alternative.minimumCredentials &&\n fresh.some(\n (proof) =>\n (!alternative.userVerified || proof.userVerified) &&\n (!alternative.phishingResistant || proof.phishingResistant),\n ),\n )\n )\n return false;\n owner.postconditions.push(\n both(\n sql`${mapping.clock.engineNowMillis} >= ${now}`,\n ...fresh.map(\n (proof) =>\n sql`${mapping.clock.engineNowMillis} < ${DateTime.toEpochMillis(proof.verifiedAt) + age}`,\n ),\n ),\n );\n }\n const condition = mapping.write.policy.action(subject.nativeId, authorization);\n\n if (!(yield* owner.check(condition))) return false;\n owner.postconditions.push(condition);\n\n return true;\n });\n\n const invalidationMatches = (\n mapping: any,\n supplied: SessionInvalidationWindow,\n policy: PasskeyManagementPolicy,\n ) =>\n jsonStorage(SessionInvalidationWindow).encode(supplied) ===\n jsonStorage(SessionInvalidationWindow).encode(mapping.invalidation.window) &&\n (!policy.requireImmediateInvalidation || supplied.existingSessions === \"immediate\");\n\n const invalidate = Effect.fn(\"passkey.invalidateCredentialChange\")(function* (\n mapping: any,\n subject: WriteSubject,\n invalidation: SessionInvalidationWindow,\n ) {\n const owner = yield* CurrentPasskeyTransaction;\n const table = mapping.read.subject;\n const revision = PasskeyRevision.fields.securityRevision.make(owner.marker);\n\n yield* owner.update(\n table.table,\n { [table.id]: subject.nativeId },\n { [table.securityRevision]: revision },\n );\n\n const input = {\n subjectId: subject.nativeId,\n previousRevision: subject.revision.securityRevision,\n securityRevision: revision,\n invalidation,\n };\n\n for (const mutation of mapping.invalidation.mutations) {\n yield* owner.write(\n owner.database\n .update(mutation.table)\n .set(mutation.values(input))\n .where(mutation.where(input)),\n );\n owner.postconditions.push(mutation.postcondition(input));\n }\n owner.postconditions.push(mapping.invalidation.postcondition(input));\n const flow = mapping.flow;\n const scope = yield* subjectScope(subject.subjectId);\n\n const where = both(\n equal(flow.table, { [flow.subjectScope]: scope }),\n sql`${col(flow.table, flow.state)} in (${flow.states.Pending}, ${flow.states.Claimed})`,\n );\n\n yield* owner.write(\n owner.database\n .update(flow.table)\n .set({ [flow.state]: flow.states.Rejected, [flow.version]: owner.marker })\n .where(where),\n );\n for (const observation of owner.observations)\n if (observation.table === flow.table)\n observation.rows = observation.rows.map((row) =>\n row[flow.subjectScope] === scope &&\n [flow.states.Pending, flow.states.Claimed].includes(row[flow.state])\n ? { ...row, [flow.state]: flow.states.Rejected, [flow.version]: owner.marker }\n : row,\n );\n owner.postconditions.push(sql`not exists(select 1 from ${flow.table} where ${where})`);\n\n return revision;\n });\n\n const validRegistration = (\n ceremony: PasskeyCeremony,\n verified: {\n readonly algorithm: number;\n readonly userVerified: boolean;\n readonly backupEligible: boolean;\n readonly backupState: boolean;\n readonly protocolCredentialId: string;\n },\n ) =>\n ceremony.profile.algorithms.some((algorithm) => algorithm === verified.algorithm) &&\n (ceremony.profile.userVerification !== \"required\" || verified.userVerified) &&\n (!verified.backupState || verified.backupEligible) &&\n !ceremony.allowedCredentials.some((item) => item.id === verified.protocolCredentialId);\n\n const insertCredential = Effect.fn(\"passkey.insertCredential\")(function* (\n mapping: any,\n subject: WriteSubject,\n ceremony: PasskeyCeremony,\n verified: any,\n now: number,\n ) {\n const owner = yield* CurrentPasskeyTransaction;\n\n invariant(ceremony.context._tag === \"Enrollment\" || ceremony.context._tag === \"Registration\");\n const read = mapping.read;\n const write = mapping.write;\n const id = PasskeyCredential.fields.credentialId.make(owner.marker);\n\n const credential = snapshotPasskeySync(PasskeyCredential, {\n credentialId: id,\n rpId: ceremony.profile.rpId,\n protocolCredentialId: verified.protocolCredentialId,\n userHandle: ceremony.context.userHandle,\n publicKey: verified.publicKey,\n algorithm: verified.algorithm,\n profile: ceremony.profile,\n revision: {\n ...subject.revision,\n credentials: [\n ...subject.revision.credentials,\n {\n credentialId: id,\n revision: PasskeyRevision.fields.securityRevision.make(owner.marker),\n },\n ],\n },\n active: true,\n primarySignIn: ceremony.profile.primarySignIn && verified.userVerified,\n enrollmentUserVerified: verified.userVerified,\n backupEligible: verified.backupEligible,\n backupState: verified.backupState,\n counter: verified.counter,\n maximumCounter: verified.counter,\n });\n\n const safe = snapshotPasskeySync(PasskeyCredentialSummary, {\n credentialId: id,\n name: ceremony.context.name,\n primarySignIn: credential.primarySignIn,\n createdAtMillis: now,\n });\n\n const input = { subjectId: subject.nativeId, credential, summary: safe, marker: owner.marker };\n const tupleKey = yield* credentialKey(credential.rpId, credential.protocolCredentialId);\n const hashedHandle = yield* handleKey(credential.rpId, credential.userHandle);\n const tuple = read.credentialOwnership;\n\n const absent = yield* owner.read(\n tuple.table,\n equal(tuple.table, { [tuple.credentialKey]: tupleKey }),\n { limit: 1 },\n );\n\n invariant(absent.rows.length === 0);\n\n const inserted = yield* owner.insert(\n tuple.table,\n {\n ...write.credentialOwnership.encodeInsert(input),\n [tuple.credentialKey]: tupleKey,\n [tuple.rpId]: credential.rpId,\n [tuple.protocolCredentialId]: credential.protocolCredentialId,\n [tuple.subjectId]: subject.nativeId,\n [tuple.credentialId]: id,\n [tuple.state]: write.credentialOwnership.ownedState,\n [tuple.version]: owner.marker,\n [tuple.reservationId]: null,\n },\n { [tuple.credentialKey]: tupleKey },\n );\n\n absent.rows = inserted.rows;\n const table = read.credential;\n\n const values = {\n ...write.credential.encodeInsert(input),\n [table.credentialId]: id,\n [table.subjectId]: subject.nativeId,\n [table.rpId]: credential.rpId,\n [table.protocolCredentialId]: credential.protocolCredentialId,\n [table.credentialKey]: tupleKey,\n [table.handleKey]: hashedHandle,\n [table.userHandle]: credential.userHandle,\n [table.algorithm]: credential.algorithm,\n [table.credentialRevision]: owner.marker,\n [table.status]: write.credential.activeStatus,\n [table.primarySignIn]: write.credential.encodePrimarySignIn(credential.primarySignIn),\n [table.enrollmentUserVerified]: write.credential.encodeEnrollmentUserVerified(\n credential.enrollmentUserVerified,\n ),\n [table.backupEligible]: write.credential.encodeBackupEligible(credential.backupEligible),\n [table.backupState]: mapping.telemetry.encodeBackupState(credential.backupState),\n [table.counter]: credential.counter,\n [table.maximumCounter]: credential.maximumCounter,\n [write.credential.name]: safe.name,\n [write.credential.createdAt]: mapping.clock.encodeInstant(now),\n [mapping.telemetry.lastUsedAt]: null,\n };\n\n yield* owner.insert(table.table, values, { [table.credentialId]: id });\n for (const observation of owner.observations)\n if (\n observation.table === table.table &&\n observation.rows !== inserted.rows &&\n !observation.rows.some((row) => row[table.credentialId] === id)\n )\n observation.rows = [...observation.rows, values];\n const factor = read.authority;\n\n const factorValues = {\n ...write.authority.encodeInsert(input),\n [factor.subjectId]: subject.nativeId,\n [factor.credentialId]: id,\n [factor.revision]: owner.marker,\n [factor.status]: write.authority.activeStatus,\n };\n\n yield* owner.insert(factor.table, factorValues, {\n [factor.subjectId]: subject.nativeId,\n [factor.credentialId]: id,\n });\n for (const observation of owner.observations)\n if (\n observation.table === factor.table &&\n !observation.rows.some((row) => row[factor.credentialId] === id)\n )\n observation.rows = [...observation.rows, factorValues];\n\n const decoded = snapshotPasskeySync(PasskeyCredential, {\n ...table.decode(copiedRow(values)),\n revision: credential.revision,\n active: true,\n });\n\n invariant(\n sameCredential(decoded, credential) &&\n decoded.counter === credential.counter &&\n decoded.maximumCounter === credential.maximumCounter &&\n decoded.backupState === credential.backupState,\n );\n invariant(summary(mapping, values).credentialId === id);\n owner.postconditions.push(sql`${mapping.clock.engineNowMillis} >= ${now}`);\n\n return safe;\n });\n\n return {\n jsonStorage,\n digest,\n currentSubject,\n credentialRows,\n summary,\n ownedCredential,\n managementPolicy,\n metadataAllowed,\n enrollmentDigest,\n removeDigest,\n authorizeAction,\n invalidationMatches,\n invalidate,\n validRegistration,\n insertCredential,\n };\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"write-state.mjs","names":["digest","digestText"],"sources":["../../../src/internal/passkey/write-state.ts"],"sourcesContent":["/* oxlint-disable no-explicit-any -- existing mapped-row bridge; public adapters preserve table, ID, and Effect types. */\n\nimport {\n type PasskeyActionAuthorization,\n type PasskeyCeremony,\n PasskeyBegin,\n PasskeyCredential,\n PasskeyCredentialSummary,\n PasskeyDescriptor,\n PasskeyLabel,\n PasskeyModuleId,\n PasskeyProfile,\n PasskeyRequirement,\n PasskeyRevision,\n PasskeyUserHandle,\n PasskeyManagementPolicy,\n snapshotPasskeySync,\n} from \"@yielded/auth/Passkey\";\nimport { type SubjectId } from \"@yielded/auth/Schema\";\nimport { SessionInvalidationWindow } from \"@yielded/auth/Sessions\";\nimport { DateTime, Effect, Schema } from \"effect\";\n\nimport { digest as digestText } from \"../crypto\";\nimport type { PersistenceMappingError } from \"../mapping-error\";\nimport type { QueryOperations } from \"../query-operations\";\nimport type { makeTransactionKernel } from \"../transaction-kernel\";\nimport { CurrentPasskeyTransaction } from \"./state\";\nimport type { makePasskeyStateKernel } from \"./state\";\n\nexport interface WriteSubject {\n readonly subjectId: SubjectId;\n readonly nativeId: any;\n readonly row: Record<string, any>;\n readonly revision: typeof PasskeyRevision.Type;\n}\n\nexport const makePasskeyWriteStateKernel = (\n operations: QueryOperations,\n state: Pick<\n ReturnType<typeof makePasskeyStateKernel>,\n | \"col\"\n | \"copiedRow\"\n | \"credentialKey\"\n | \"equal\"\n | \"handleKey\"\n | \"invariant\"\n | \"mappedColumns\"\n | \"sameCredential\"\n | \"sameRevision\"\n | \"subjectScope\"\n >,\n transactions: Pick<ReturnType<typeof makeTransactionKernel>, \"both\">,\n) => {\n const { sql } = operations;\n\n const {\n col,\n copiedRow,\n credentialKey,\n equal,\n handleKey,\n mappedColumns,\n sameCredential,\n sameRevision,\n subjectScope,\n } = state;\n\n const invariant: (value: unknown) => asserts value = state.invariant;\n const { both } = transactions;\n\n const jsonStorage = <S extends Schema.Codec<unknown, unknown, never, never>>(schema: S) => {\n const codec = Schema.fromJsonString(Schema.toCodecJson(Schema.toType(schema)));\n\n return {\n encode: (value: S[\"Type\"]) => Schema.encodeSync(codec)(snapshotPasskeySync(schema, value)),\n decode: (text: unknown): S[\"Type\"] => {\n // oxlint-disable-next-line no-restricted-properties -- persisted private JSON enters through its schema.\n return Schema.decodeUnknownSync(codec)(text);\n },\n };\n };\n\n const digest = <S extends Schema.Codec<unknown, unknown, never, never>>(\n schema: S,\n value: S[\"Type\"],\n ) => digestText(jsonStorage(schema).encode(value));\n\n const currentSubject = Effect.fn(\"passkey.currentWriteSubject\")(function* (\n mapping: any,\n subjectId: SubjectId,\n ) {\n const owner = yield* CurrentPasskeyTransaction;\n const read = mapping.read;\n const table = read.subject;\n const nativeId = read.subjectIds.toNative(subjectId);\n\n invariant(read.subjectIds.toSubject(nativeId) === subjectId);\n\n const row = (yield* owner.read(table.table, equal(table.table, { [table.id]: nativeId }), {\n limit: 1,\n columns: [\n ...new Set<string>([\n table.id,\n table.status,\n table.securityRevision,\n ...mapping.write.policy.subjectColumns,\n ]),\n ],\n })).rows[0];\n\n if (row === undefined || !table.isActiveStatus(row[table.status])) return undefined;\n invariant(read.subjectIds.equals(table.decodeId(copiedRow(row)), nativeId));\n const active = sql`exists(select 1 from ${table.table} where ${both(equal(table.table, { [table.id]: nativeId }), table.activeCondition)})`;\n\n if (!(yield* owner.check(active))) return undefined;\n owner.postconditions.push(active);\n const factor = read.authority;\n\n const factors = (yield* owner.read(\n factor.table,\n both(equal(factor.table, { [factor.subjectId]: nativeId }), factor.activeCondition),\n {\n limit: 64,\n columns: mappedColumns(factor),\n orderBy: col(factor.table, factor.credentialId),\n },\n )).rows;\n\n const revision = snapshotPasskeySync(PasskeyRevision, {\n subjectId,\n securityRevision: row[table.securityRevision],\n credentials: factors.map((value) => ({\n credentialId: value[factor.credentialId],\n revision: value[factor.revision],\n })),\n });\n\n invariant(\n new Set(revision.credentials.map((item) => item.credentialId)).size ===\n revision.credentials.length,\n );\n\n return { subjectId, nativeId, row, revision };\n });\n\n const credentialRows = Effect.fn(\"passkey.writeCredentialRows\")(function* (\n mapping: any,\n subject: WriteSubject,\n rpId?: string,\n ) {\n const owner = yield* CurrentPasskeyTransaction;\n const table = mapping.read.credential;\n\n return (yield* owner.read(\n table.table,\n both(\n equal(table.table, { [table.subjectId]: subject.nativeId }),\n table.activeCondition,\n rpId === undefined ? undefined : equal(table.table, { [table.rpId]: rpId }),\n ),\n { limit: 64, orderBy: col(table.table, table.credentialId) },\n )).rows;\n });\n\n const summary = (mapping: any, row: any) => {\n const table = mapping.read.credential;\n const write = mapping.write.credential;\n const decoded = table.decode(copiedRow(row));\n\n return snapshotPasskeySync(PasskeyCredentialSummary, {\n credentialId: decoded.credentialId,\n name: row[write.name],\n primarySignIn: decoded.primarySignIn,\n createdAtMillis: mapping.clock.decodeInstant(row[write.createdAt]),\n ...(row[mapping.telemetry.lastUsedAt] === null ||\n row[mapping.telemetry.lastUsedAt] === undefined\n ? {}\n : { lastUsedAtMillis: mapping.clock.decodeInstant(row[mapping.telemetry.lastUsedAt]) }),\n });\n };\n\n const ownedCredential = Effect.fn(\"passkey.ownedWriteCredential\")(function* (\n mapping: any,\n subject: WriteSubject,\n row: any,\n ) {\n const owner = yield* CurrentPasskeyTransaction;\n const read = mapping.read;\n const table = read.credential;\n\n const decoded = snapshotPasskeySync(PasskeyCredential, {\n ...table.decode(copiedRow(row)),\n revision: subject.revision,\n active: true,\n });\n\n invariant(\n decoded.credentialId === row[table.credentialId] &&\n decoded.profile.rpId === decoded.rpId &&\n read.subjectIds.equals(table.decodeSubjectId(copiedRow(row)), subject.nativeId),\n );\n const ownership = read.credentialOwnership;\n const key = yield* credentialKey(decoded.rpId, decoded.protocolCredentialId);\n\n const tuple = (yield* owner.read(\n ownership.table,\n equal(ownership.table, { [ownership.credentialKey]: key }),\n { limit: 1, columns: mappedColumns(ownership) },\n )).rows[0];\n\n if (\n tuple === undefined ||\n !ownership.isOwnedState(tuple[ownership.state]) ||\n !read.subjectIds.equals(ownership.decodeSubjectId(copiedRow(tuple)), subject.nativeId)\n )\n return undefined;\n invariant(\n tuple[ownership.rpId] === decoded.rpId &&\n tuple[ownership.protocolCredentialId] === decoded.protocolCredentialId &&\n tuple[ownership.credentialId] === decoded.credentialId &&\n row[table.credentialKey] === key,\n );\n const handle = read.handleOwnership;\n const hashedHandle = yield* handleKey(decoded.rpId, decoded.userHandle);\n\n const held = (yield* owner.read(\n handle.table,\n equal(handle.table, { [handle.handleKey]: hashedHandle }),\n { limit: 1, columns: mappedColumns(handle) },\n )).rows[0];\n\n if (\n held === undefined ||\n !handle.isOwnedState(held[handle.state]) ||\n !read.subjectIds.equals(handle.decodeSubjectId(copiedRow(held)), subject.nativeId)\n )\n return undefined;\n invariant(\n held[handle.rpId] === decoded.rpId &&\n held[handle.userHandle] === decoded.userHandle &&\n row[table.handleKey] === hashedHandle,\n );\n invariant(\n subject.revision.credentials.some(\n (item) =>\n item.credentialId === decoded.credentialId &&\n item.revision === row[table.credentialRevision],\n ),\n );\n\n return decoded;\n });\n\n const managementPolicy = (mapping: any, subject: WriteSubject) =>\n snapshotPasskeySync(\n PasskeyManagementPolicy,\n mapping.write.policy.management(copiedRow(subject.row)),\n );\n\n const metadataAllowed = Effect.fn(\"passkey.metadataAllowed\")(function* (\n mapping: any,\n subject: WriteSubject,\n ) {\n const owner = yield* CurrentPasskeyTransaction;\n const condition = mapping.write.policy.metadata(subject.nativeId);\n const allowed = yield* owner.check(condition);\n\n if (allowed) owner.postconditions.push(condition);\n\n return allowed;\n });\n\n const enrollmentDigest = (ceremony: PasskeyCeremony) => {\n invariant(ceremony.context._tag === \"Enrollment\");\n const context = ceremony.context;\n\n return digest(\n Schema.Tuple([\n PasskeyModuleId,\n Schema.Literal(\"enrollment\"),\n Schema.Struct({ ...PasskeyBegin.fields, name: PasskeyLabel }),\n PasskeyProfile,\n PasskeyRevision,\n PasskeyUserHandle,\n Schema.Array(PasskeyDescriptor),\n ]),\n [\n ceremony.moduleId,\n \"enrollment\",\n {\n flowId: ceremony.flowId,\n commandId: ceremony.commandId,\n profileId: ceremony.profile.profileId,\n name: context.name,\n },\n ceremony.profile,\n context.revision,\n context.userHandle,\n ceremony.allowedCredentials,\n ],\n );\n };\n\n const removeDigest = (moduleId: string, commandId: string, credential: PasskeyCredential) =>\n digest(\n Schema.Tuple([\n PasskeyModuleId,\n Schema.Literal(\"remove\"),\n PasskeyBegin.fields.commandId,\n PasskeyCredential,\n ]),\n [\n PasskeyModuleId.make(moduleId),\n \"remove\",\n PasskeyBegin.fields.commandId.make(commandId),\n credential,\n ],\n );\n\n const authorizeAction = Effect.fn(\"passkey.authorizeWriteAction\")(function* (\n mapping: any,\n subject: WriteSubject,\n authorization: PasskeyActionAuthorization,\n expected: {\n readonly action: PasskeyActionAuthorization[\"challenge\"][\"action\"];\n readonly commandId: string;\n readonly flowId: string;\n readonly bindingDigest: string;\n readonly revision: typeof PasskeyRevision.Type;\n },\n policy: PasskeyManagementPolicy,\n original?: typeof PasskeyRequirement.Type,\n ) {\n const owner = yield* CurrentPasskeyTransaction;\n const { challenge, evidence } = authorization;\n\n if (\n challenge.moduleId !== mapping.moduleId ||\n challenge.action !== expected.action ||\n challenge.commandId !== expected.commandId ||\n challenge.flowId !== expected.flowId ||\n challenge.bindingDigest !== expected.bindingDigest ||\n evidence.flowId !== expected.flowId ||\n evidence.bindingDigest !== expected.bindingDigest ||\n !sameRevision(challenge.revision, expected.revision) ||\n subject.revision.subjectId !== expected.revision.subjectId ||\n subject.revision.securityRevision !== expected.revision.securityRevision ||\n evidence.revision.subjectId !== subject.subjectId ||\n evidence.revision.securityRevision !== subject.revision.securityRevision\n )\n return false;\n for (const revision of [expected.revision, evidence.revision])\n if (\n revision.credentials.some(\n (item) =>\n !subject.revision.credentials.some(\n (current) =>\n current.credentialId === item.credentialId && current.revision === item.revision,\n ),\n )\n )\n return false;\n const now = yield* owner.now(mapping.clock);\n\n if (\n evidence.proofs.some(\n (proof) =>\n DateTime.toEpochMillis(proof.verifiedAt) > now ||\n !evidence.revision.credentials.some((item) => item.credentialId === proof.credentialId),\n )\n )\n return false;\n\n const currentRequirement: Effect.Effect<\n typeof PasskeyRequirement.Type,\n PersistenceMappingError\n > = mapping.write.policy.requirement(copiedRow(subject.row), expected.action);\n\n const current = snapshotPasskeySync(PasskeyRequirement, yield* currentRequirement);\n\n for (const requirement of [\n authorization.requirement,\n current,\n ...(original === undefined ? [] : [original]),\n ]) {\n const age = Math.min(policy.maximumEvidenceAgeMillis, requirement.maximumAgeMillis);\n\n const fresh = evidence.proofs.filter(\n (proof) => now - DateTime.toEpochMillis(proof.verifiedAt) < age,\n );\n\n const factors = new Set(fresh.flatMap((proof) => proof.factors));\n\n if (\n !requirement.alternatives.some(\n (alternative) =>\n alternative.factors.every((factor) => factors.has(factor)) &&\n new Set(fresh.map((proof) => proof.credentialId)).size >=\n alternative.minimumCredentials &&\n fresh.some(\n (proof) =>\n (!alternative.userVerified || proof.userVerified) &&\n (!alternative.phishingResistant || proof.phishingResistant),\n ),\n )\n )\n return false;\n owner.postconditions.push(\n both(\n sql`${mapping.clock.engineNowMillis} >= ${now}`,\n ...fresh.map(\n (proof) =>\n sql`${mapping.clock.engineNowMillis} < ${DateTime.toEpochMillis(proof.verifiedAt) + age}`,\n ),\n ),\n );\n }\n const condition = mapping.write.policy.action(subject.nativeId, authorization);\n\n if (!(yield* owner.check(condition))) return false;\n owner.postconditions.push(condition);\n\n return true;\n });\n\n const invalidationMatches = (\n mapping: any,\n supplied: SessionInvalidationWindow,\n policy: PasskeyManagementPolicy,\n ) => {\n if (supplied.existingSessions === \"cache-expiry\" && supplied.maximumExposureMillis === 0)\n return false;\n\n // Cookie-cache exposure does not weaken the mapping's authoritative\n // revision bump. Compare that immediate guarantee independently of the TTL.\n const authoritative: SessionInvalidationWindow =\n supplied.existingSessions === \"cache-expiry\" &&\n mapping.invalidation.window.existingSessions === \"immediate\"\n ? { ...supplied, existingSessions: \"immediate\", maximumExposureMillis: 0 }\n : supplied;\n\n return (\n jsonStorage(SessionInvalidationWindow).encode(authoritative) ===\n jsonStorage(SessionInvalidationWindow).encode(mapping.invalidation.window) &&\n (!policy.requireImmediateInvalidation || supplied.existingSessions === \"immediate\")\n );\n };\n\n const invalidate = Effect.fn(\"passkey.invalidateCredentialChange\")(function* (\n mapping: any,\n subject: WriteSubject,\n invalidation: SessionInvalidationWindow,\n ) {\n const owner = yield* CurrentPasskeyTransaction;\n const table = mapping.read.subject;\n const revision = PasskeyRevision.fields.securityRevision.make(owner.marker);\n\n yield* owner.update(\n table.table,\n { [table.id]: subject.nativeId },\n { [table.securityRevision]: revision },\n );\n\n const input = {\n subjectId: subject.nativeId,\n previousRevision: subject.revision.securityRevision,\n securityRevision: revision,\n invalidation,\n };\n\n for (const mutation of mapping.invalidation.mutations) {\n yield* owner.write(\n owner.database\n .update(mutation.table)\n .set(mutation.values(input))\n .where(mutation.where(input)),\n );\n owner.postconditions.push(mutation.postcondition(input));\n }\n owner.postconditions.push(mapping.invalidation.postcondition(input));\n const flow = mapping.flow;\n const scope = yield* subjectScope(subject.subjectId);\n\n const where = both(\n equal(flow.table, { [flow.subjectScope]: scope }),\n sql`${col(flow.table, flow.state)} in (${flow.states.Pending}, ${flow.states.Claimed})`,\n );\n\n yield* owner.write(\n owner.database\n .update(flow.table)\n .set({ [flow.state]: flow.states.Rejected, [flow.version]: owner.marker })\n .where(where),\n );\n for (const observation of owner.observations)\n if (observation.table === flow.table)\n observation.rows = observation.rows.map((row) =>\n row[flow.subjectScope] === scope &&\n [flow.states.Pending, flow.states.Claimed].includes(row[flow.state])\n ? { ...row, [flow.state]: flow.states.Rejected, [flow.version]: owner.marker }\n : row,\n );\n owner.postconditions.push(sql`not exists(select 1 from ${flow.table} where ${where})`);\n\n return revision;\n });\n\n const validRegistration = (\n ceremony: PasskeyCeremony,\n verified: {\n readonly algorithm: number;\n readonly userVerified: boolean;\n readonly backupEligible: boolean;\n readonly backupState: boolean;\n readonly protocolCredentialId: string;\n },\n ) =>\n ceremony.profile.algorithms.some((algorithm) => algorithm === verified.algorithm) &&\n (ceremony.profile.userVerification !== \"required\" || verified.userVerified) &&\n (!verified.backupState || verified.backupEligible) &&\n !ceremony.allowedCredentials.some((item) => item.id === verified.protocolCredentialId);\n\n const insertCredential = Effect.fn(\"passkey.insertCredential\")(function* (\n mapping: any,\n subject: WriteSubject,\n ceremony: PasskeyCeremony,\n verified: any,\n now: number,\n ) {\n const owner = yield* CurrentPasskeyTransaction;\n\n invariant(ceremony.context._tag === \"Enrollment\" || ceremony.context._tag === \"Registration\");\n const read = mapping.read;\n const write = mapping.write;\n const id = PasskeyCredential.fields.credentialId.make(owner.marker);\n\n const credential = snapshotPasskeySync(PasskeyCredential, {\n credentialId: id,\n rpId: ceremony.profile.rpId,\n protocolCredentialId: verified.protocolCredentialId,\n userHandle: ceremony.context.userHandle,\n publicKey: verified.publicKey,\n algorithm: verified.algorithm,\n profile: ceremony.profile,\n revision: {\n ...subject.revision,\n credentials: [\n ...subject.revision.credentials,\n {\n credentialId: id,\n revision: PasskeyRevision.fields.securityRevision.make(owner.marker),\n },\n ],\n },\n active: true,\n primarySignIn: ceremony.profile.primarySignIn && verified.userVerified,\n enrollmentUserVerified: verified.userVerified,\n backupEligible: verified.backupEligible,\n backupState: verified.backupState,\n counter: verified.counter,\n maximumCounter: verified.counter,\n });\n\n const safe = snapshotPasskeySync(PasskeyCredentialSummary, {\n credentialId: id,\n name: ceremony.context.name,\n primarySignIn: credential.primarySignIn,\n createdAtMillis: now,\n });\n\n const input = { subjectId: subject.nativeId, credential, summary: safe, marker: owner.marker };\n const tupleKey = yield* credentialKey(credential.rpId, credential.protocolCredentialId);\n const hashedHandle = yield* handleKey(credential.rpId, credential.userHandle);\n const tuple = read.credentialOwnership;\n\n const absent = yield* owner.read(\n tuple.table,\n equal(tuple.table, { [tuple.credentialKey]: tupleKey }),\n { limit: 1 },\n );\n\n invariant(absent.rows.length === 0);\n\n const inserted = yield* owner.insert(\n tuple.table,\n {\n ...write.credentialOwnership.encodeInsert(input),\n [tuple.credentialKey]: tupleKey,\n [tuple.rpId]: credential.rpId,\n [tuple.protocolCredentialId]: credential.protocolCredentialId,\n [tuple.subjectId]: subject.nativeId,\n [tuple.credentialId]: id,\n [tuple.state]: write.credentialOwnership.ownedState,\n [tuple.version]: owner.marker,\n [tuple.reservationId]: null,\n },\n { [tuple.credentialKey]: tupleKey },\n );\n\n absent.rows = inserted.rows;\n const table = read.credential;\n\n const values = {\n ...write.credential.encodeInsert(input),\n [table.credentialId]: id,\n [table.subjectId]: subject.nativeId,\n [table.rpId]: credential.rpId,\n [table.protocolCredentialId]: credential.protocolCredentialId,\n [table.credentialKey]: tupleKey,\n [table.handleKey]: hashedHandle,\n [table.userHandle]: credential.userHandle,\n [table.algorithm]: credential.algorithm,\n [table.credentialRevision]: owner.marker,\n [table.status]: write.credential.activeStatus,\n [table.primarySignIn]: write.credential.encodePrimarySignIn(credential.primarySignIn),\n [table.enrollmentUserVerified]: write.credential.encodeEnrollmentUserVerified(\n credential.enrollmentUserVerified,\n ),\n [table.backupEligible]: write.credential.encodeBackupEligible(credential.backupEligible),\n [table.backupState]: mapping.telemetry.encodeBackupState(credential.backupState),\n [table.counter]: credential.counter,\n [table.maximumCounter]: credential.maximumCounter,\n [write.credential.name]: safe.name,\n [write.credential.createdAt]: mapping.clock.encodeInstant(now),\n [mapping.telemetry.lastUsedAt]: null,\n };\n\n yield* owner.insert(table.table, values, { [table.credentialId]: id });\n for (const observation of owner.observations)\n if (\n observation.table === table.table &&\n observation.rows !== inserted.rows &&\n !observation.rows.some((row) => row[table.credentialId] === id)\n )\n observation.rows = [...observation.rows, values];\n const factor = read.authority;\n\n const factorValues = {\n ...write.authority.encodeInsert(input),\n [factor.subjectId]: subject.nativeId,\n [factor.credentialId]: id,\n [factor.revision]: owner.marker,\n [factor.status]: write.authority.activeStatus,\n };\n\n yield* owner.insert(factor.table, factorValues, {\n [factor.subjectId]: subject.nativeId,\n [factor.credentialId]: id,\n });\n for (const observation of owner.observations)\n if (\n observation.table === factor.table &&\n !observation.rows.some((row) => row[factor.credentialId] === id)\n )\n observation.rows = [...observation.rows, factorValues];\n\n const decoded = snapshotPasskeySync(PasskeyCredential, {\n ...table.decode(copiedRow(values)),\n revision: credential.revision,\n active: true,\n });\n\n invariant(\n sameCredential(decoded, credential) &&\n decoded.counter === credential.counter &&\n decoded.maximumCounter === credential.maximumCounter &&\n decoded.backupState === credential.backupState,\n );\n invariant(summary(mapping, values).credentialId === id);\n owner.postconditions.push(sql`${mapping.clock.engineNowMillis} >= ${now}`);\n\n return safe;\n });\n\n return {\n jsonStorage,\n digest,\n currentSubject,\n credentialRows,\n summary,\n ownedCredential,\n managementPolicy,\n metadataAllowed,\n enrollmentDigest,\n removeDigest,\n authorizeAction,\n invalidationMatches,\n invalidate,\n validRegistration,\n insertCredential,\n };\n};\n"],"mappings":"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"}