@yielded/auth-persistence-drizzle 0.1.0-beta.22 → 0.1.0-beta.24

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (200) hide show
  1. package/README.md +3 -0
  2. package/dist/D1.d.mts +11 -11
  3. package/dist/D1.mjs +2 -1
  4. package/dist/D1.mjs.map +1 -1
  5. package/dist/Libsql.d.mts +40 -56
  6. package/dist/Libsql.mjs +2 -1
  7. package/dist/Libsql.mjs.map +1 -1
  8. package/dist/Mysql2.d.mts +16 -17
  9. package/dist/Pglite.d.mts +18 -18
  10. package/dist/Pglite.mjs +2 -1
  11. package/dist/Pglite.mjs.map +1 -1
  12. package/dist/Postgres.d.mts +24 -24
  13. package/dist/Postgres.mjs +2 -1
  14. package/dist/Postgres.mjs.map +1 -1
  15. package/dist/SqliteBun.d.mts +39 -55
  16. package/dist/SqliteBun.mjs +2 -1
  17. package/dist/SqliteBun.mjs.map +1 -1
  18. package/dist/SqliteDo.d.mts +48 -64
  19. package/dist/SqliteDo.mjs +2 -1
  20. package/dist/SqliteDo.mjs.map +1 -1
  21. package/dist/SqliteNode.d.mts +45 -61
  22. package/dist/SqliteNode.mjs +2 -1
  23. package/dist/SqliteNode.mjs.map +1 -1
  24. package/dist/SqliteWasm.d.mts +48 -64
  25. package/dist/SqliteWasm.mjs +2 -1
  26. package/dist/SqliteWasm.mjs.map +1 -1
  27. package/dist/drizzle/crypto.mjs +1 -1
  28. package/dist/drizzle/d1-emails.d.mts +1 -1
  29. package/dist/drizzle/d1-oauth.d.mts +14 -14
  30. package/dist/drizzle/d1-passkey.d.mts +1 -1
  31. package/dist/drizzle/d1-password-prepared.d.mts +4 -4
  32. package/dist/drizzle/d1-password-prepared.mjs.map +1 -1
  33. package/dist/drizzle/d1-passwords.d.mts +18 -35
  34. package/dist/drizzle/d1-passwords.mjs +78 -290
  35. package/dist/drizzle/d1-passwords.mjs.map +1 -1
  36. package/dist/drizzle/d1-phone.d.mts +1 -1
  37. package/dist/drizzle/d1-proofs.d.mts +2 -2
  38. package/dist/drizzle/d1-sessions.d.mts +3 -3
  39. package/dist/drizzle/d1-sessions.mjs +11 -6
  40. package/dist/drizzle/d1-sessions.mjs.map +1 -1
  41. package/dist/drizzle/d1-totp.d.mts +1 -1
  42. package/dist/drizzle/mysql-password-prepared.d.mts +5 -5
  43. package/dist/drizzle/mysql-password-prepared.mjs.map +1 -1
  44. package/dist/drizzle/mysql-passwords.d.mts +16 -32
  45. package/dist/drizzle/mysql-passwords.mjs.map +1 -1
  46. package/dist/drizzle/mysql-sessions.d.mts +1 -1
  47. package/dist/drizzle/native-sql-table.mjs +135 -0
  48. package/dist/drizzle/native-sql-table.mjs.map +1 -0
  49. package/dist/drizzle/oauth-connected-model.d.mts +20 -281
  50. package/dist/drizzle/oauth-connected-model.mjs +3 -17
  51. package/dist/drizzle/oauth-connected-model.mjs.map +1 -1
  52. package/dist/drizzle/oauth-connected-reference.d.mts +1 -3
  53. package/dist/drizzle/oauth-connected-reference.mjs +4 -53
  54. package/dist/drizzle/oauth-connected-reference.mjs.map +1 -1
  55. package/dist/drizzle/oauth-connected-target.d.mts +3 -990
  56. package/dist/drizzle/oauth-connected-target.mjs +8 -92
  57. package/dist/drizzle/oauth-connected-target.mjs.map +1 -1
  58. package/dist/drizzle/oauth-kernel.mjs +11 -0
  59. package/dist/drizzle/oauth-kernel.mjs.map +1 -0
  60. package/dist/drizzle/oauth-model.d.mts +35 -438
  61. package/dist/drizzle/oauth-model.mjs +6 -44
  62. package/dist/drizzle/oauth-model.mjs.map +1 -1
  63. package/dist/drizzle/oauth-mysql.mjs +2 -2
  64. package/dist/drizzle/oauth-mysql.mjs.map +1 -1
  65. package/dist/drizzle/oauth-proxy.d.mts +10 -0
  66. package/dist/drizzle/oauth-proxy.mjs +54 -0
  67. package/dist/drizzle/oauth-proxy.mjs.map +1 -0
  68. package/dist/drizzle/oauth-target.d.mts +6 -107
  69. package/dist/drizzle/oauth-target.mjs +15 -245
  70. package/dist/drizzle/oauth-target.mjs.map +1 -1
  71. package/dist/drizzle/password-model.d.mts +5 -8
  72. package/dist/drizzle/password-prepared-model.d.mts +5 -5
  73. package/dist/drizzle/password-prepared-model.mjs.map +1 -1
  74. package/dist/drizzle/password-prepared-state.mjs +1 -1
  75. package/dist/drizzle/password-sql.mjs +2 -1
  76. package/dist/drizzle/password-sql.mjs.map +1 -1
  77. package/dist/drizzle/password-target.mjs +13 -2
  78. package/dist/drizzle/password-target.mjs.map +1 -1
  79. package/dist/drizzle/pg-password-prepared.d.mts +5 -5
  80. package/dist/drizzle/pg-password-prepared.mjs.map +1 -1
  81. package/dist/drizzle/pg-passwords.d.mts +16 -32
  82. package/dist/drizzle/pg-passwords.mjs.map +1 -1
  83. package/dist/drizzle/pg-sessions.d.mts +1 -1
  84. package/dist/drizzle/phone-target.d.mts +2 -2
  85. package/dist/drizzle/phone-target.mjs +1 -1
  86. package/dist/drizzle/query-operations.mjs +3 -1
  87. package/dist/drizzle/query-operations.mjs.map +1 -1
  88. package/dist/drizzle/session-sql.mjs +2 -1
  89. package/dist/drizzle/session-sql.mjs.map +1 -1
  90. package/dist/drizzle/sqlite-password-prepared.mjs.map +1 -1
  91. package/dist/drizzle/sqlite-passwords.mjs.map +1 -1
  92. package/dist/drizzle/storage-validation.mjs +10 -198
  93. package/dist/drizzle/storage-validation.mjs.map +1 -1
  94. package/dist/drizzle/totp-target.d.mts +3 -3
  95. package/dist/drizzle/totp-target.mjs +2 -2
  96. package/dist/drizzle/transaction-execution.d.mts +2 -2
  97. package/dist/drizzle/transaction-owner.d.mts +1 -2
  98. package/dist/index.d.mts +3 -2
  99. package/dist/internal/drizzle-postgres-oauth-proxy.d.mts +138 -0
  100. package/dist/internal/drizzle-postgres-oauth-proxy.mjs +29 -0
  101. package/dist/internal/drizzle-postgres-oauth-proxy.mjs.map +1 -0
  102. package/dist/internal/drizzle-postgres.mjs +2 -0
  103. package/dist/internal/drizzle-postgres.mjs.map +1 -1
  104. package/dist/internal/drizzle-sqlite-oauth-proxy.d.mts +146 -0
  105. package/dist/internal/drizzle-sqlite-oauth-proxy.mjs +29 -0
  106. package/dist/internal/drizzle-sqlite-oauth-proxy.mjs.map +1 -0
  107. package/dist/internal/drizzle-sqlite.mjs +2 -0
  108. package/dist/internal/drizzle-sqlite.mjs.map +1 -1
  109. package/package.json +1 -1
  110. package/src/D1.ts +2 -0
  111. package/src/Libsql.ts +2 -0
  112. package/src/Pglite.ts +2 -0
  113. package/src/Postgres.ts +2 -0
  114. package/src/SqliteBun.ts +2 -0
  115. package/src/SqliteDo.ts +2 -0
  116. package/src/SqliteNode.ts +2 -0
  117. package/src/SqliteWasm.ts +2 -0
  118. package/src/drizzle/d1-password-prepared.ts +2 -23
  119. package/src/drizzle/d1-passwords.ts +158 -780
  120. package/src/drizzle/d1-sessions.ts +21 -6
  121. package/src/drizzle/mysql-password-prepared.ts +4 -16
  122. package/src/drizzle/mysql-passwords.ts +5 -20
  123. package/src/drizzle/native-sql-table.ts +259 -0
  124. package/src/drizzle/oauth-connected-model.ts +97 -315
  125. package/src/drizzle/oauth-connected-reference.ts +13 -93
  126. package/src/drizzle/oauth-connected-target.ts +14 -271
  127. package/src/drizzle/oauth-kernel.ts +10 -0
  128. package/src/drizzle/oauth-model.ts +188 -541
  129. package/src/drizzle/oauth-mysql.ts +2 -2
  130. package/src/drizzle/oauth-proxy.ts +101 -0
  131. package/src/drizzle/oauth-target.ts +33 -737
  132. package/src/drizzle/password-model.ts +0 -33
  133. package/src/drizzle/password-prepared-model.ts +0 -18
  134. package/src/drizzle/password-sql.ts +3 -0
  135. package/src/drizzle/password-target.ts +41 -4
  136. package/src/drizzle/pg-password-prepared.ts +4 -16
  137. package/src/drizzle/pg-passwords.ts +5 -20
  138. package/src/drizzle/query-operations.ts +4 -0
  139. package/src/drizzle/session-sql.ts +2 -1
  140. package/src/drizzle/sqlite-password-prepared.ts +4 -52
  141. package/src/drizzle/sqlite-passwords.ts +7 -28
  142. package/src/drizzle/storage-validation.ts +13 -222
  143. package/src/index.ts +2 -8
  144. package/src/internal/drizzle-postgres-oauth-proxy.ts +37 -0
  145. package/src/internal/drizzle-postgres.ts +2 -0
  146. package/src/internal/drizzle-sqlite-oauth-proxy.ts +44 -0
  147. package/src/internal/drizzle-sqlite.ts +2 -0
  148. package/dist/_virtual/_rolldown/runtime.mjs +0 -13
  149. package/dist/drizzle/oauth-accounts.mjs +0 -359
  150. package/dist/drizzle/oauth-accounts.mjs.map +0 -1
  151. package/dist/drizzle/oauth-connected-access.mjs +0 -212
  152. package/dist/drizzle/oauth-connected-access.mjs.map +0 -1
  153. package/dist/drizzle/oauth-connected-collection.mjs +0 -202
  154. package/dist/drizzle/oauth-connected-collection.mjs.map +0 -1
  155. package/dist/drizzle/oauth-connected-custody.mjs +0 -147
  156. package/dist/drizzle/oauth-connected-custody.mjs.map +0 -1
  157. package/dist/drizzle/oauth-connected-flow.mjs +0 -297
  158. package/dist/drizzle/oauth-connected-flow.mjs.map +0 -1
  159. package/dist/drizzle/oauth-connected-input.mjs +0 -122
  160. package/dist/drizzle/oauth-connected-input.mjs.map +0 -1
  161. package/dist/drizzle/oauth-connected-maintenance.mjs +0 -214
  162. package/dist/drizzle/oauth-connected-maintenance.mjs.map +0 -1
  163. package/dist/drizzle/oauth-connected-management.mjs +0 -229
  164. package/dist/drizzle/oauth-connected-management.mjs.map +0 -1
  165. package/dist/drizzle/oauth-connected-settlement.mjs +0 -128
  166. package/dist/drizzle/oauth-connected-settlement.mjs.map +0 -1
  167. package/dist/drizzle/oauth-connected-sign-in.mjs +0 -265
  168. package/dist/drizzle/oauth-connected-sign-in.mjs.map +0 -1
  169. package/dist/drizzle/oauth-connected-state.d.mts +0 -2062
  170. package/dist/drizzle/oauth-connected-state.mjs +0 -430
  171. package/dist/drizzle/oauth-connected-state.mjs.map +0 -1
  172. package/dist/drizzle/oauth-flow.d.mts +0 -22
  173. package/dist/drizzle/oauth-flow.mjs +0 -253
  174. package/dist/drizzle/oauth-flow.mjs.map +0 -1
  175. package/dist/drizzle/oauth-input.mjs +0 -127
  176. package/dist/drizzle/oauth-input.mjs.map +0 -1
  177. package/dist/drizzle/oauth-owner.d.mts +0 -10
  178. package/dist/drizzle/oauth-owner.mjs +0 -10
  179. package/dist/drizzle/oauth-owner.mjs.map +0 -1
  180. package/dist/drizzle/oauth-registration.d.mts +0 -5
  181. package/dist/drizzle/oauth-registration.mjs +0 -374
  182. package/dist/drizzle/oauth-registration.mjs.map +0 -1
  183. package/dist/drizzle/oauth-state.mjs +0 -107
  184. package/dist/drizzle/oauth-state.mjs.map +0 -1
  185. package/src/drizzle/oauth-accounts.ts +0 -805
  186. package/src/drizzle/oauth-connected-access.ts +0 -361
  187. package/src/drizzle/oauth-connected-collection.ts +0 -324
  188. package/src/drizzle/oauth-connected-custody.ts +0 -279
  189. package/src/drizzle/oauth-connected-flow.ts +0 -529
  190. package/src/drizzle/oauth-connected-input.ts +0 -147
  191. package/src/drizzle/oauth-connected-maintenance.ts +0 -346
  192. package/src/drizzle/oauth-connected-management.ts +0 -365
  193. package/src/drizzle/oauth-connected-settlement.ts +0 -251
  194. package/src/drizzle/oauth-connected-sign-in.ts +0 -443
  195. package/src/drizzle/oauth-connected-state.ts +0 -872
  196. package/src/drizzle/oauth-flow.ts +0 -462
  197. package/src/drizzle/oauth-input.ts +0 -201
  198. package/src/drizzle/oauth-owner.ts +0 -29
  199. package/src/drizzle/oauth-registration.ts +0 -640
  200. package/src/drizzle/oauth-state.ts +0 -218
@@ -1,374 +0,0 @@
1
- import { invariant, oauthIdentityKey, sameIdentity, storage } from "./oauth-state.mjs";
2
- import { both } from "./transaction-owner.mjs";
3
- import { CurrentOAuthTransaction, col, equal, matchesNativeRow } from "./oauth-owner.mjs";
4
- import { discoverOwned, exactClaim, resolveOwned, terminalFlow } from "./oauth-flow.mjs";
5
- import { eq, sql } from "drizzle-orm";
6
- import { Effect, Schema } from "effect";
7
- import { OAuthCredentialSnapshot, OAuthDisplayProfile, OAuthRegistrationAccess, OAuthRegistrationDecision, OAuthRegistrationFingerprint, OAuthRegistrationInspection, OAuthRegistrationIntent, OAuthSignInTransactionContext, snapshotOAuthSync } from "@yielded/auth/OAuth";
8
- //#region src/drizzle/oauth-registration.ts
9
- const intentStorage = storage(OAuthRegistrationIntent);
10
- const decisionStorage = storage(OAuthRegistrationDecision);
11
- const contextStorage = storage(OAuthSignInTransactionContext);
12
- const profileStorage = storage(Schema.NullOr(OAuthDisplayProfile));
13
- const reservationStorage = storage(Schema.Struct({
14
- moduleId: Schema.String,
15
- reference: Schema.String,
16
- commandId: Schema.String,
17
- fingerprint: Schema.String,
18
- provisioningIdentity: Schema.String
19
- }));
20
- const readTuple = (ownership, identity) => Effect.flatMap(CurrentOAuthTransaction, (owner) => Effect.gen(function* () {
21
- const t = ownership.tuple, key = yield* oauthIdentityKey(identity);
22
- const where = { [t.identityKey]: key };
23
- const observed = yield* owner.read(t.table, equal(t.table, where), { limit: 1 });
24
- if (observed.rows.length === 0) {
25
- const values = {
26
- ...t.encodeInsert({
27
- identityKey: key,
28
- identity
29
- }),
30
- ...where,
31
- [t.provider]: identity.provider,
32
- [t.issuer]: identity.issuer,
33
- [t.externalSubject]: identity.subject,
34
- [t.state]: "Unowned",
35
- [t.version]: owner.marker,
36
- [t.subjectId]: null,
37
- [t.reservation]: null
38
- };
39
- observed.rows = (yield* owner.insert(t.table, values, where, true)).rows;
40
- }
41
- const row = observed.rows[0];
42
- invariant(row[t.provider] === identity.provider && row[t.issuer] === identity.issuer && row[t.externalSubject] === identity.subject && [
43
- "Unowned",
44
- "Reserved",
45
- "Owned"
46
- ].includes(row[t.state]));
47
- invariant(row[t.state] === "Owned" ? row[t.subjectId] !== null : row[t.subjectId] === null && (row[t.state] === "Reserved" ? typeof row[t.reservation] === "string" : row[t.reservation] === null));
48
- if (ownership.mode === "separate") {
49
- const o = ownership.external;
50
- const external = yield* owner.read(o.table, equal(o.table, { [o.identityKey]: key }), { limit: 1 });
51
- if (row[t.state] === "Owned") {
52
- const linked = external.rows[0];
53
- invariant(linked !== void 0 && linked[o.provider] === identity.provider && linked[o.issuer] === identity.issuer && linked[o.externalSubject] === identity.subject && matchesNativeRow(o.table, linked, { [o.subjectId]: row[t.subjectId] }));
54
- const owned = sql`exists(select 1 from ${o.table} where ${both(equal(o.table, { [o.identityKey]: key }), o.ownedCondition)})`;
55
- invariant(yield* owner.check(owned));
56
- owner.postconditions.push(owned);
57
- } else invariant(external.rows.length === 0);
58
- }
59
- return {
60
- observed,
61
- row,
62
- key
63
- };
64
- }));
65
- const acquireTuple = (ownership, identity, key, subjectId) => Effect.flatMap(CurrentOAuthTransaction, (owner) => Effect.gen(function* () {
66
- const t = ownership.tuple;
67
- yield* owner.update(t.table, { [t.identityKey]: key }, {
68
- [t.state]: "Owned",
69
- [t.subjectId]: subjectId,
70
- [t.reservation]: null,
71
- [t.version]: owner.marker
72
- });
73
- if (ownership.mode === "separate") {
74
- const o = ownership.external;
75
- const values = {
76
- ...o.encodeInsert({
77
- identity,
78
- identityKey: key,
79
- subjectId
80
- }),
81
- [o.identityKey]: key,
82
- [o.provider]: identity.provider,
83
- [o.issuer]: identity.issuer,
84
- [o.externalSubject]: identity.subject,
85
- [o.subjectId]: subjectId
86
- };
87
- yield* owner.insert(o.table, values, { [o.identityKey]: key });
88
- }
89
- }));
90
- const settleRegistrationIntent = (mapping, input) => Effect.flatMap(CurrentOAuthTransaction, (owner) => Effect.gen(function* () {
91
- const identity = input.identity.identity, context = input.claim.flow.context;
92
- invariant(identity.provider === context.provider && identity.issuer === context.issuer);
93
- const found = yield* discoverOwned(mapping.signIn, identity);
94
- const tuple = found.owned ? void 0 : yield* readTuple(mapping.ownership, identity);
95
- const exact = yield* exactClaim(mapping.signIn, input.claim, "sign-in");
96
- if (exact === void 0) return { _tag: "Rejected" };
97
- const credential = resolveOwned(mapping.signIn, context.moduleId, identity, found);
98
- if (credential !== void 0) {
99
- yield* terminalFlow(mapping.signIn, input.claim.flow, "Verified");
100
- return {
101
- _tag: "Verified",
102
- credential
103
- };
104
- }
105
- let decision = { _tag: "Rejected" };
106
- if (!found.owned && tuple?.row[mapping.ownership.tuple.state] === "Unowned" && input.intent !== void 0) {
107
- const intent = snapshotOAuthSync(OAuthRegistrationIntent, input.intent);
108
- const c = intent.context;
109
- invariant(sameIdentity(intent.identity, identity) && profileStorage.encode(intent.profile ?? null) === profileStorage.encode(input.identity.profile ?? null) && intent.claimId === input.claim.claimId && intent.claimedAtMillis === input.claim.claimedAtMillis && contextStorage.encode(c) === contextStorage.encode(context));
110
- if (intent.issuedAtMillis >= intent.claimedAtMillis && intent.verifiedAtMillis <= intent.issuedAtMillis && intent.issuedAtMillis <= exact.now && exact.now < intent.expiresAtMillis && intent.expiresAtMillis <= c.requestBindingExpiresAtMillis && intent.retentionUntilMillis >= intent.expiresAtMillis && (yield* owner.check(mapping.eligibility.condition({ intent })))) {
111
- const i = mapping.intent, encode = mapping.signIn.clock.encodeInstant;
112
- const key = {
113
- [i.moduleId]: c.moduleId,
114
- [i.reference]: intent.reference
115
- };
116
- const values = {
117
- ...i.encodeInsert(snapshotOAuthSync(OAuthRegistrationIntent, intent)),
118
- ...key,
119
- [i.flowId]: c.flowId,
120
- [i.claimId]: intent.claimId,
121
- [i.identityKey]: tuple.key,
122
- [i.version]: owner.marker,
123
- [i.state]: "Unbound",
124
- [i.snapshot]: intentStorage.encode(intent),
125
- [i.commandId]: null,
126
- [i.fingerprint]: null,
127
- [i.pendingReference]: null,
128
- [i.expiresAt]: encode(intent.expiresAtMillis),
129
- [i.retentionUntil]: encode(intent.retentionUntilMillis)
130
- };
131
- yield* owner.insert(i.table, values, key);
132
- owner.postconditions.push(mapping.eligibility.condition({ intent }), sql`${mapping.signIn.clock.engineNowMillis} >= ${intent.issuedAtMillis} and
133
- ${mapping.signIn.clock.engineNowMillis} < ${intent.expiresAtMillis}`);
134
- decision = {
135
- _tag: "RegistrationIssued",
136
- intent
137
- };
138
- }
139
- }
140
- yield* terminalFlow(mapping.signIn, input.claim.flow, decision._tag);
141
- return decision;
142
- }));
143
- const inspectIntent = (mapping, original, discovery = false) => Effect.flatMap(CurrentOAuthTransaction, (owner) => Effect.gen(function* () {
144
- const access = snapshotOAuthSync(OAuthRegistrationAccess, original), i = mapping.intent;
145
- const observed = yield* owner.read(i.table, equal(i.table, {
146
- [i.moduleId]: access.moduleId,
147
- [i.reference]: access.reference
148
- }), {
149
- limit: 1,
150
- ...discovery ? {
151
- lock: false,
152
- observe: false
153
- } : {}
154
- });
155
- const row = observed.rows[0];
156
- if (row === void 0) return void 0;
157
- const intent = intentStorage.decode(row[i.snapshot]), c = intent.context, now = yield* owner.now(mapping.clock);
158
- invariant(row[i.moduleId] === c.moduleId && row[i.reference] === intent.reference && row[i.flowId] === c.flowId && row[i.claimId] === intent.claimId && row[i.identityKey] === (yield* oauthIdentityKey(intent.identity)) && mapping.clock.decodeInstant(row[i.expiresAt]) === intent.expiresAtMillis && mapping.clock.decodeInstant(row[i.retentionUntil]) === intent.retentionUntilMillis);
159
- if (access.moduleId !== c.moduleId || access.reference !== intent.reference || access.flowId !== c.flowId || access.requestBindingVerifier !== c.requestBindingVerifier || access.requestBindingExpiresAtMillis !== c.requestBindingExpiresAtMillis || access.credentialDigest !== intent.credentialDigest || now < intent.issuedAtMillis || now >= intent.expiresAtMillis) return void 0;
160
- let application;
161
- if (row[i.state] === "Unbound") {
162
- invariant(row[i.commandId] === null && row[i.fingerprint] === null && row[i.pendingReference] === null);
163
- application = { _tag: "Unbound" };
164
- } else application = {
165
- _tag: row[i.state],
166
- commandId: row[i.commandId],
167
- fingerprint: row[i.fingerprint],
168
- ...row[i.state] === "ProvisioningPending" ? { reference: row[i.pendingReference] } : {}
169
- };
170
- const inspection = snapshotOAuthSync(OAuthRegistrationInspection, {
171
- intent,
172
- application
173
- });
174
- owner.postconditions.push(sql`${mapping.clock.engineNowMillis} >= ${intent.issuedAtMillis} and
175
- ${mapping.clock.engineNowMillis} < ${intent.expiresAtMillis}`);
176
- return {
177
- observed,
178
- row,
179
- inspection
180
- };
181
- }));
182
- const registrationResources = (mapping) => Effect.gen(function* () {
183
- const provisioningIdentity = yield* mapping.allocateProvisioningIdentity;
184
- invariant(typeof provisioningIdentity === "string" && provisioningIdentity.length > 0 && provisioningIdentity.length <= 256);
185
- if (mapping.mode === "pending") {
186
- const pendingReference = yield* mapping.allocatePendingReference;
187
- invariant(typeof pendingReference === "string" && pendingReference.length > 0 && pendingReference.length <= 256);
188
- return {
189
- provisioningIdentity,
190
- pendingReference
191
- };
192
- }
193
- const subjectId = yield* mapping.allocateSubjectId;
194
- const publicId = yield* mapping.subjectId.toSubject(subjectId);
195
- invariant(mapping.subjectId.equals(subjectId, yield* mapping.subjectId.toNative(publicId)));
196
- return {
197
- provisioningIdentity,
198
- subjectId,
199
- credentialId: snapshotOAuthSync(OAuthCredentialSnapshot.fields.credentialId, yield* mapping.allocateCredentialId),
200
- revision: snapshotOAuthSync(OAuthCredentialSnapshot.fields.credentialRevision, yield* mapping.allocateRevision)
201
- };
202
- });
203
- const registrationData = (mapping, input, bound) => Effect.gen(function* () {
204
- const snapshot = bound ? (invariant(mapping.snapshotSync !== void 0), mapping.snapshotSync(input.registration)) : yield* mapping.snapshot(input.registration);
205
- const encoded = mapping.application.encode(snapshot);
206
- invariant(typeof encoded === "string" && new TextEncoder().encode(encoded).length <= 1048576);
207
- const detached = mapping.application.decode(encoded);
208
- invariant(mapping.application.encode(detached) === encoded);
209
- const checked = bound ? (invariant(mapping.inspectSync !== void 0), mapping.inspectSync({
210
- intent: snapshotOAuthSync(OAuthRegistrationIntent, input.intent),
211
- registration: mapping.application.decode(encoded)
212
- })) : yield* mapping.inspect({
213
- intent: snapshotOAuthSync(OAuthRegistrationIntent, input.intent),
214
- registration: mapping.application.decode(encoded)
215
- });
216
- const fingerprint = snapshotOAuthSync(OAuthRegistrationFingerprint, checked.fingerprint);
217
- invariant(typeof checked.eligible === "boolean");
218
- return {
219
- encoded,
220
- registration: detached,
221
- fingerprint,
222
- eligible: checked.eligible && fingerprint === input.fingerprint
223
- };
224
- });
225
- const register = (mapping, input, data, resources) => Effect.flatMap(CurrentOAuthTransaction, (owner) => Effect.gen(function* () {
226
- const intent = snapshotOAuthSync(OAuthRegistrationIntent, input.intent), c = intent.context;
227
- const discovered = yield* inspectIntent(mapping, input.access, true);
228
- if (discovered === void 0 || intentStorage.encode(discovered.inspection.intent) !== intentStorage.encode(intent)) return { _tag: "Rejected" };
229
- const nativeSubjectId = resources.subjectId;
230
- const policyInput = () => ({
231
- intent: snapshotOAuthSync(OAuthRegistrationIntent, intent),
232
- registration: mapping.application.decode(data.encoded),
233
- ...mapping.mode === "atomic" ? { nativeSubjectId } : {}
234
- });
235
- invariant((mapping.eligibility.guards?.length ?? 0) <= 32);
236
- for (const guard of mapping.eligibility.guards ?? []) {
237
- const locked = yield* owner.read(guard.table, guard.condition(policyInput()), {
238
- orderBy: col(guard.table, guard.orderBy),
239
- admissionOnly: true
240
- });
241
- invariant(locked.rows.length > 0);
242
- }
243
- const tuple = yield* readTuple(mapping.ownership, intent.identity);
244
- const inspected = yield* inspectIntent(mapping, input.access);
245
- if (inspected === void 0 || intentStorage.encode(inspected.inspection.intent) !== intentStorage.encode(intent)) return { _tag: "Rejected" };
246
- const r = mapping.command, i = mapping.intent, t = mapping.ownership.tuple;
247
- const commandKey = {
248
- [r.moduleId]: c.moduleId,
249
- [r.commandId]: input.commandId
250
- };
251
- const command = yield* owner.read(r.table, equal(r.table, commandKey), { limit: 1 });
252
- const previous = command.rows[0];
253
- if (previous !== void 0) {
254
- if (previous[r.reference] !== intent.reference || previous[r.identityKey] !== tuple.key || previous[r.fingerprint] !== data.fingerprint || previous[r.intentSnapshot] !== intentStorage.encode(intent) || previous[r.applicationSnapshot] !== data.encoded) return { _tag: "Conflict" };
255
- invariant(mapping.application.encode(mapping.application.decode(previous[r.applicationSnapshot])) === data.encoded);
256
- const old = decisionStorage.decode(previous[r.decision]);
257
- invariant(inspected.inspection.application._tag === old._tag);
258
- return old._tag === "Registered" || old._tag === "ProvisioningPending" ? {
259
- ...old,
260
- replayed: true
261
- } : old;
262
- }
263
- if (inspected.inspection.application._tag !== "Unbound" || tuple.row[t.state] !== "Unowned") return { _tag: "Conflict" };
264
- if (data.fingerprint !== input.fingerprint) return { _tag: "Rejected" };
265
- const admitted = data.eligible && (yield* owner.check(mapping.eligibility.admission(policyInput())));
266
- let decision;
267
- if (!admitted) decision = { _tag: "Rejected" };
268
- else if (mapping.mode === "pending") {
269
- invariant(resources.pendingReference !== void 0);
270
- const reservation = reservationStorage.encode({
271
- moduleId: c.moduleId,
272
- reference: intent.reference,
273
- commandId: input.commandId,
274
- fingerprint: data.fingerprint,
275
- provisioningIdentity: resources.provisioningIdentity
276
- });
277
- yield* owner.update(t.table, { [t.identityKey]: tuple.key }, {
278
- [t.state]: "Reserved",
279
- [t.version]: owner.marker,
280
- [t.reservation]: reservation
281
- });
282
- decision = {
283
- _tag: "ProvisioningPending",
284
- reference: resources.pendingReference,
285
- replayed: false
286
- };
287
- } else {
288
- invariant(resources.credentialId !== void 0 && resources.revision !== void 0);
289
- const s = mapping.subject, cr = mapping.credential, a = mapping.authority;
290
- const subjectValues = {
291
- ...mapping.encodeSubjectInsert(policyInput(), {
292
- subjectId: nativeSubjectId,
293
- securityRevision: resources.revision
294
- }),
295
- [s.id]: nativeSubjectId,
296
- [s.securityRevision]: resources.revision
297
- };
298
- yield* owner.insert(s.table, subjectValues, { [s.id]: nativeSubjectId });
299
- const credentialValues = {
300
- ...cr.encodeInsert({
301
- moduleId: c.moduleId,
302
- subjectId: nativeSubjectId,
303
- identityKey: tuple.key,
304
- credentialId: resources.credentialId,
305
- credentialRevision: resources.revision
306
- }),
307
- [cr.moduleId]: c.moduleId,
308
- [cr.subjectId]: nativeSubjectId,
309
- [cr.identityKey]: tuple.key,
310
- [cr.credentialId]: resources.credentialId,
311
- [cr.credentialRevision]: resources.revision
312
- };
313
- invariant(cr.isActiveStatus(credentialValues[cr.status]) && s.isActiveStatus(subjectValues[s.status]));
314
- yield* owner.insert(cr.table, credentialValues, { [cr.credentialId]: resources.credentialId });
315
- const authorityValues = {
316
- ...a.encodeInsert({
317
- subjectId: nativeSubjectId,
318
- credentialId: resources.credentialId,
319
- revision: resources.revision
320
- }),
321
- [a.subjectId]: nativeSubjectId,
322
- [a.credentialId]: resources.credentialId,
323
- [a.revision]: resources.revision
324
- };
325
- invariant(a.isActiveStatus(authorityValues[a.status]));
326
- yield* owner.insert(a.table, authorityValues, {
327
- [a.subjectId]: nativeSubjectId,
328
- [a.credentialId]: resources.credentialId
329
- });
330
- yield* acquireTuple(mapping.ownership, intent.identity, tuple.key, nativeSubjectId);
331
- owner.postconditions.push(sql`exists(select 1 from ${s.table} where ${both(eq(col(s.table, s.id), nativeSubjectId), s.activeCondition)})`, sql`exists(select 1 from ${cr.table} where ${both(eq(col(cr.table, cr.credentialId), resources.credentialId), cr.activeCondition)})`, sql`exists(select 1 from ${a.table} where ${both(eq(col(a.table, a.credentialId), resources.credentialId), eq(col(a.table, a.subjectId), nativeSubjectId), a.activeCondition)})`);
332
- decision = {
333
- _tag: "Registered",
334
- replayed: false
335
- };
336
- }
337
- const now = yield* owner.now(mapping.clock);
338
- invariant(Number.isSafeInteger(mapping.retentionMillis) && mapping.retentionMillis >= 12e4);
339
- const values = {
340
- ...r.encodeInsert({
341
- intent: snapshotOAuthSync(OAuthRegistrationIntent, intent),
342
- commandId: input.commandId,
343
- fingerprint: data.fingerprint,
344
- registration: mapping.application.decode(data.encoded),
345
- provisioningIdentity: resources.provisioningIdentity
346
- }),
347
- ...commandKey,
348
- [r.reference]: intent.reference,
349
- [r.identityKey]: tuple.key,
350
- [r.fingerprint]: data.fingerprint,
351
- [r.intentSnapshot]: intentStorage.encode(intent),
352
- [r.applicationSnapshot]: data.encoded,
353
- [r.provisioningIdentity]: resources.provisioningIdentity,
354
- [r.decision]: decisionStorage.encode(decision),
355
- [r.retentionUntil]: mapping.clock.encodeInstant(Math.max(intent.retentionUntilMillis, now + mapping.retentionMillis))
356
- };
357
- command.rows = (yield* owner.insert(r.table, values, commandKey)).rows;
358
- yield* owner.update(i.table, {
359
- [i.moduleId]: c.moduleId,
360
- [i.reference]: intent.reference
361
- }, {
362
- [i.state]: decision._tag,
363
- [i.commandId]: input.commandId,
364
- [i.fingerprint]: data.fingerprint,
365
- [i.version]: owner.marker,
366
- [i.pendingReference]: decision._tag === "ProvisioningPending" ? decision.reference : null
367
- });
368
- if (admitted) owner.postconditions.push(mapping.eligibility.postcondition(policyInput()));
369
- return decision;
370
- }));
371
- //#endregion
372
- export { acquireTuple, inspectIntent, intentStorage, readTuple, register, registrationData, registrationResources, settleRegistrationIntent };
373
-
374
- //# sourceMappingURL=oauth-registration.mjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"oauth-registration.mjs","names":[],"sources":["../../src/drizzle/oauth-registration.ts"],"sourcesContent":["import {\n OAuthRegistrationAccess,\n OAuthRegistrationDecision,\n OAuthRegistrationFingerprint,\n OAuthRegistrationInspection,\n OAuthRegistrationIntent,\n OAuthCredentialSnapshot,\n OAuthDisplayProfile,\n OAuthSignInTransactionContext,\n type OAuthExternalIdentity,\n snapshotOAuthSync,\n} from \"@yielded/auth/OAuth\";\nimport type { SecurityRevision } from \"@yielded/auth/Sessions\";\n/* oxlint-disable no-explicit-any -- private owner kernel preserves Registration at the exported constructor. */\nimport { eq, sql } from \"drizzle-orm\";\nimport { Effect, Schema } from \"effect\";\n\nimport type { PersistenceMappingError, SubjectIdCodec } from \"./model\";\nimport { discoverOwned, exactClaim, resolveOwned, terminalFlow } from \"./oauth-flow\";\nimport type { OAuthRegistrationBase } from \"./oauth-model\";\nimport { both, col, equal, matchesNativeRow, CurrentOAuthTransaction } from \"./oauth-owner\";\nimport { invariant, oauthIdentityKey, sameIdentity, storage } from \"./oauth-state\";\n\nexport const intentStorage = storage(OAuthRegistrationIntent);\nconst decisionStorage = storage(OAuthRegistrationDecision);\nconst contextStorage = storage(OAuthSignInTransactionContext);\nconst profileStorage = storage(Schema.NullOr(OAuthDisplayProfile));\n\nconst reservationStorage = storage(\n Schema.Struct({\n moduleId: Schema.String,\n reference: Schema.String,\n commandId: Schema.String,\n fingerprint: Schema.String,\n provisioningIdentity: Schema.String,\n }),\n);\n\nexport const readTuple = (ownership: any, identity: typeof OAuthExternalIdentity.Type) =>\n Effect.flatMap(CurrentOAuthTransaction, (owner) =>\n Effect.gen(function* () {\n const t = ownership.tuple,\n key = yield* oauthIdentityKey(identity);\n\n const where = { [t.identityKey]: key };\n const observed = yield* owner.read(t.table, equal(t.table, where), { limit: 1 });\n\n if (observed.rows.length === 0) {\n const values = {\n ...t.encodeInsert({ identityKey: key, identity }),\n ...where,\n [t.provider]: identity.provider,\n [t.issuer]: identity.issuer,\n [t.externalSubject]: identity.subject,\n [t.state]: \"Unowned\",\n [t.version]: owner.marker,\n [t.subjectId]: null,\n [t.reservation]: null,\n };\n\n const inserted = yield* owner.insert(t.table, values, where, true);\n\n observed.rows = inserted.rows;\n }\n const row = observed.rows[0]!;\n\n invariant(\n row[t.provider] === identity.provider &&\n row[t.issuer] === identity.issuer &&\n row[t.externalSubject] === identity.subject &&\n [\"Unowned\", \"Reserved\", \"Owned\"].includes(row[t.state]),\n );\n invariant(\n row[t.state] === \"Owned\"\n ? row[t.subjectId] !== null\n : row[t.subjectId] === null &&\n (row[t.state] === \"Reserved\"\n ? typeof row[t.reservation] === \"string\"\n : row[t.reservation] === null),\n );\n if (ownership.mode === \"separate\") {\n const o = ownership.external;\n\n const external = yield* owner.read(o.table, equal(o.table, { [o.identityKey]: key }), {\n limit: 1,\n });\n\n if (row[t.state] === \"Owned\") {\n const linked = external.rows[0];\n\n invariant(\n linked !== undefined &&\n linked[o.provider] === identity.provider &&\n linked[o.issuer] === identity.issuer &&\n linked[o.externalSubject] === identity.subject &&\n matchesNativeRow(o.table, linked, { [o.subjectId]: row[t.subjectId] }),\n );\n const owned = sql`exists(select 1 from ${o.table} where ${both(equal(o.table, { [o.identityKey]: key }), o.ownedCondition)})`;\n\n invariant(yield* owner.check(owned));\n owner.postconditions.push(owned);\n } else invariant(external.rows.length === 0);\n }\n\n return { observed, row, key };\n }),\n );\n\nexport const acquireTuple = (\n ownership: any,\n identity: typeof OAuthExternalIdentity.Type,\n key: string,\n subjectId: unknown,\n) =>\n Effect.flatMap(CurrentOAuthTransaction, (owner) =>\n Effect.gen(function* () {\n const t = ownership.tuple;\n\n yield* owner.update(\n t.table,\n { [t.identityKey]: key },\n {\n [t.state]: \"Owned\",\n [t.subjectId]: subjectId,\n [t.reservation]: null,\n [t.version]: owner.marker,\n },\n );\n if (ownership.mode === \"separate\") {\n const o = ownership.external;\n\n const values = {\n ...o.encodeInsert({ identity, identityKey: key, subjectId }),\n [o.identityKey]: key,\n [o.provider]: identity.provider,\n [o.issuer]: identity.issuer,\n [o.externalSubject]: identity.subject,\n [o.subjectId]: subjectId,\n };\n\n yield* owner.insert(o.table, values, { [o.identityKey]: key });\n }\n }),\n );\n\nexport const settleRegistrationIntent = (mapping: any, input: any) =>\n Effect.flatMap(CurrentOAuthTransaction, (owner) =>\n Effect.gen(function* () {\n const identity = input.identity.identity,\n context = input.claim.flow.context;\n\n invariant(identity.provider === context.provider && identity.issuer === context.issuer);\n const found = yield* discoverOwned(mapping.signIn, identity);\n const tuple = found.owned ? undefined : yield* readTuple(mapping.ownership, identity);\n const exact = yield* exactClaim(mapping.signIn, input.claim, \"sign-in\");\n\n if (exact === undefined) return { _tag: \"Rejected\" } as const;\n const credential = resolveOwned(mapping.signIn, context.moduleId, identity, found);\n\n if (credential !== undefined) {\n yield* terminalFlow(mapping.signIn, input.claim.flow, \"Verified\");\n\n return { _tag: \"Verified\", credential } as const;\n }\n let decision: any = { _tag: \"Rejected\" };\n\n if (\n !found.owned &&\n tuple?.row[mapping.ownership.tuple.state] === \"Unowned\" &&\n input.intent !== undefined\n ) {\n const intent = snapshotOAuthSync(OAuthRegistrationIntent, input.intent);\n const c = intent.context;\n\n invariant(\n sameIdentity(intent.identity, identity) &&\n profileStorage.encode(intent.profile ?? null) ===\n profileStorage.encode(input.identity.profile ?? null) &&\n intent.claimId === input.claim.claimId &&\n intent.claimedAtMillis === input.claim.claimedAtMillis &&\n contextStorage.encode(c) === contextStorage.encode(context),\n );\n\n const allowed =\n intent.issuedAtMillis >= intent.claimedAtMillis &&\n intent.verifiedAtMillis <= intent.issuedAtMillis &&\n intent.issuedAtMillis <= exact.now &&\n exact.now < intent.expiresAtMillis &&\n intent.expiresAtMillis <= c.requestBindingExpiresAtMillis &&\n intent.retentionUntilMillis >= intent.expiresAtMillis &&\n (yield* owner.check(mapping.eligibility.condition({ intent })));\n\n if (allowed) {\n const i = mapping.intent,\n encode = mapping.signIn.clock.encodeInstant;\n\n const key = { [i.moduleId]: c.moduleId, [i.reference]: intent.reference };\n\n const values = {\n ...i.encodeInsert(snapshotOAuthSync(OAuthRegistrationIntent, intent)),\n ...key,\n [i.flowId]: c.flowId,\n [i.claimId]: intent.claimId,\n [i.identityKey]: tuple.key,\n [i.version]: owner.marker,\n [i.state]: \"Unbound\",\n [i.snapshot]: intentStorage.encode(intent),\n [i.commandId]: null,\n [i.fingerprint]: null,\n [i.pendingReference]: null,\n [i.expiresAt]: encode(intent.expiresAtMillis),\n [i.retentionUntil]: encode(intent.retentionUntilMillis),\n };\n\n yield* owner.insert(i.table, values, key);\n owner.postconditions.push(\n mapping.eligibility.condition({ intent }),\n sql`${mapping.signIn.clock.engineNowMillis} >= ${intent.issuedAtMillis} and\n ${mapping.signIn.clock.engineNowMillis} < ${intent.expiresAtMillis}`,\n );\n decision = { _tag: \"RegistrationIssued\", intent };\n }\n }\n yield* terminalFlow(mapping.signIn, input.claim.flow, decision._tag);\n\n return decision;\n }),\n );\n\nexport const inspectIntent = (\n mapping: any,\n original: typeof OAuthRegistrationAccess.Type,\n discovery = false,\n) =>\n Effect.flatMap(CurrentOAuthTransaction, (owner) =>\n Effect.gen(function* () {\n const access = snapshotOAuthSync(OAuthRegistrationAccess, original),\n i = mapping.intent;\n\n const observed = yield* owner.read(\n i.table,\n equal(i.table, {\n [i.moduleId]: access.moduleId,\n [i.reference]: access.reference,\n }),\n { limit: 1, ...(discovery ? { lock: false, observe: false } : {}) },\n );\n\n const row = observed.rows[0];\n\n if (row === undefined) return undefined;\n\n const intent = intentStorage.decode(row[i.snapshot]),\n c = intent.context,\n now = yield* owner.now(mapping.clock);\n\n invariant(\n row[i.moduleId] === c.moduleId &&\n row[i.reference] === intent.reference &&\n row[i.flowId] === c.flowId &&\n row[i.claimId] === intent.claimId &&\n row[i.identityKey] === (yield* oauthIdentityKey(intent.identity)) &&\n mapping.clock.decodeInstant(row[i.expiresAt]) === intent.expiresAtMillis &&\n mapping.clock.decodeInstant(row[i.retentionUntil]) === intent.retentionUntilMillis,\n );\n if (\n access.moduleId !== c.moduleId ||\n access.reference !== intent.reference ||\n access.flowId !== c.flowId ||\n access.requestBindingVerifier !== c.requestBindingVerifier ||\n access.requestBindingExpiresAtMillis !== c.requestBindingExpiresAtMillis ||\n access.credentialDigest !== intent.credentialDigest ||\n now < intent.issuedAtMillis ||\n now >= intent.expiresAtMillis\n )\n return undefined;\n let application: any;\n\n if (row[i.state] === \"Unbound\") {\n invariant(\n row[i.commandId] === null &&\n row[i.fingerprint] === null &&\n row[i.pendingReference] === null,\n );\n application = { _tag: \"Unbound\" };\n } else {\n application = {\n _tag: row[i.state],\n commandId: row[i.commandId],\n fingerprint: row[i.fingerprint],\n ...(row[i.state] === \"ProvisioningPending\" ? { reference: row[i.pendingReference] } : {}),\n };\n }\n const inspection = snapshotOAuthSync(OAuthRegistrationInspection, { intent, application });\n\n owner.postconditions.push(sql`${mapping.clock.engineNowMillis} >= ${intent.issuedAtMillis} and\n ${mapping.clock.engineNowMillis} < ${intent.expiresAtMillis}`);\n\n return { observed, row, inspection };\n }),\n );\n\nexport interface RegistrationResources {\n readonly provisioningIdentity: string;\n readonly pendingReference?: string;\n readonly subjectId?: unknown;\n readonly credentialId?: string;\n readonly revision?: string;\n}\n\n/** Public mapping callbacks are closed Effects; erasing native row shapes must\n * not erase their error or requirements channels. */\nexport type RegistrationCallbacks<Registration> = Pick<\n OAuthRegistrationBase<Registration, any, any, any, any, unknown>,\n \"snapshot\" | \"snapshotSync\" | \"inspect\" | \"inspectSync\"\n>;\n\nexport const registrationResources = (mapping: any) =>\n Effect.gen(function* () {\n const provisioningIdentity = yield* mapping.allocateProvisioningIdentity as Effect.Effect<\n string,\n PersistenceMappingError\n >;\n\n invariant(\n typeof provisioningIdentity === \"string\" &&\n provisioningIdentity.length > 0 &&\n provisioningIdentity.length <= 256,\n );\n if (mapping.mode === \"pending\") {\n const pendingReference = yield* mapping.allocatePendingReference as Effect.Effect<\n string,\n PersistenceMappingError\n >;\n\n invariant(\n typeof pendingReference === \"string\" &&\n pendingReference.length > 0 &&\n pendingReference.length <= 256,\n );\n\n return { provisioningIdentity, pendingReference } as RegistrationResources;\n }\n\n const subjectId = yield* mapping.allocateSubjectId as Effect.Effect<\n unknown,\n PersistenceMappingError\n >;\n\n const publicId = yield* (mapping.subjectId as SubjectIdCodec<unknown>).toSubject(subjectId);\n\n invariant(\n mapping.subjectId.equals(\n subjectId,\n yield* (mapping.subjectId as SubjectIdCodec<unknown>).toNative(publicId),\n ),\n );\n\n const credentialId = snapshotOAuthSync(\n OAuthCredentialSnapshot.fields.credentialId,\n yield* mapping.allocateCredentialId as Effect.Effect<string, PersistenceMappingError>,\n );\n\n const revision = snapshotOAuthSync(\n OAuthCredentialSnapshot.fields.credentialRevision,\n yield* mapping.allocateRevision as Effect.Effect<SecurityRevision, PersistenceMappingError>,\n );\n\n return { provisioningIdentity, subjectId, credentialId, revision } as RegistrationResources;\n });\n\nexport const registrationData = <Registration>(\n mapping: any,\n input: {\n readonly intent: OAuthRegistrationIntent;\n readonly registration: Registration;\n readonly fingerprint: string;\n },\n bound: boolean,\n) =>\n Effect.gen(function* () {\n const snapshot = bound\n ? (invariant(mapping.snapshotSync !== undefined), mapping.snapshotSync(input.registration))\n : yield* (mapping as RegistrationCallbacks<Registration>).snapshot(input.registration);\n\n const encoded = mapping.application.encode(snapshot);\n\n invariant(typeof encoded === \"string\" && new TextEncoder().encode(encoded).length <= 1048576);\n const detached = mapping.application.decode(encoded);\n\n invariant(mapping.application.encode(detached) === encoded);\n\n const checked = bound\n ? (invariant(mapping.inspectSync !== undefined),\n mapping.inspectSync({\n intent: snapshotOAuthSync(OAuthRegistrationIntent, input.intent),\n registration: mapping.application.decode(encoded),\n }))\n : yield* (mapping as RegistrationCallbacks<Registration>).inspect({\n intent: snapshotOAuthSync(OAuthRegistrationIntent, input.intent),\n registration: mapping.application.decode(encoded),\n });\n\n const fingerprint = snapshotOAuthSync(OAuthRegistrationFingerprint, checked.fingerprint);\n\n invariant(typeof checked.eligible === \"boolean\");\n\n return {\n encoded,\n registration: detached as Registration,\n fingerprint,\n eligible: checked.eligible && fingerprint === input.fingerprint,\n };\n });\n\nexport const register = (\n mapping: any,\n input: any,\n data: { readonly encoded: string; readonly fingerprint: string; readonly eligible: boolean },\n resources: RegistrationResources,\n) =>\n Effect.flatMap(CurrentOAuthTransaction, (owner) =>\n Effect.gen(function* () {\n const intent = snapshotOAuthSync(OAuthRegistrationIntent, input.intent),\n c = intent.context;\n\n const discovered = yield* inspectIntent(mapping, input.access, true);\n\n if (\n discovered === undefined ||\n intentStorage.encode(discovered.inspection.intent) !== intentStorage.encode(intent)\n )\n return { _tag: \"Rejected\" } as const;\n const nativeSubjectId = resources.subjectId;\n\n const policyInput = () => ({\n intent: snapshotOAuthSync(OAuthRegistrationIntent, intent),\n registration: mapping.application.decode(data.encoded),\n ...(mapping.mode === \"atomic\" ? { nativeSubjectId } : {}),\n });\n\n invariant((mapping.eligibility.guards?.length ?? 0) <= 32);\n for (const guard of mapping.eligibility.guards ?? []) {\n const locked = yield* owner.read(guard.table, guard.condition(policyInput()), {\n orderBy: col(guard.table, guard.orderBy),\n admissionOnly: true,\n });\n\n invariant(locked.rows.length > 0);\n }\n const tuple = yield* readTuple(mapping.ownership, intent.identity);\n const inspected = yield* inspectIntent(mapping, input.access);\n\n if (\n inspected === undefined ||\n intentStorage.encode(inspected.inspection.intent) !== intentStorage.encode(intent)\n )\n return { _tag: \"Rejected\" } as const;\n\n const r = mapping.command,\n i = mapping.intent,\n t = mapping.ownership.tuple;\n\n const commandKey = { [r.moduleId]: c.moduleId, [r.commandId]: input.commandId };\n const command = yield* owner.read(r.table, equal(r.table, commandKey), { limit: 1 });\n const previous = command.rows[0];\n\n if (previous !== undefined) {\n if (\n previous[r.reference] !== intent.reference ||\n previous[r.identityKey] !== tuple.key ||\n previous[r.fingerprint] !== data.fingerprint ||\n previous[r.intentSnapshot] !== intentStorage.encode(intent) ||\n previous[r.applicationSnapshot] !== data.encoded\n )\n return { _tag: \"Conflict\" } as const;\n invariant(\n mapping.application.encode(\n mapping.application.decode(previous[r.applicationSnapshot]),\n ) === data.encoded,\n );\n const old = decisionStorage.decode(previous[r.decision]);\n\n invariant(inspected.inspection.application._tag === old._tag);\n\n return old._tag === \"Registered\" || old._tag === \"ProvisioningPending\"\n ? { ...old, replayed: true }\n : old;\n }\n if (inspected.inspection.application._tag !== \"Unbound\" || tuple.row[t.state] !== \"Unowned\")\n return { _tag: \"Conflict\" } as const;\n if (data.fingerprint !== input.fingerprint) return { _tag: \"Rejected\" } as const;\n\n const admitted =\n data.eligible && (yield* owner.check(mapping.eligibility.admission(policyInput())));\n\n let decision: typeof OAuthRegistrationDecision.Type;\n\n if (!admitted) decision = { _tag: \"Rejected\" };\n else if (mapping.mode === \"pending\") {\n invariant(resources.pendingReference !== undefined);\n\n const reservation = reservationStorage.encode({\n moduleId: c.moduleId,\n reference: intent.reference,\n commandId: input.commandId,\n fingerprint: data.fingerprint,\n provisioningIdentity: resources.provisioningIdentity,\n });\n\n yield* owner.update(\n t.table,\n { [t.identityKey]: tuple.key },\n {\n [t.state]: \"Reserved\",\n [t.version]: owner.marker,\n [t.reservation]: reservation,\n },\n );\n decision = {\n _tag: \"ProvisioningPending\",\n reference: resources.pendingReference,\n replayed: false,\n };\n } else {\n invariant(resources.credentialId !== undefined && resources.revision !== undefined);\n\n const s = mapping.subject,\n cr = mapping.credential,\n a = mapping.authority;\n\n const subjectValues = {\n ...mapping.encodeSubjectInsert(policyInput(), {\n subjectId: nativeSubjectId,\n securityRevision: resources.revision,\n }),\n [s.id]: nativeSubjectId,\n [s.securityRevision]: resources.revision,\n };\n\n yield* owner.insert(s.table, subjectValues, { [s.id]: nativeSubjectId });\n\n const credentialValues = {\n ...cr.encodeInsert({\n moduleId: c.moduleId,\n subjectId: nativeSubjectId,\n identityKey: tuple.key,\n credentialId: resources.credentialId,\n credentialRevision: resources.revision,\n }),\n [cr.moduleId]: c.moduleId,\n [cr.subjectId]: nativeSubjectId,\n [cr.identityKey]: tuple.key,\n [cr.credentialId]: resources.credentialId,\n [cr.credentialRevision]: resources.revision,\n };\n\n invariant(\n cr.isActiveStatus(credentialValues[cr.status]) &&\n s.isActiveStatus(subjectValues[s.status]),\n );\n yield* owner.insert(cr.table, credentialValues, {\n [cr.credentialId]: resources.credentialId,\n });\n\n const authorityValues = {\n ...a.encodeInsert({\n subjectId: nativeSubjectId,\n credentialId: resources.credentialId,\n revision: resources.revision,\n }),\n [a.subjectId]: nativeSubjectId,\n [a.credentialId]: resources.credentialId,\n [a.revision]: resources.revision,\n };\n\n invariant(a.isActiveStatus(authorityValues[a.status]));\n yield* owner.insert(a.table, authorityValues, {\n [a.subjectId]: nativeSubjectId,\n [a.credentialId]: resources.credentialId,\n });\n yield* acquireTuple(mapping.ownership, intent.identity, tuple.key, nativeSubjectId);\n owner.postconditions.push(\n sql`exists(select 1 from ${s.table} where ${both(\n eq(col(s.table, s.id), nativeSubjectId),\n s.activeCondition,\n )})`,\n sql`exists(select 1 from ${cr.table} where ${both(eq(col(cr.table, cr.credentialId), resources.credentialId), cr.activeCondition)})`,\n sql`exists(select 1 from ${a.table} where ${both(\n eq(col(a.table, a.credentialId), resources.credentialId),\n eq(col(a.table, a.subjectId), nativeSubjectId),\n a.activeCondition,\n )})`,\n );\n decision = { _tag: \"Registered\", replayed: false };\n }\n const now = yield* owner.now(mapping.clock);\n\n invariant(Number.isSafeInteger(mapping.retentionMillis) && mapping.retentionMillis >= 120000);\n\n const values = {\n ...r.encodeInsert({\n intent: snapshotOAuthSync(OAuthRegistrationIntent, intent),\n commandId: input.commandId,\n fingerprint: data.fingerprint,\n registration: mapping.application.decode(data.encoded),\n provisioningIdentity: resources.provisioningIdentity,\n }),\n ...commandKey,\n [r.reference]: intent.reference,\n [r.identityKey]: tuple.key,\n [r.fingerprint]: data.fingerprint,\n [r.intentSnapshot]: intentStorage.encode(intent),\n [r.applicationSnapshot]: data.encoded,\n [r.provisioningIdentity]: resources.provisioningIdentity,\n [r.decision]: decisionStorage.encode(decision),\n [r.retentionUntil]: mapping.clock.encodeInstant(\n Math.max(intent.retentionUntilMillis, now + mapping.retentionMillis),\n ),\n };\n\n const inserted = yield* owner.insert(r.table, values, commandKey);\n\n command.rows = inserted.rows;\n yield* owner.update(\n i.table,\n { [i.moduleId]: c.moduleId, [i.reference]: intent.reference },\n {\n [i.state]: decision._tag,\n [i.commandId]: input.commandId,\n [i.fingerprint]: data.fingerprint,\n [i.version]: owner.marker,\n [i.pendingReference]: decision._tag === \"ProvisioningPending\" ? decision.reference : null,\n },\n );\n if (admitted) owner.postconditions.push(mapping.eligibility.postcondition(policyInput()));\n\n return decision;\n }),\n );\n"],"mappings":"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"}
@@ -1,107 +0,0 @@
1
- import { digest, randomId } from "./crypto.mjs";
2
- import { Crypto, DateTime, Effect, Schema } from "effect";
3
- import { OAuthExternalIdentity, OAuthUnavailable, snapshotOAuthSync } from "@yielded/auth/OAuth";
4
- import { Base64Url } from "effect/encoding";
5
- //#region src/drizzle/oauth-state.ts
6
- const encoder = new TextEncoder();
7
- const decoder = new TextDecoder("utf-8", { fatal: true });
8
- const unavailable = () => OAuthUnavailable.make({});
9
- const invariant = (value) => {
10
- if (!value) throw unavailable();
11
- };
12
- const nonce = randomId;
13
- /** Capture configuration/callback references while preserving Drizzle table, SQL
14
- * and Effect objects. Never freeze or mutate the consumer's original graph. */
15
- const captureOAuthMapping = (input) => {
16
- const seen = /* @__PURE__ */ new Map();
17
- const copy = (value) => {
18
- if (value === null || typeof value !== "object" || Effect.isEffect(value)) return value;
19
- if (!Array.isArray(value) && Object.getPrototypeOf(value) !== Object.prototype) return value;
20
- const prior = seen.get(value);
21
- if (prior !== void 0) return prior;
22
- if (Array.isArray(value)) {
23
- const result = [];
24
- seen.set(value, result);
25
- result.push(...value.map(copy));
26
- return Object.freeze(result);
27
- }
28
- const result = {};
29
- seen.set(value, result);
30
- for (const [key, child] of Object.entries(value)) result[key] = copy(child);
31
- return Object.freeze(result);
32
- };
33
- return copy(input);
34
- };
35
- /** Versioned length-delimited UTF-8 tuple; the module is deliberately excluded.
36
- * Reject ill-formed UTF-16 rather than letting UTF-8 replacement alias identities. */
37
- const oauthIdentityKey = Effect.fnUntraced(function* (input) {
38
- const identity = snapshotOAuthSync(OAuthExternalIdentity, input);
39
- const bytes = [
40
- "effect-auth/oauth-identity-key/v1",
41
- identity.provider,
42
- identity.issuer,
43
- identity.subject
44
- ].map((field) => {
45
- const value = encoder.encode(field);
46
- invariant(decoder.decode(value) === field);
47
- return value;
48
- });
49
- const packed = new Uint8Array(bytes.reduce((size, value) => size + 4 + value.length, 0));
50
- const view = new DataView(packed.buffer);
51
- let offset = 0;
52
- for (const value of bytes) {
53
- view.setUint32(offset, value.length, false);
54
- packed.set(value, offset + 4);
55
- offset += 4 + value.length;
56
- }
57
- const crypto = yield* Crypto.Crypto;
58
- return "v1:" + Base64Url.encode(yield* crypto.digest("SHA-256", packed));
59
- });
60
- const sameIdentity = (left, right) => left.provider === right.provider && left.issuer === right.issuer && left.subject === right.subject;
61
- /** Private Type storage: opaque wrappers and DateTimes are freshly reconstructed. */
62
- const storage = (schema) => {
63
- const codec = Schema.fromJsonString(Schema.toCodecJson(Schema.toType(schema)));
64
- const encode = Schema.encodeSync(codec);
65
- const decode = Schema.decodeSync(codec);
66
- return {
67
- encode: (value) => encode(snapshotOAuthSync(schema, value)),
68
- decode: (value) => snapshotOAuthSync(schema, decode(value))
69
- };
70
- };
71
- const sameRevision = (left, right) => {
72
- if (left.subjectId !== right.subjectId || left.securityRevision !== right.securityRevision || left.credentials.length !== right.credentials.length) return false;
73
- const revisions = new Map(left.credentials.map((item) => [item.credentialId, item.revision]));
74
- return revisions.size === left.credentials.length && new Set(right.credentials.map((item) => item.credentialId)).size === right.credentials.length && right.credentials.every((item) => revisions.get(item.credentialId) === item.revision);
75
- };
76
- const satisfies = (proofs, requirement) => {
77
- const factors = new Set(proofs.flatMap((proof) => [...proof.factors]));
78
- const count = new Set(proofs.map((proof) => proof.credentialId)).size;
79
- return requirement.alternatives.some((alternative) => alternative.factors.every((factor) => factors.has(factor)) && count >= alternative.minimumCredentials && proofs.some((proof) => (!alternative.userVerified || proof.userVerified) && (!alternative.phishingResistant || proof.phishingResistant)));
80
- };
81
- const validAction = Effect.fnUntraced(function* (authorization, expected, currentRequirement, now, maximumAgeMillis) {
82
- const challenge = authorization.challenge;
83
- const evidence = authorization.evidence;
84
- const intentDigest = yield* digest(expected.intent);
85
- const binding = yield* digest(JSON.stringify([
86
- "effect-auth/oauth-action/v1",
87
- expected.moduleId,
88
- expected.action,
89
- expected.flowId,
90
- expected.commandId,
91
- intentDigest
92
- ]));
93
- if (challenge.moduleId !== expected.moduleId || challenge.action !== expected.action || challenge.flowId !== expected.flowId || challenge.commandId !== expected.commandId || challenge.intentDigest !== intentDigest || challenge.bindingDigest !== binding || evidence.flowId !== expected.flowId || evidence.bindingDigest !== binding || !sameRevision(challenge.revision, expected.revision) || !sameRevision(evidence.revision, expected.revision)) return false;
94
- const revisions = new Map(expected.revision.credentials.map((item) => [item.credentialId, item.revision]));
95
- if (evidence.proofs.some((proof) => !revisions.has(proof.credentialId) || DateTime.toEpochMillis(proof.verifiedAt) > now)) return false;
96
- return [authorization.requirement, currentRequirement].every((requirement) => {
97
- const fresh = evidence.proofs.filter((proof) => {
98
- const age = now - DateTime.toEpochMillis(proof.verifiedAt);
99
- return age >= 0 && age < Math.min(maximumAgeMillis, requirement.maximumAgeMillis);
100
- });
101
- return satisfies(fresh, requirement);
102
- });
103
- });
104
- //#endregion
105
- export { captureOAuthMapping, digest, invariant, nonce, oauthIdentityKey, sameIdentity, sameRevision, satisfies, storage, unavailable, validAction };
106
-
107
- //# sourceMappingURL=oauth-state.mjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"oauth-state.mjs","names":[],"sources":["../../src/drizzle/oauth-state.ts"],"sourcesContent":["import {\n type OAuthActionAuthorization,\n type OAuthAccountRevision,\n OAuthUnavailable,\n OAuthExternalIdentity,\n snapshotOAuthSync,\n} from \"@yielded/auth/OAuth\";\nimport type { AuthenticationRequirement } from \"@yielded/auth/Sessions\";\nimport { Crypto, DateTime, Effect, Schema } from \"effect\";\nimport { Base64Url } from \"effect/encoding\";\n\nimport { digest, randomId } from \"./crypto\";\nexport { digest } from \"./crypto\";\n\nconst encoder = new TextEncoder();\nconst decoder = new TextDecoder(\"utf-8\", { fatal: true });\n\nexport const unavailable = () => OAuthUnavailable.make({});\n\nexport const invariant: (value: unknown) => asserts value = (value) => {\n if (!value) throw unavailable();\n};\n\nexport const nonce = randomId;\n\n/** Capture configuration/callback references while preserving Drizzle table, SQL\n * and Effect objects. Never freeze or mutate the consumer's original graph. */\nexport const captureOAuthMapping = <A>(input: A): A => {\n const seen = new Map<object, unknown>();\n\n const copy = (value: unknown): unknown => {\n if (value === null || typeof value !== \"object\" || Effect.isEffect(value)) return value;\n if (!Array.isArray(value) && Object.getPrototypeOf(value) !== Object.prototype) return value;\n const prior = seen.get(value);\n\n if (prior !== undefined) return prior;\n if (Array.isArray(value)) {\n const result: unknown[] = [];\n\n seen.set(value, result);\n result.push(...value.map(copy));\n\n return Object.freeze(result);\n }\n const result: Record<string, unknown> = {};\n\n seen.set(value, result);\n for (const [key, child] of Object.entries(value)) result[key] = copy(child);\n\n return Object.freeze(result);\n };\n\n return copy(input) as A;\n};\n\n/** Versioned length-delimited UTF-8 tuple; the module is deliberately excluded.\n * Reject ill-formed UTF-16 rather than letting UTF-8 replacement alias identities. */\nexport const oauthIdentityKey = Effect.fnUntraced(function* (\n input: typeof OAuthExternalIdentity.Type,\n) {\n const identity = snapshotOAuthSync(OAuthExternalIdentity, input);\n\n const fields = [\n \"effect-auth/oauth-identity-key/v1\",\n identity.provider,\n identity.issuer,\n identity.subject,\n ];\n\n const bytes = fields.map((field) => {\n const value = encoder.encode(field);\n\n invariant(decoder.decode(value) === field);\n\n return value;\n });\n\n const packed = new Uint8Array(bytes.reduce((size, value) => size + 4 + value.length, 0));\n const view = new DataView(packed.buffer);\n let offset = 0;\n\n for (const value of bytes) {\n view.setUint32(offset, value.length, false);\n packed.set(value, offset + 4);\n offset += 4 + value.length;\n }\n\n const crypto = yield* Crypto.Crypto;\n\n return \"v1:\" + Base64Url.encode(yield* crypto.digest(\"SHA-256\", packed));\n});\n\nexport const sameIdentity = (\n left: typeof OAuthExternalIdentity.Type,\n right: typeof OAuthExternalIdentity.Type,\n) =>\n left.provider === right.provider &&\n left.issuer === right.issuer &&\n left.subject === right.subject;\n\n/** Private Type storage: opaque wrappers and DateTimes are freshly reconstructed. */\nexport const storage = <S extends Schema.Codec<unknown, unknown, never, never>>(schema: S) => {\n const codec = Schema.fromJsonString(Schema.toCodecJson(Schema.toType(schema)));\n const encode = Schema.encodeSync(codec);\n const decode = Schema.decodeSync(codec);\n\n return {\n encode: (value: S[\"Type\"]) => encode(snapshotOAuthSync(schema, value)),\n decode: (value: string) => snapshotOAuthSync(schema, decode(value)),\n };\n};\n\nexport const sameRevision = (left: OAuthAccountRevision, right: OAuthAccountRevision) => {\n if (\n left.subjectId !== right.subjectId ||\n left.securityRevision !== right.securityRevision ||\n left.credentials.length !== right.credentials.length\n )\n return false;\n const revisions = new Map(left.credentials.map((item) => [item.credentialId, item.revision]));\n\n return (\n revisions.size === left.credentials.length &&\n new Set(right.credentials.map((item) => item.credentialId)).size === right.credentials.length &&\n right.credentials.every((item) => revisions.get(item.credentialId) === item.revision)\n );\n};\n\nexport const satisfies = (\n proofs: ReadonlyArray<{\n readonly credentialId: string;\n readonly factors: ReadonlyArray<string>;\n readonly userVerified: boolean;\n readonly phishingResistant: boolean;\n }>,\n requirement: AuthenticationRequirement,\n) => {\n const factors = new Set(proofs.flatMap((proof) => [...proof.factors]));\n const count = new Set(proofs.map((proof) => proof.credentialId)).size;\n\n return requirement.alternatives.some(\n (alternative) =>\n alternative.factors.every((factor) => factors.has(factor)) &&\n count >= alternative.minimumCredentials &&\n proofs.some(\n (proof) =>\n (!alternative.userVerified || proof.userVerified) &&\n (!alternative.phishingResistant || proof.phishingResistant),\n ),\n );\n};\n\nexport const validAction = Effect.fnUntraced(function* (\n authorization: OAuthActionAuthorization,\n expected: {\n readonly moduleId: string;\n readonly action: OAuthActionAuthorization[\"challenge\"][\"action\"];\n readonly flowId: string;\n readonly commandId: string;\n readonly revision: OAuthAccountRevision;\n readonly intent: string;\n },\n currentRequirement: AuthenticationRequirement,\n now: number,\n maximumAgeMillis: number,\n) {\n const challenge = authorization.challenge;\n const evidence = authorization.evidence;\n const intentDigest = yield* digest(expected.intent);\n\n const binding = yield* digest(\n // oxlint-disable-next-line no-restricted-properties -- Fixed private action fingerprint format shared with the core verifier.\n JSON.stringify([\n \"effect-auth/oauth-action/v1\",\n expected.moduleId,\n expected.action,\n expected.flowId,\n expected.commandId,\n intentDigest,\n ]),\n );\n\n if (\n challenge.moduleId !== expected.moduleId ||\n challenge.action !== expected.action ||\n challenge.flowId !== expected.flowId ||\n challenge.commandId !== expected.commandId ||\n challenge.intentDigest !== intentDigest ||\n challenge.bindingDigest !== binding ||\n evidence.flowId !== expected.flowId ||\n evidence.bindingDigest !== binding ||\n !sameRevision(challenge.revision, expected.revision) ||\n !sameRevision(evidence.revision, expected.revision)\n )\n return false;\n\n const revisions = new Map(\n expected.revision.credentials.map((item) => [item.credentialId, item.revision]),\n );\n\n if (\n evidence.proofs.some(\n (proof) =>\n !revisions.has(proof.credentialId) || DateTime.toEpochMillis(proof.verifiedAt) > now,\n )\n )\n return false;\n\n return [authorization.requirement, currentRequirement].every((requirement) => {\n const fresh = evidence.proofs.filter((proof) => {\n const age = now - DateTime.toEpochMillis(proof.verifiedAt);\n\n return age >= 0 && age < Math.min(maximumAgeMillis, requirement.maximumAgeMillis);\n });\n\n return satisfies(fresh, requirement);\n });\n});\n"],"mappings":"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"}