@yielded/auth-persistence-drizzle 0.1.0-beta.0 → 0.1.0-beta.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +6 -1
- package/dist/D1.d.mts +155 -40
- package/dist/D1.mjs +10 -6
- package/dist/D1.mjs.map +1 -1
- package/dist/Libsql.d.mts +251 -129
- package/dist/Libsql.mjs +20 -21
- package/dist/Libsql.mjs.map +1 -1
- package/dist/Mysql2.d.mts +208 -56
- package/dist/Mysql2.mjs +13 -8
- package/dist/Mysql2.mjs.map +1 -1
- package/dist/Pglite.d.mts +209 -57
- package/dist/Pglite.mjs +13 -9
- package/dist/Pglite.mjs.map +1 -1
- package/dist/Postgres.d.mts +207 -55
- package/dist/Postgres.mjs +13 -9
- package/dist/Postgres.mjs.map +1 -1
- package/dist/SqliteBun.d.mts +249 -126
- package/dist/SqliteBun.mjs +20 -18
- package/dist/SqliteBun.mjs.map +1 -1
- package/dist/SqliteDo.d.mts +248 -158
- package/dist/SqliteDo.mjs +26 -44
- package/dist/SqliteDo.mjs.map +1 -1
- package/dist/SqliteNode.d.mts +247 -124
- package/dist/SqliteNode.mjs +20 -18
- package/dist/SqliteNode.mjs.map +1 -1
- package/dist/SqliteWasm.d.mts +251 -128
- package/dist/SqliteWasm.mjs +20 -18
- package/dist/SqliteWasm.mjs.map +1 -1
- package/dist/drizzle/D1BatchStatements.d.mts +1 -1
- package/dist/drizzle/D1BatchStatements.mjs.map +1 -1
- package/dist/drizzle/d1-database.d.mts +11 -0
- package/dist/drizzle/d1-database.mjs +8 -0
- package/dist/drizzle/d1-database.mjs.map +1 -0
- package/dist/drizzle/d1-emails.d.mts +8 -7
- package/dist/drizzle/d1-emails.mjs +7 -4
- package/dist/drizzle/d1-emails.mjs.map +1 -1
- package/dist/drizzle/d1-generated-statement.mjs.map +1 -1
- package/dist/drizzle/d1-identity.mjs +12 -9
- package/dist/drizzle/d1-identity.mjs.map +1 -1
- package/dist/drizzle/d1-oauth.d.mts +41 -10
- package/dist/drizzle/d1-oauth.mjs +8 -5
- package/dist/drizzle/d1-oauth.mjs.map +1 -1
- package/dist/drizzle/d1-passkey.d.mts +3 -14
- package/dist/drizzle/d1-passkey.mjs +2 -1
- package/dist/drizzle/d1-passkey.mjs.map +1 -1
- package/dist/drizzle/d1-password-prepared.d.mts +4 -3
- package/dist/drizzle/d1-password-prepared.mjs +3 -1
- package/dist/drizzle/d1-password-prepared.mjs.map +1 -1
- package/dist/drizzle/d1-passwords.d.mts +7 -6
- package/dist/drizzle/d1-passwords.mjs +5 -2
- package/dist/drizzle/d1-passwords.mjs.map +1 -1
- package/dist/drizzle/d1-phone.d.mts +3 -4
- package/dist/drizzle/d1-phone.mjs +2 -1
- package/dist/drizzle/d1-phone.mjs.map +1 -1
- package/dist/drizzle/d1-planning.d.mts +1 -1
- package/dist/drizzle/d1-proofs.d.mts +5 -4
- package/dist/drizzle/d1-proofs.mjs +3 -1
- package/dist/drizzle/d1-proofs.mjs.map +1 -1
- package/dist/drizzle/d1-sessions.d.mts +14 -13
- package/dist/drizzle/d1-sessions.mjs +15 -9
- package/dist/drizzle/d1-sessions.mjs.map +1 -1
- package/dist/drizzle/d1-totp.d.mts +3 -4
- package/dist/drizzle/d1-totp.mjs +2 -1
- package/dist/drizzle/d1-totp.mjs.map +1 -1
- package/dist/drizzle/email-registration.d.mts +1 -1
- package/dist/drizzle/email-registration.mjs +2 -1
- package/dist/drizzle/email-registration.mjs.map +1 -1
- package/dist/drizzle/email-target.d.mts +8 -7
- package/dist/drizzle/email-target.mjs +10 -10
- package/dist/drizzle/email-target.mjs.map +1 -1
- package/dist/drizzle/model.d.mts +2 -126
- package/dist/drizzle/model.mjs +2 -21
- package/dist/drizzle/model.mjs.map +1 -1
- package/dist/drizzle/mysql-database.d.mts +8 -0
- package/dist/drizzle/mysql-database.mjs +8 -0
- package/dist/drizzle/mysql-database.mjs.map +1 -0
- package/dist/drizzle/mysql-emails.d.mts +8 -7
- package/dist/drizzle/mysql-emails.mjs +12 -8
- package/dist/drizzle/mysql-emails.mjs.map +1 -1
- package/dist/drizzle/mysql-identity.mjs +12 -9
- package/dist/drizzle/mysql-identity.mjs.map +1 -1
- package/dist/drizzle/mysql-password-prepared.d.mts +4 -3
- package/dist/drizzle/mysql-password-prepared.mjs +6 -2
- package/dist/drizzle/mysql-password-prepared.mjs.map +1 -1
- package/dist/drizzle/mysql-passwords.d.mts +7 -5
- package/dist/drizzle/mysql-passwords.mjs +11 -7
- package/dist/drizzle/mysql-passwords.mjs.map +1 -1
- package/dist/drizzle/mysql-proofs.d.mts +4 -3
- package/dist/drizzle/mysql-proofs.mjs +8 -4
- package/dist/drizzle/mysql-proofs.mjs.map +1 -1
- package/dist/drizzle/mysql-sessions.d.mts +12 -11
- package/dist/drizzle/mysql-sessions.mjs +16 -12
- package/dist/drizzle/mysql-sessions.mjs.map +1 -1
- package/dist/drizzle/native-database.mjs +10 -0
- package/dist/drizzle/native-database.mjs.map +1 -0
- package/dist/drizzle/oauth-accounts.mjs +1 -1
- package/dist/drizzle/oauth-connected-access.mjs +14 -12
- package/dist/drizzle/oauth-connected-access.mjs.map +1 -1
- package/dist/drizzle/oauth-connected-custody.mjs +2 -2
- package/dist/drizzle/oauth-connected-drivers.mjs +11 -6
- package/dist/drizzle/oauth-connected-drivers.mjs.map +1 -1
- package/dist/drizzle/oauth-connected-flow.mjs +2 -2
- package/dist/drizzle/oauth-connected-input.mjs +14 -1
- package/dist/drizzle/oauth-connected-input.mjs.map +1 -1
- package/dist/drizzle/oauth-connected-maintenance.mjs +1 -1
- package/dist/drizzle/oauth-connected-management.mjs +2 -2
- package/dist/drizzle/oauth-connected-model.d.mts +17 -3
- package/dist/drizzle/oauth-connected-model.mjs.map +1 -1
- package/dist/drizzle/oauth-connected-settlement.mjs +51 -41
- package/dist/drizzle/oauth-connected-settlement.mjs.map +1 -1
- package/dist/drizzle/oauth-connected-sign-in.mjs +263 -0
- package/dist/drizzle/oauth-connected-sign-in.mjs.map +1 -0
- package/dist/drizzle/oauth-connected-state.d.mts +110 -2
- package/dist/drizzle/oauth-connected-state.mjs +9 -4
- package/dist/drizzle/oauth-connected-state.mjs.map +1 -1
- package/dist/drizzle/oauth-connected-target.d.mts +142 -15
- package/dist/drizzle/oauth-connected-target.mjs +9 -6
- package/dist/drizzle/oauth-connected-target.mjs.map +1 -1
- package/dist/drizzle/oauth-drivers.mjs +9 -7
- package/dist/drizzle/oauth-drivers.mjs.map +1 -1
- package/dist/drizzle/oauth-flow.d.mts +1 -1
- package/dist/drizzle/oauth-flow.mjs +1 -1
- package/dist/drizzle/oauth-input.mjs +1 -1
- package/dist/drizzle/oauth-model.d.mts +1 -1
- package/dist/drizzle/oauth-owner.d.mts +1 -1
- package/dist/drizzle/oauth-registration.d.mts +2 -2
- package/dist/drizzle/oauth-registration.mjs +1 -1
- package/dist/drizzle/oauth-state.mjs +5 -4
- package/dist/drizzle/oauth-state.mjs.map +1 -1
- package/dist/drizzle/oauth-target.d.mts +14 -13
- package/dist/drizzle/oauth-target.mjs +14 -13
- package/dist/drizzle/oauth-target.mjs.map +1 -1
- package/dist/drizzle/passkey-drivers.mjs +8 -6
- package/dist/drizzle/passkey-drivers.mjs.map +1 -1
- package/dist/drizzle/passkey-write-drivers.mjs +5 -3
- package/dist/drizzle/passkey-write-drivers.mjs.map +1 -1
- package/dist/drizzle/passkey-write-target.d.mts +1 -1
- package/dist/drizzle/password-prepared-sql.mjs +2 -1
- package/dist/drizzle/password-prepared-sql.mjs.map +1 -1
- package/dist/drizzle/password-prepared-state.mjs +1 -1
- package/dist/drizzle/password-prepared-target.d.mts +4 -3
- package/dist/drizzle/password-prepared-target.mjs +4 -3
- package/dist/drizzle/password-prepared-target.mjs.map +1 -1
- package/dist/drizzle/password-registration.mjs +2 -1
- package/dist/drizzle/password-registration.mjs.map +1 -1
- package/dist/drizzle/password-target.d.mts +6 -5
- package/dist/drizzle/password-target.mjs +8 -8
- package/dist/drizzle/password-target.mjs.map +1 -1
- package/dist/drizzle/pg-database.d.mts +9 -0
- package/dist/drizzle/pg-database.mjs +8 -0
- package/dist/drizzle/pg-database.mjs.map +1 -0
- package/dist/drizzle/pg-emails.d.mts +8 -7
- package/dist/drizzle/pg-emails.mjs +12 -8
- package/dist/drizzle/pg-emails.mjs.map +1 -1
- package/dist/drizzle/pg-identity.mjs +92 -0
- package/dist/drizzle/pg-identity.mjs.map +1 -0
- package/dist/drizzle/pg-password-prepared.d.mts +4 -3
- package/dist/drizzle/pg-password-prepared.mjs +6 -2
- package/dist/drizzle/pg-password-prepared.mjs.map +1 -1
- package/dist/drizzle/pg-passwords.d.mts +7 -5
- package/dist/drizzle/pg-passwords.mjs +11 -7
- package/dist/drizzle/pg-passwords.mjs.map +1 -1
- package/dist/drizzle/pg-proofs.d.mts +4 -3
- package/dist/drizzle/pg-proofs.mjs +8 -4
- package/dist/drizzle/pg-proofs.mjs.map +1 -1
- package/dist/drizzle/pg-sessions.d.mts +12 -11
- package/dist/drizzle/pg-sessions.mjs +16 -12
- package/dist/drizzle/pg-sessions.mjs.map +1 -1
- package/dist/drizzle/phone-model.d.mts +1 -1
- package/dist/drizzle/phone-target.d.mts +5 -4
- package/dist/drizzle/phone-target.mjs +12 -11
- package/dist/drizzle/phone-target.mjs.map +1 -1
- package/dist/drizzle/proof-target.d.mts +4 -3
- package/dist/drizzle/proof-target.mjs +5 -5
- package/dist/drizzle/proof-target.mjs.map +1 -1
- package/dist/drizzle/session-sql.d.mts +1 -0
- package/dist/drizzle/session-target.d.mts +11 -9
- package/dist/drizzle/session-target.mjs +11 -11
- package/dist/drizzle/session-target.mjs.map +1 -1
- package/dist/drizzle/sqlite-emails.mjs +9 -5
- package/dist/drizzle/sqlite-emails.mjs.map +1 -1
- package/dist/drizzle/sqlite-identity.mjs +14 -11
- package/dist/drizzle/sqlite-identity.mjs.map +1 -1
- package/dist/drizzle/sqlite-password-prepared.mjs +7 -3
- package/dist/drizzle/sqlite-password-prepared.mjs.map +1 -1
- package/dist/drizzle/sqlite-passwords.mjs +10 -6
- package/dist/drizzle/sqlite-passwords.mjs.map +1 -1
- package/dist/drizzle/sqlite-proofs.mjs +7 -3
- package/dist/drizzle/sqlite-proofs.mjs.map +1 -1
- package/dist/drizzle/sqlite-sessions.mjs +16 -12
- package/dist/drizzle/sqlite-sessions.mjs.map +1 -1
- package/dist/drizzle/standalone-guard.d.mts +2 -0
- package/dist/drizzle/standalone-guard.mjs +8 -4
- package/dist/drizzle/standalone-guard.mjs.map +1 -1
- package/dist/drizzle/totp-model.d.mts +1 -1
- package/dist/drizzle/totp-target.d.mts +5 -4
- package/dist/drizzle/totp-target.mjs +31 -28
- package/dist/drizzle/totp-target.mjs.map +1 -1
- package/dist/drizzle/transaction-mysql.mjs +1 -1
- package/dist/drizzle/transaction-mysql.mjs.map +1 -1
- package/dist/index.d.mts +2 -4
- package/dist/index.mjs +2 -4
- package/dist/internal/drizzle-postgres.mjs.map +1 -1
- package/dist/internal/drizzle-sqlite.mjs.map +1 -1
- package/package.json +1 -1
- package/src/D1.ts +37 -26
- package/src/Libsql.ts +45 -61
- package/src/Mysql2.ts +39 -35
- package/src/Pglite.ts +48 -30
- package/src/Postgres.ts +48 -30
- package/src/SqliteBun.ts +59 -68
- package/src/SqliteDo.ts +61 -274
- package/src/SqliteNode.ts +56 -66
- package/src/SqliteWasm.ts +56 -66
- package/src/drizzle/D1BatchStatements.ts +1 -1
- package/src/drizzle/d1-database.ts +10 -0
- package/src/drizzle/d1-emails.ts +86 -88
- package/src/drizzle/d1-generated-statement.ts +1 -1
- package/src/drizzle/d1-identity.ts +17 -20
- package/src/drizzle/d1-oauth.ts +19 -8
- package/src/drizzle/d1-passkey.ts +5 -1
- package/src/drizzle/d1-password-prepared.ts +40 -42
- package/src/drizzle/d1-passwords.ts +76 -80
- package/src/drizzle/d1-phone.ts +5 -1
- package/src/drizzle/d1-proofs.ts +31 -34
- package/src/drizzle/d1-sessions.ts +53 -40
- package/src/drizzle/d1-totp.ts +5 -1
- package/src/drizzle/email-registration.ts +6 -2
- package/src/drizzle/email-target.ts +18 -20
- package/src/drizzle/model.ts +1 -208
- package/src/drizzle/mysql-database.ts +8 -0
- package/src/drizzle/mysql-emails.ts +29 -17
- package/src/drizzle/mysql-identity.ts +18 -21
- package/src/drizzle/mysql-password-prepared.ts +11 -9
- package/src/drizzle/mysql-passwords.ts +22 -10
- package/src/drizzle/mysql-proofs.ts +17 -6
- package/src/drizzle/mysql-sessions.ts +41 -18
- package/src/drizzle/native-database.ts +22 -0
- package/src/drizzle/oauth-connected-access.ts +8 -1
- package/src/drizzle/oauth-connected-drivers.ts +21 -6
- package/src/drizzle/oauth-connected-input.ts +13 -0
- package/src/drizzle/oauth-connected-model.ts +17 -0
- package/src/drizzle/oauth-connected-settlement.ts +65 -42
- package/src/drizzle/oauth-connected-sign-in.ts +438 -0
- package/src/drizzle/oauth-connected-state.ts +19 -7
- package/src/drizzle/oauth-connected-target.ts +26 -18
- package/src/drizzle/oauth-drivers.ts +26 -10
- package/src/drizzle/oauth-state.ts +5 -4
- package/src/drizzle/oauth-target.ts +31 -43
- package/src/drizzle/passkey-drivers.ts +21 -13
- package/src/drizzle/passkey-write-drivers.ts +11 -6
- package/src/drizzle/password-prepared-sql.ts +2 -4
- package/src/drizzle/password-prepared-target.ts +10 -7
- package/src/drizzle/password-registration.ts +7 -8
- package/src/drizzle/password-target.ts +20 -19
- package/src/drizzle/pg-database.ts +10 -0
- package/src/drizzle/pg-emails.ts +29 -17
- package/src/drizzle/pg-identity.ts +297 -0
- package/src/drizzle/pg-password-prepared.ts +11 -9
- package/src/drizzle/pg-passwords.ts +22 -10
- package/src/drizzle/pg-proofs.ts +17 -6
- package/src/drizzle/pg-sessions.ts +41 -18
- package/src/drizzle/phone-target.ts +23 -18
- package/src/drizzle/proof-target.ts +10 -13
- package/src/drizzle/session-target.ts +33 -51
- package/src/drizzle/sqlite-emails.ts +31 -14
- package/src/drizzle/sqlite-identity.ts +22 -42
- package/src/drizzle/sqlite-password-prepared.ts +24 -10
- package/src/drizzle/sqlite-passwords.ts +30 -16
- package/src/drizzle/sqlite-proofs.ts +29 -6
- package/src/drizzle/sqlite-sessions.ts +50 -24
- package/src/drizzle/standalone-guard.ts +19 -7
- package/src/drizzle/totp-target.ts +62 -61
- package/src/drizzle/transaction-mysql.ts +1 -1
- package/src/index.ts +0 -24
- package/src/internal/drizzle-postgres.ts +1 -1
- package/src/internal/drizzle-sqlite.ts +1 -1
- package/dist/drizzle/d1-identity.d.mts +0 -30
- package/dist/drizzle/mysql-identity.d.mts +0 -21
- package/dist/drizzle/mysql.d.mts +0 -69
- package/dist/drizzle/mysql.mjs +0 -218
- package/dist/drizzle/mysql.mjs.map +0 -1
- package/dist/drizzle/pg.d.mts +0 -80
- package/dist/drizzle/pg.mjs +0 -289
- package/dist/drizzle/pg.mjs.map +0 -1
- package/dist/drizzle/sqlite.d.mts +0 -77
- package/dist/drizzle/sqlite.mjs +0 -217
- package/dist/drizzle/sqlite.mjs.map +0 -1
- package/src/drizzle/mysql.ts +0 -687
- package/src/drizzle/pg.ts +0 -984
- package/src/drizzle/sqlite.ts +0 -705
package/dist/drizzle/mysql.mjs
DELETED
|
@@ -1,218 +0,0 @@
|
|
|
1
|
-
import { column, requireStandaloneConsume, updateValues } from "./model.mjs";
|
|
2
|
-
import { AuthStore, EmailOtpRejected } from "@yielded/auth/AuthStore";
|
|
3
|
-
import { AuthRateLimited, AuthStoreError, InvalidRegistration } from "@yielded/auth/Errors";
|
|
4
|
-
import { InvalidOAuthState, OAuthStateDecisions, OAuthStateStore } from "@yielded/auth/OAuth";
|
|
5
|
-
import { VerifiedEmail, timingSafeStringEqual } from "@yielded/auth/Schema";
|
|
6
|
-
import { and, eq, gt, sql } from "drizzle-orm";
|
|
7
|
-
import { Cause, Context, DateTime, Duration, Effect, Schema } from "effect";
|
|
8
|
-
import { AuthStoreDecisions, reportPersistenceFailure } from "@yielded/auth/Persistence";
|
|
9
|
-
//#region src/drizzle/mysql.ts
|
|
10
|
-
const selected = (row) => row;
|
|
11
|
-
const readError = () => AuthStoreError.make({ message: "Auth store read failed" });
|
|
12
|
-
const writeError = () => AuthStoreError.make({ message: "Auth store write failed" });
|
|
13
|
-
const isStoreFailure = Schema.is(AuthStoreError);
|
|
14
|
-
const mapStoreFailure = (failure) => (effect) => reportPersistenceFailure(effect, isStoreFailure).pipe(Effect.catchCause((cause) => Effect.failCause(Cause.map(cause, failure))));
|
|
15
|
-
const mapStoreReadFailure = mapStoreFailure(readError);
|
|
16
|
-
const mapStoreWriteFailure = mapStoreFailure(writeError);
|
|
17
|
-
/** MySQL/InnoDB implementation. Multi-step decisions stay values until commit. */
|
|
18
|
-
const makeMysqlAuthStoreServices = (database, mapping) => {
|
|
19
|
-
const db = database;
|
|
20
|
-
const challengeTable = mapping.challenge.table;
|
|
21
|
-
const ck = mapping.challenge.columns;
|
|
22
|
-
const c = Object.fromEntries(Object.entries(ck).map(([name, key]) => [name, column(challengeTable, key)]));
|
|
23
|
-
const registrationTable = mapping.registration.table;
|
|
24
|
-
const rk = mapping.registration.columns;
|
|
25
|
-
const r = Object.fromEntries(Object.entries(rk).map(([name, key]) => [name, column(registrationTable, key)]));
|
|
26
|
-
const issueChallenge = Effect.fn("DrizzleMysqlAuthStore.issueChallenge")(function* (input) {
|
|
27
|
-
const result = yield* Effect.suspend(() => db.transaction((tx) => Effect.gen(function* () {
|
|
28
|
-
yield* tx.insert(challengeTable).values(mapping.challenge.encodeInsert(input, {
|
|
29
|
-
namespace: mapping.challenge.identifierNamespace,
|
|
30
|
-
failedAttempts: 0,
|
|
31
|
-
consumed: false
|
|
32
|
-
})).onDuplicateKeyUpdate({ set: updateValues([[ck.challengeId, c.challengeId]]) });
|
|
33
|
-
const rows = yield* tx.select().from(challengeTable).where(and(eq(c.namespace, mapping.challenge.identifierNamespace), eq(c.value, input.email), eq(c.purpose, input.purpose))).for("update").limit(1);
|
|
34
|
-
if (rows[0] === void 0) return yield* AuthStoreError.make({ message: "Challenge digest conflict" });
|
|
35
|
-
const existing = yield* mapping.challenge.decode(selected(rows[0]));
|
|
36
|
-
const now = yield* DateTime.now;
|
|
37
|
-
const exactReplay = existing.challenge.challengeId === input.challengeId && timingSafeStringEqual(existing.challenge.tokenDigest, input.tokenDigest) && existing.challenge.email === input.email && existing.challenge.purpose === input.purpose && existing.challenge.otpKeyId === input.otpKeyId && timingSafeStringEqual(existing.challenge.otpDigest, input.otpDigest) && DateTime.toEpochMillis(existing.challenge.issuedAt) === DateTime.toEpochMillis(input.issuedAt) && DateTime.toEpochMillis(existing.challenge.expiresAt) === DateTime.toEpochMillis(input.expiresAt) && existing.challenge.attemptLimit === input.attemptLimit && Duration.toMillis(existing.challenge.resendCooldown) === Duration.toMillis(input.resendCooldown);
|
|
38
|
-
if (exactReplay && !existing.consumed && DateTime.toEpochMillis(existing.challenge.expiresAt) > DateTime.toEpochMillis(now)) return { _tag: "issued" };
|
|
39
|
-
if (exactReplay) return {
|
|
40
|
-
_tag: "limited",
|
|
41
|
-
retryAfterSeconds: 1
|
|
42
|
-
};
|
|
43
|
-
if (existing.challenge.challengeId === input.challengeId || DateTime.toEpochMillis(input.issuedAt) <= DateTime.toEpochMillis(existing.challenge.issuedAt)) return {
|
|
44
|
-
_tag: "limited",
|
|
45
|
-
retryAfterSeconds: 1
|
|
46
|
-
};
|
|
47
|
-
const eligibleAt = DateTime.toEpochMillis(existing.challenge.issuedAt) + Duration.toMillis(input.resendCooldown);
|
|
48
|
-
if (!existing.consumed && DateTime.toEpochMillis(now) < eligibleAt) return {
|
|
49
|
-
_tag: "limited",
|
|
50
|
-
retryAfterSeconds: Math.max(1, Math.ceil((eligibleAt - DateTime.toEpochMillis(now)) / 1e3))
|
|
51
|
-
};
|
|
52
|
-
const failedAttempts = DateTime.toEpochMillis(existing.challenge.expiresAt) > DateTime.toEpochMillis(now) ? existing.failedAttempts : 0;
|
|
53
|
-
yield* tx.update(challengeTable).set(mapping.challenge.encodeUpdate(input, {
|
|
54
|
-
namespace: mapping.challenge.identifierNamespace,
|
|
55
|
-
failedAttempts,
|
|
56
|
-
consumed: false
|
|
57
|
-
})).where(and(eq(c.namespace, mapping.challenge.identifierNamespace), eq(c.value, input.email), eq(c.purpose, input.purpose)));
|
|
58
|
-
return { _tag: "issued" };
|
|
59
|
-
}))).pipe(mapStoreWriteFailure);
|
|
60
|
-
if (result._tag === "limited") return yield* AuthRateLimited.make({ retryAfterSeconds: result.retryAfterSeconds });
|
|
61
|
-
});
|
|
62
|
-
const consumeChallengeDecision = Effect.fn("DrizzleMysqlAuthStore.consumeChallengeDecision")(function* (input) {
|
|
63
|
-
return yield* Effect.suspend(() => db.transaction((tx) => Effect.gen(function* () {
|
|
64
|
-
const rows = yield* tx.select().from(challengeTable).where(eq(c.tokenDigest, input.tokenDigest)).for("update").limit(1);
|
|
65
|
-
if (rows[0] === void 0) return {
|
|
66
|
-
_tag: "rejected",
|
|
67
|
-
reason: "missing_challenge"
|
|
68
|
-
};
|
|
69
|
-
const row = yield* mapping.challenge.decode(selected(rows[0]));
|
|
70
|
-
const now = yield* DateTime.now;
|
|
71
|
-
if (row.consumed) return {
|
|
72
|
-
_tag: "rejected",
|
|
73
|
-
reason: "consumed_challenge"
|
|
74
|
-
};
|
|
75
|
-
if (DateTime.toEpochMillis(row.challenge.expiresAt) <= DateTime.toEpochMillis(now)) return {
|
|
76
|
-
_tag: "rejected",
|
|
77
|
-
reason: "expired_challenge"
|
|
78
|
-
};
|
|
79
|
-
if (row.failedAttempts >= row.challenge.attemptLimit) return {
|
|
80
|
-
_tag: "rejected",
|
|
81
|
-
reason: "attempts_exhausted"
|
|
82
|
-
};
|
|
83
|
-
const candidate = input.otpDigests[row.challenge.otpKeyId];
|
|
84
|
-
const matches = candidate !== void 0 && timingSafeStringEqual(candidate, row.challenge.otpDigest);
|
|
85
|
-
yield* tx.update(challengeTable).set(updateValues(matches ? [[ck.consumed, true]] : [[ck.failedAttempts, sql`${c.failedAttempts} + 1`]])).where(eq(c.tokenDigest, input.tokenDigest));
|
|
86
|
-
return matches ? {
|
|
87
|
-
_tag: "accepted",
|
|
88
|
-
value: VerifiedEmail.make({
|
|
89
|
-
email: row.challenge.email,
|
|
90
|
-
purpose: row.challenge.purpose
|
|
91
|
-
})
|
|
92
|
-
} : {
|
|
93
|
-
_tag: "rejected",
|
|
94
|
-
reason: "bad_code"
|
|
95
|
-
};
|
|
96
|
-
}))).pipe(mapStoreWriteFailure);
|
|
97
|
-
});
|
|
98
|
-
const consumeChallenge = Effect.fn("DrizzleMysqlAuthStore.consumeChallenge")(function* (input) {
|
|
99
|
-
yield* requireStandaloneConsume(db);
|
|
100
|
-
const decision = yield* consumeChallengeDecision(input);
|
|
101
|
-
return decision._tag === "accepted" ? decision.value : yield* EmailOtpRejected.make({ reason: decision.reason });
|
|
102
|
-
});
|
|
103
|
-
const issueRegistration = Effect.fn("DrizzleMysqlAuthStore.issueRegistration")(function* (input) {
|
|
104
|
-
yield* Effect.suspend(() => db.insert(registrationTable).values(mapping.registration.encodeInsert(input, false))).pipe(mapStoreWriteFailure);
|
|
105
|
-
});
|
|
106
|
-
const inspectRegistration = Effect.fn("DrizzleMysqlAuthStore.inspectRegistration")(function* (digest) {
|
|
107
|
-
const now = yield* DateTime.now;
|
|
108
|
-
const rows = yield* Effect.suspend(() => db.select().from(registrationTable).where(and(eq(r.tokenDigest, digest), eq(r.consumed, false), gt(r.expiresAt, mapping.registration.encodeInstant(now)))).limit(1)).pipe(mapStoreReadFailure);
|
|
109
|
-
if (rows[0] === void 0) return yield* InvalidRegistration.make();
|
|
110
|
-
return (yield* Effect.suspend(() => mapping.registration.decode(selected(rows[0]))).pipe(mapStoreReadFailure)).registration;
|
|
111
|
-
});
|
|
112
|
-
const consumeRegistrationDecision = Effect.fn("DrizzleMysqlAuthStore.consumeRegistrationDecision")(function* (input) {
|
|
113
|
-
return yield* Effect.suspend(() => db.transaction((tx) => Effect.gen(function* () {
|
|
114
|
-
const rows = yield* tx.select().from(registrationTable).where(eq(r.tokenDigest, input.tokenDigest)).for("update").limit(1);
|
|
115
|
-
if (rows[0] === void 0) return { _tag: "rejected" };
|
|
116
|
-
const row = yield* mapping.registration.decode(selected(rows[0]));
|
|
117
|
-
const now = yield* DateTime.now;
|
|
118
|
-
if (row.consumed || DateTime.toEpochMillis(row.registration.expiresAt) <= DateTime.toEpochMillis(now)) return { _tag: "rejected" };
|
|
119
|
-
yield* tx.update(registrationTable).set(updateValues([[rk.consumed, true]])).where(eq(r.tokenDigest, input.tokenDigest));
|
|
120
|
-
return {
|
|
121
|
-
_tag: "accepted",
|
|
122
|
-
value: void 0
|
|
123
|
-
};
|
|
124
|
-
}))).pipe(mapStoreWriteFailure);
|
|
125
|
-
});
|
|
126
|
-
const consumeRegistration = Effect.fn("DrizzleMysqlAuthStore.consumeRegistration")(function* (input) {
|
|
127
|
-
yield* requireStandaloneConsume(db);
|
|
128
|
-
if ((yield* consumeRegistrationDecision(input))._tag === "rejected") return yield* InvalidRegistration.make();
|
|
129
|
-
});
|
|
130
|
-
return {
|
|
131
|
-
authStore: AuthStore.of({
|
|
132
|
-
issueChallenge,
|
|
133
|
-
consumeChallenge,
|
|
134
|
-
issueRegistration,
|
|
135
|
-
inspectRegistration,
|
|
136
|
-
consumeRegistration
|
|
137
|
-
}),
|
|
138
|
-
decisions: {
|
|
139
|
-
consumeChallenge: consumeChallengeDecision,
|
|
140
|
-
consumeRegistration: consumeRegistrationDecision
|
|
141
|
-
}
|
|
142
|
-
};
|
|
143
|
-
};
|
|
144
|
-
const makeMysqlOAuthStateServices = (database, mapping) => {
|
|
145
|
-
const db = database;
|
|
146
|
-
const stateTable = mapping.oauthState.table;
|
|
147
|
-
const sk = mapping.oauthState.columns;
|
|
148
|
-
const s = Object.fromEntries(Object.entries(sk).map(([name, key]) => [name, column(stateTable, key)]));
|
|
149
|
-
const issue = Effect.fn("DrizzleMysqlOAuthStateStore.issue")(function* (input) {
|
|
150
|
-
yield* Effect.suspend(() => db.insert(stateTable).values(mapping.oauthState.encodeInsert(input, false))).pipe(mapStoreWriteFailure);
|
|
151
|
-
});
|
|
152
|
-
const consumeDecision = Effect.fn("DrizzleMysqlOAuthStateStore.consumeDecision")(function* (digest) {
|
|
153
|
-
return yield* Effect.suspend(() => db.transaction((tx) => Effect.gen(function* () {
|
|
154
|
-
const rows = yield* tx.select().from(stateTable).where(eq(s.stateDigest, digest)).for("update").limit(1);
|
|
155
|
-
if (rows[0] === void 0) return { _tag: "rejected" };
|
|
156
|
-
const row = yield* mapping.oauthState.decode(selected(rows[0]));
|
|
157
|
-
const now = yield* DateTime.now;
|
|
158
|
-
if (row.consumed || DateTime.toEpochMillis(row.state.expiresAt) <= DateTime.toEpochMillis(now)) return { _tag: "rejected" };
|
|
159
|
-
yield* tx.update(stateTable).set(updateValues([[sk.consumed, true]])).where(eq(s.stateDigest, digest));
|
|
160
|
-
return {
|
|
161
|
-
_tag: "accepted",
|
|
162
|
-
value: row.state
|
|
163
|
-
};
|
|
164
|
-
}))).pipe(mapStoreWriteFailure);
|
|
165
|
-
});
|
|
166
|
-
const consume = Effect.fn("DrizzleMysqlOAuthStateStore.consume")(function* (digest) {
|
|
167
|
-
yield* requireStandaloneConsume(db);
|
|
168
|
-
const decision = yield* consumeDecision(digest);
|
|
169
|
-
return decision._tag === "accepted" ? decision.value : yield* InvalidOAuthState.make();
|
|
170
|
-
});
|
|
171
|
-
return {
|
|
172
|
-
oauthStateStore: OAuthStateStore.of({
|
|
173
|
-
issue,
|
|
174
|
-
consume
|
|
175
|
-
}),
|
|
176
|
-
decisions: { consumeOAuthState: consumeDecision }
|
|
177
|
-
};
|
|
178
|
-
};
|
|
179
|
-
const makeMysqlAuthServices = (database, mapping) => {
|
|
180
|
-
const auth = makeMysqlAuthStoreServices(database, mapping);
|
|
181
|
-
const oauth = makeMysqlOAuthStateServices(database, mapping);
|
|
182
|
-
return {
|
|
183
|
-
...auth,
|
|
184
|
-
...oauth,
|
|
185
|
-
decisions: {
|
|
186
|
-
...auth.decisions,
|
|
187
|
-
...oauth.decisions
|
|
188
|
-
}
|
|
189
|
-
};
|
|
190
|
-
};
|
|
191
|
-
function coordinateMysqlAuthStoreTransaction(acquire, options, body) {
|
|
192
|
-
return Effect.flatMap(acquire, (database) => database.transaction((transaction) => {
|
|
193
|
-
const decisions = makeMysqlAuthStoreServices(transaction, options.mapping).decisions;
|
|
194
|
-
const provided = Context.make(AuthStoreDecisions, decisions);
|
|
195
|
-
const work = Effect.provideContext(body, provided);
|
|
196
|
-
return options.transaction === void 0 ? work : Effect.provideService(work, options.transaction, options.transaction.of(transaction));
|
|
197
|
-
}));
|
|
198
|
-
}
|
|
199
|
-
function coordinateMysqlOAuthStateTransaction(acquire, options, body) {
|
|
200
|
-
return Effect.flatMap(acquire, (database) => database.transaction((transaction) => {
|
|
201
|
-
const decisions = makeMysqlOAuthStateServices(transaction, options.mapping).decisions;
|
|
202
|
-
const provided = Context.make(OAuthStateDecisions, decisions);
|
|
203
|
-
const work = Effect.provideContext(body, provided);
|
|
204
|
-
return options.transaction === void 0 ? work : Effect.provideService(work, options.transaction, options.transaction.of(transaction));
|
|
205
|
-
}));
|
|
206
|
-
}
|
|
207
|
-
function coordinateMysqlAuthTransaction(acquire, options, body) {
|
|
208
|
-
return Effect.flatMap(acquire, (database) => database.transaction((transaction) => {
|
|
209
|
-
const decisions = makeMysqlAuthServices(transaction, options.mapping).decisions;
|
|
210
|
-
const provided = Context.make(AuthStoreDecisions, decisions).pipe(Context.add(OAuthStateDecisions, decisions));
|
|
211
|
-
const work = Effect.provideContext(body, provided);
|
|
212
|
-
return options.transaction === void 0 ? work : Effect.provideService(work, options.transaction, options.transaction.of(transaction));
|
|
213
|
-
}));
|
|
214
|
-
}
|
|
215
|
-
//#endregion
|
|
216
|
-
export { coordinateMysqlAuthStoreTransaction, coordinateMysqlAuthTransaction, coordinateMysqlOAuthStateTransaction, makeMysqlAuthServices, makeMysqlAuthStoreServices, makeMysqlOAuthStateServices };
|
|
217
|
-
|
|
218
|
-
//# sourceMappingURL=mysql.mjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"mysql.mjs","names":[],"sources":["../../src/drizzle/mysql.ts"],"sourcesContent":["import { AuthStore, EmailOtpRejected } from \"@yielded/auth/AuthStore\";\nimport { AuthRateLimited, AuthStoreError, InvalidRegistration } from \"@yielded/auth/Errors\";\nimport {\n InvalidOAuthState,\n OAuthStateDecisions,\n OAuthStateStore,\n type OAuthState,\n} from \"@yielded/auth/OAuth\";\nimport { AuthStoreDecisions, reportPersistenceFailure } from \"@yielded/auth/Persistence\";\nimport {\n timingSafeStringEqual,\n VerifiedEmail,\n type ConsumeChallenge,\n type ConsumeRegistration,\n type NewChallenge,\n type NewRegistration,\n type TokenDigest,\n} from \"@yielded/auth/Schema\";\n/* oxlint-disable no-explicit-any -- Drizzle's generic query builders lose the concrete consumer table through a runtime column map. Assertions stay in this adapter. */\nimport { and, eq, gt, sql, type AnyRelations, type InferSelectModel } from \"drizzle-orm\";\nimport type { EffectMysql2Database } from \"drizzle-orm/effect-mysql2\";\nimport type { AnyMySqlTable, MySqlColumn } from \"drizzle-orm/mysql-core\";\nimport { Cause, Context, DateTime, Duration, Effect, Schema } from \"effect\";\nimport type { SqlError } from \"effect/unstable/sql/SqlError\";\n\nimport {\n column,\n requireStandaloneConsume,\n updateValues,\n type AuthTables,\n type AuthStoreTables,\n type ChallengeConsumeDecision,\n type ConsumeDecision,\n type OAuthStateTables,\n} from \"./model\";\nimport type { SuppliedService } from \"./SuppliedService\";\n\ntype Database = EffectMysql2Database<AnyRelations>;\ntype RuntimeDatabase = EffectMysql2Database<any> & Parameters<typeof requireStandaloneConsume>[0];\ntype TransactionOf<D extends Database> = Parameters<Parameters<D[\"transaction\"]>[0]>[0];\n\nconst selected = <T extends AnyMySqlTable>(row: unknown): InferSelectModel<T> =>\n row as InferSelectModel<T>;\n\nconst readError = () => AuthStoreError.make({ message: \"Auth store read failed\" });\nconst writeError = () => AuthStoreError.make({ message: \"Auth store write failed\" });\nconst isStoreFailure = Schema.is(AuthStoreError);\n\nconst mapStoreFailure =\n (failure: () => AuthStoreError) =>\n <A, E, R>(effect: Effect.Effect<A, E, R>): Effect.Effect<A, AuthStoreError, R> =>\n reportPersistenceFailure(effect, isStoreFailure).pipe(\n Effect.catchCause((cause) => Effect.failCause(Cause.map(cause, failure))),\n );\n\nconst mapStoreReadFailure = mapStoreFailure(readError);\nconst mapStoreWriteFailure = mapStoreFailure(writeError);\n\n/** MySQL/InnoDB implementation. Multi-step decisions stay values until commit. */\nexport const makeMysqlAuthStoreServices = <C extends AnyMySqlTable, R extends AnyMySqlTable>(\n database: Database,\n mapping: AuthStoreTables<C, R>,\n) => {\n const db = database as RuntimeDatabase;\n const challengeTable = mapping.challenge.table;\n const ck = mapping.challenge.columns;\n\n const c = Object.fromEntries(\n Object.entries(ck).map(([name, key]) => [name, column(challengeTable, key)]),\n ) as Record<keyof typeof ck, MySqlColumn>;\n\n const registrationTable = mapping.registration.table;\n const rk = mapping.registration.columns;\n\n const r = Object.fromEntries(\n Object.entries(rk).map(([name, key]) => [name, column(registrationTable, key)]),\n ) as Record<keyof typeof rk, MySqlColumn>;\n\n const issueChallenge = Effect.fn(\"DrizzleMysqlAuthStore.issueChallenge\")(function* (\n input: NewChallenge,\n ) {\n const result = yield* Effect.suspend(() =>\n db.transaction((tx) =>\n Effect.gen(function* () {\n // A locking read of a missing InnoDB key takes a gap lock. Concurrent\n // first issuances would then deadlock when each transaction inserts.\n // The no-op upsert serializes on the declared series/digest unique\n // indexes before the row is read and evaluated below.\n yield* tx\n .insert(challengeTable as any)\n .values(\n mapping.challenge.encodeInsert(input, {\n namespace: mapping.challenge.identifierNamespace,\n failedAttempts: 0,\n consumed: false,\n }) as any,\n )\n .onDuplicateKeyUpdate({\n set: updateValues<C>([[ck.challengeId, c.challengeId]]) as any,\n });\n\n const rows = yield* tx\n .select()\n .from(challengeTable as any)\n .where(\n and(\n eq(c.namespace, mapping.challenge.identifierNamespace),\n eq(c.value, input.email),\n eq(c.purpose, input.purpose),\n ),\n )\n .for(\"update\")\n .limit(1);\n\n // A digest collision against another series is not a replay and must\n // never overwrite that row.\n if (rows[0] === undefined)\n return yield* AuthStoreError.make({ message: \"Challenge digest conflict\" });\n const existing = yield* mapping.challenge.decode(selected<C>(rows[0]));\n const now = yield* DateTime.now;\n\n const exactReplay =\n existing.challenge.challengeId === input.challengeId &&\n timingSafeStringEqual(existing.challenge.tokenDigest, input.tokenDigest) &&\n existing.challenge.email === input.email &&\n existing.challenge.purpose === input.purpose &&\n existing.challenge.otpKeyId === input.otpKeyId &&\n timingSafeStringEqual(existing.challenge.otpDigest, input.otpDigest) &&\n DateTime.toEpochMillis(existing.challenge.issuedAt) ===\n DateTime.toEpochMillis(input.issuedAt) &&\n DateTime.toEpochMillis(existing.challenge.expiresAt) ===\n DateTime.toEpochMillis(input.expiresAt) &&\n existing.challenge.attemptLimit === input.attemptLimit &&\n Duration.toMillis(existing.challenge.resendCooldown) ===\n Duration.toMillis(input.resendCooldown);\n\n // Retrying an identical still-live request is idempotent. In\n // particular, it does not reset the persisted wrong-attempt budget.\n if (\n exactReplay &&\n !existing.consumed &&\n DateTime.toEpochMillis(existing.challenge.expiresAt) > DateTime.toEpochMillis(now)\n )\n return { _tag: \"issued\" } as const;\n if (exactReplay) return { _tag: \"limited\", retryAfterSeconds: 1 } as const;\n if (\n existing.challenge.challengeId === input.challengeId ||\n DateTime.toEpochMillis(input.issuedAt) <=\n DateTime.toEpochMillis(existing.challenge.issuedAt)\n )\n return { _tag: \"limited\", retryAfterSeconds: 1 } as const;\n\n const eligibleAt =\n DateTime.toEpochMillis(existing.challenge.issuedAt) +\n Duration.toMillis(input.resendCooldown);\n\n if (!existing.consumed && DateTime.toEpochMillis(now) < eligibleAt) {\n return {\n _tag: \"limited\",\n retryAfterSeconds: Math.max(\n 1,\n Math.ceil((eligibleAt - DateTime.toEpochMillis(now)) / 1000),\n ),\n } as const;\n }\n\n const failedAttempts =\n DateTime.toEpochMillis(existing.challenge.expiresAt) > DateTime.toEpochMillis(now)\n ? existing.failedAttempts\n : 0;\n\n yield* tx\n .update(challengeTable as any)\n .set(\n mapping.challenge.encodeUpdate(input, {\n namespace: mapping.challenge.identifierNamespace,\n failedAttempts,\n consumed: false,\n }) as any,\n )\n .where(\n and(\n eq(c.namespace, mapping.challenge.identifierNamespace),\n eq(c.value, input.email),\n eq(c.purpose, input.purpose),\n ),\n );\n\n return { _tag: \"issued\" } as const;\n }),\n ),\n ).pipe(mapStoreWriteFailure);\n\n if (result._tag === \"limited\")\n return yield* AuthRateLimited.make({ retryAfterSeconds: result.retryAfterSeconds });\n });\n\n const consumeChallengeDecision = Effect.fn(\"DrizzleMysqlAuthStore.consumeChallengeDecision\")(\n function* (\n input: ConsumeChallenge,\n ): Effect.fn.Return<ChallengeConsumeDecision, AuthStoreError> {\n return yield* Effect.suspend(() =>\n db.transaction((tx) =>\n Effect.gen(function* () {\n const rows = yield* tx\n .select()\n .from(challengeTable as any)\n .where(eq(c.tokenDigest, input.tokenDigest))\n .for(\"update\")\n .limit(1);\n\n if (rows[0] === undefined)\n return { _tag: \"rejected\", reason: \"missing_challenge\" } as const;\n const row = yield* mapping.challenge.decode(selected<C>(rows[0]));\n const now = yield* DateTime.now;\n\n if (row.consumed) return { _tag: \"rejected\", reason: \"consumed_challenge\" } as const;\n if (DateTime.toEpochMillis(row.challenge.expiresAt) <= DateTime.toEpochMillis(now))\n return { _tag: \"rejected\", reason: \"expired_challenge\" } as const;\n if (row.failedAttempts >= row.challenge.attemptLimit)\n return { _tag: \"rejected\", reason: \"attempts_exhausted\" } as const;\n const candidate = input.otpDigests[row.challenge.otpKeyId];\n\n const matches =\n candidate !== undefined && timingSafeStringEqual(candidate, row.challenge.otpDigest);\n\n yield* tx\n .update(challengeTable as any)\n .set(\n updateValues<C>(\n matches\n ? [[ck.consumed, true]]\n : [[ck.failedAttempts, sql`${c.failedAttempts} + 1`]],\n ) as any,\n )\n .where(eq(c.tokenDigest, input.tokenDigest));\n\n return matches\n ? ({\n _tag: \"accepted\",\n value: VerifiedEmail.make({\n email: row.challenge.email,\n purpose: row.challenge.purpose,\n }),\n } as const)\n : ({ _tag: \"rejected\", reason: \"bad_code\" } as const);\n }),\n ),\n ).pipe(mapStoreWriteFailure);\n },\n );\n\n const consumeChallenge = Effect.fn(\"DrizzleMysqlAuthStore.consumeChallenge\")(function* (\n input: ConsumeChallenge,\n ) {\n yield* requireStandaloneConsume(db);\n const decision = yield* consumeChallengeDecision(input);\n\n return decision._tag === \"accepted\"\n ? decision.value\n : yield* EmailOtpRejected.make({ reason: decision.reason });\n });\n\n const issueRegistration = Effect.fn(\"DrizzleMysqlAuthStore.issueRegistration\")(function* (\n input: NewRegistration,\n ) {\n yield* Effect.suspend(() =>\n db\n .insert(registrationTable as any)\n .values(mapping.registration.encodeInsert(input, false) as any),\n ).pipe(mapStoreWriteFailure);\n });\n\n const inspectRegistration = Effect.fn(\"DrizzleMysqlAuthStore.inspectRegistration\")(function* (\n digest: TokenDigest,\n ) {\n const now = yield* DateTime.now;\n\n const rows = yield* Effect.suspend(() =>\n db\n .select()\n .from(registrationTable as any)\n .where(\n and(\n eq(r.tokenDigest, digest),\n eq(r.consumed, false),\n gt(r.expiresAt, mapping.registration.encodeInstant(now)),\n ),\n )\n .limit(1),\n ).pipe(mapStoreReadFailure);\n\n if (rows[0] === undefined) return yield* InvalidRegistration.make();\n\n return (yield* Effect.suspend(() => mapping.registration.decode(selected<R>(rows[0]))).pipe(\n mapStoreReadFailure,\n )).registration;\n });\n\n const consumeRegistrationDecision = Effect.fn(\n \"DrizzleMysqlAuthStore.consumeRegistrationDecision\",\n )(function* (\n input: ConsumeRegistration,\n ): Effect.fn.Return<ConsumeDecision<void>, AuthStoreError> {\n return yield* Effect.suspend(() =>\n db.transaction((tx) =>\n Effect.gen(function* () {\n const rows = yield* tx\n .select()\n .from(registrationTable as any)\n .where(eq(r.tokenDigest, input.tokenDigest))\n .for(\"update\")\n .limit(1);\n\n if (rows[0] === undefined) return { _tag: \"rejected\" } as const;\n const row = yield* mapping.registration.decode(selected<R>(rows[0]));\n const now = yield* DateTime.now;\n\n if (\n row.consumed ||\n DateTime.toEpochMillis(row.registration.expiresAt) <= DateTime.toEpochMillis(now)\n )\n return { _tag: \"rejected\" } as const;\n yield* tx\n .update(registrationTable as any)\n .set(updateValues<R>([[rk.consumed, true]]) as any)\n .where(eq(r.tokenDigest, input.tokenDigest));\n\n return { _tag: \"accepted\", value: undefined } as const;\n }),\n ),\n ).pipe(mapStoreWriteFailure);\n });\n\n const consumeRegistration = Effect.fn(\"DrizzleMysqlAuthStore.consumeRegistration\")(function* (\n input: ConsumeRegistration,\n ) {\n yield* requireStandaloneConsume(db);\n const decision = yield* consumeRegistrationDecision(input);\n\n if (decision._tag === \"rejected\") return yield* InvalidRegistration.make();\n });\n\n return {\n authStore: AuthStore.of({\n issueChallenge,\n consumeChallenge,\n issueRegistration,\n inspectRegistration,\n consumeRegistration,\n }),\n decisions: {\n consumeChallenge: consumeChallengeDecision,\n consumeRegistration: consumeRegistrationDecision,\n },\n } as const;\n};\n\nexport const makeMysqlOAuthStateServices = <S extends AnyMySqlTable>(\n database: Database,\n mapping: OAuthStateTables<S>,\n) => {\n const db = database as RuntimeDatabase;\n const stateTable = mapping.oauthState.table;\n const sk = mapping.oauthState.columns;\n\n const s = Object.fromEntries(\n Object.entries(sk).map(([name, key]) => [name, column(stateTable, key)]),\n ) as Record<keyof typeof sk, MySqlColumn>;\n\n const issue = Effect.fn(\"DrizzleMysqlOAuthStateStore.issue\")(function* (input: OAuthState) {\n yield* Effect.suspend(() =>\n db.insert(stateTable as any).values(mapping.oauthState.encodeInsert(input, false) as any),\n ).pipe(mapStoreWriteFailure);\n });\n\n const consumeDecision = Effect.fn(\"DrizzleMysqlOAuthStateStore.consumeDecision\")(function* (\n digest: TokenDigest,\n ): Effect.fn.Return<ConsumeDecision<OAuthState>, AuthStoreError> {\n return yield* Effect.suspend(() =>\n db.transaction((tx) =>\n Effect.gen(function* () {\n const rows = yield* tx\n .select()\n .from(stateTable as any)\n .where(eq(s.stateDigest, digest))\n .for(\"update\")\n .limit(1);\n\n if (rows[0] === undefined) return { _tag: \"rejected\" } as const;\n const row = yield* mapping.oauthState.decode(selected<S>(rows[0]));\n const now = yield* DateTime.now;\n\n if (\n row.consumed ||\n DateTime.toEpochMillis(row.state.expiresAt) <= DateTime.toEpochMillis(now)\n )\n return { _tag: \"rejected\" } as const;\n yield* tx\n .update(stateTable as any)\n .set(updateValues<S>([[sk.consumed, true]]) as any)\n .where(eq(s.stateDigest, digest));\n\n return { _tag: \"accepted\", value: row.state } as const;\n }),\n ),\n ).pipe(mapStoreWriteFailure);\n });\n\n const consume = Effect.fn(\"DrizzleMysqlOAuthStateStore.consume\")(function* (digest: TokenDigest) {\n yield* requireStandaloneConsume(db);\n const decision = yield* consumeDecision(digest);\n\n return decision._tag === \"accepted\" ? decision.value : yield* InvalidOAuthState.make();\n });\n\n return {\n oauthStateStore: OAuthStateStore.of({ issue, consume }),\n decisions: { consumeOAuthState: consumeDecision },\n } as const;\n};\n\nexport const makeMysqlAuthServices = <\n C extends AnyMySqlTable,\n R extends AnyMySqlTable,\n S extends AnyMySqlTable,\n>(\n database: Database,\n mapping: AuthTables<C, R, S>,\n) => {\n const auth = makeMysqlAuthStoreServices(database, mapping);\n const oauth = makeMysqlOAuthStateServices(database, mapping);\n\n return { ...auth, ...oauth, decisions: { ...auth.decisions, ...oauth.decisions } } as const;\n};\n\n/**\n * Owns the native outer commit. Keep rejection as a decision value inside the\n * owner; interruption before commit rolls back. This adapter never retries a\n * deadlock inside the caller's transaction.\n */\nexport function coordinateMysqlAuthStoreTransaction<\n D extends Database,\n C extends AnyMySqlTable,\n R extends AnyMySqlTable,\n A,\n E,\n Requirements,\n DatabaseError,\n DatabaseRequirements,\n>(\n acquire: Effect.Effect<D, DatabaseError, DatabaseRequirements>,\n options: { readonly mapping: AuthStoreTables<C, R>; readonly transaction?: never },\n body: Effect.Effect<A, E, Requirements>,\n): Effect.Effect<\n A,\n E | DatabaseError | SqlError,\n Exclude<Requirements, AuthStoreDecisions> | DatabaseRequirements\n>;\n\nexport function coordinateMysqlAuthStoreTransaction<\n D extends Database,\n C extends AnyMySqlTable,\n R extends AnyMySqlTable,\n A,\n E,\n Requirements,\n DatabaseError,\n DatabaseRequirements,\n TxId,\n TxShape,\n>(\n acquire: Effect.Effect<D, DatabaseError, DatabaseRequirements>,\n options: {\n readonly mapping: AuthStoreTables<C, R>;\n readonly transaction: SuppliedService<TxId, NoInfer<TransactionOf<D>>, TxShape>;\n },\n body: Effect.Effect<A, E, Requirements>,\n): Effect.Effect<\n A,\n E | DatabaseError | SqlError,\n Exclude<Requirements, AuthStoreDecisions | TxId> | DatabaseRequirements\n>;\n\nexport function coordinateMysqlAuthStoreTransaction<\n D extends Database,\n C extends AnyMySqlTable,\n R extends AnyMySqlTable,\n A,\n E,\n Requirements,\n DatabaseError,\n DatabaseRequirements,\n TxId,\n TxShape,\n>(\n acquire: Effect.Effect<D, DatabaseError, DatabaseRequirements>,\n options: {\n readonly mapping: AuthStoreTables<C, R>;\n readonly transaction?: SuppliedService<TxId, NoInfer<TransactionOf<D>>, TxShape>;\n },\n body: Effect.Effect<A, E, Requirements>,\n) {\n return Effect.flatMap(acquire, (database) =>\n database.transaction<A, E, Exclude<Requirements, AuthStoreDecisions>>((transaction) => {\n const decisions = makeMysqlAuthStoreServices(transaction as never, options.mapping).decisions;\n const provided = Context.make(AuthStoreDecisions, decisions);\n const work = Effect.provideContext(body, provided);\n\n return options.transaction === undefined\n ? work\n : Effect.provideService(\n work,\n options.transaction,\n options.transaction.of(transaction as TransactionOf<D>),\n );\n }),\n );\n}\n\nexport function coordinateMysqlOAuthStateTransaction<\n D extends Database,\n S extends AnyMySqlTable,\n A,\n E,\n Requirements,\n DatabaseError,\n DatabaseRequirements,\n>(\n acquire: Effect.Effect<D, DatabaseError, DatabaseRequirements>,\n options: { readonly mapping: OAuthStateTables<S>; readonly transaction?: never },\n body: Effect.Effect<A, E, Requirements>,\n): Effect.Effect<\n A,\n E | DatabaseError | SqlError,\n Exclude<Requirements, OAuthStateDecisions> | DatabaseRequirements\n>;\n\nexport function coordinateMysqlOAuthStateTransaction<\n D extends Database,\n S extends AnyMySqlTable,\n A,\n E,\n Requirements,\n DatabaseError,\n DatabaseRequirements,\n TxId,\n TxShape,\n>(\n acquire: Effect.Effect<D, DatabaseError, DatabaseRequirements>,\n options: {\n readonly mapping: OAuthStateTables<S>;\n readonly transaction: SuppliedService<TxId, NoInfer<TransactionOf<D>>, TxShape>;\n },\n body: Effect.Effect<A, E, Requirements>,\n): Effect.Effect<\n A,\n E | DatabaseError | SqlError,\n Exclude<Requirements, OAuthStateDecisions | TxId> | DatabaseRequirements\n>;\n\nexport function coordinateMysqlOAuthStateTransaction<\n D extends Database,\n S extends AnyMySqlTable,\n A,\n E,\n Requirements,\n DatabaseError,\n DatabaseRequirements,\n TxId,\n TxShape,\n>(\n acquire: Effect.Effect<D, DatabaseError, DatabaseRequirements>,\n options: {\n readonly mapping: OAuthStateTables<S>;\n readonly transaction?: SuppliedService<TxId, NoInfer<TransactionOf<D>>, TxShape>;\n },\n body: Effect.Effect<A, E, Requirements>,\n) {\n return Effect.flatMap(acquire, (database) =>\n database.transaction<A, E, Exclude<Requirements, OAuthStateDecisions>>((transaction) => {\n const decisions = makeMysqlOAuthStateServices(\n transaction as never,\n options.mapping,\n ).decisions;\n\n const provided = Context.make(OAuthStateDecisions, decisions);\n const work = Effect.provideContext(body, provided);\n\n return options.transaction === undefined\n ? work\n : Effect.provideService(\n work,\n options.transaction,\n options.transaction.of(transaction as TransactionOf<D>),\n );\n }),\n );\n}\n\nexport function coordinateMysqlAuthTransaction<\n D extends Database,\n C extends AnyMySqlTable,\n R extends AnyMySqlTable,\n S extends AnyMySqlTable,\n A,\n E,\n Requirements,\n DatabaseError,\n DatabaseRequirements,\n>(\n acquire: Effect.Effect<D, DatabaseError, DatabaseRequirements>,\n options: { readonly mapping: AuthTables<C, R, S>; readonly transaction?: never },\n body: Effect.Effect<A, E, Requirements>,\n): Effect.Effect<\n A,\n E | DatabaseError | SqlError,\n Exclude<Requirements, AuthStoreDecisions | OAuthStateDecisions> | DatabaseRequirements\n>;\n\nexport function coordinateMysqlAuthTransaction<\n D extends Database,\n C extends AnyMySqlTable,\n R extends AnyMySqlTable,\n S extends AnyMySqlTable,\n A,\n E,\n Requirements,\n DatabaseError,\n DatabaseRequirements,\n TxId,\n TxShape,\n>(\n acquire: Effect.Effect<D, DatabaseError, DatabaseRequirements>,\n options: {\n readonly mapping: AuthTables<C, R, S>;\n readonly transaction: SuppliedService<TxId, NoInfer<TransactionOf<D>>, TxShape>;\n },\n body: Effect.Effect<A, E, Requirements>,\n): Effect.Effect<\n A,\n E | DatabaseError | SqlError,\n Exclude<Requirements, AuthStoreDecisions | OAuthStateDecisions | TxId> | DatabaseRequirements\n>;\n\nexport function coordinateMysqlAuthTransaction<\n D extends Database,\n C extends AnyMySqlTable,\n R extends AnyMySqlTable,\n S extends AnyMySqlTable,\n A,\n E,\n Requirements,\n DatabaseError,\n DatabaseRequirements,\n TxId,\n TxShape,\n>(\n acquire: Effect.Effect<D, DatabaseError, DatabaseRequirements>,\n options: {\n readonly mapping: AuthTables<C, R, S>;\n readonly transaction?: SuppliedService<TxId, NoInfer<TransactionOf<D>>, TxShape>;\n },\n body: Effect.Effect<A, E, Requirements>,\n) {\n return Effect.flatMap(acquire, (database) =>\n database.transaction<A, E, Exclude<Requirements, AuthStoreDecisions | OAuthStateDecisions>>(\n (transaction) => {\n const decisions = makeMysqlAuthServices(transaction as never, options.mapping).decisions;\n\n const provided = Context.make(AuthStoreDecisions, decisions).pipe(\n Context.add(OAuthStateDecisions, decisions),\n );\n\n const work = Effect.provideContext(body, provided);\n\n return options.transaction === undefined\n ? work\n : Effect.provideService(\n work,\n options.transaction,\n options.transaction.of(transaction as TransactionOf<D>),\n );\n },\n ),\n );\n}\n"],"mappings":"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"}
|
package/dist/drizzle/pg.d.mts
DELETED
|
@@ -1,80 +0,0 @@
|
|
|
1
|
-
import { AuthStoreTables, AuthTables, ChallengeConsumeDecision, ConsumeDecision, ExternalIdentityTables, OAuthStateTables, SubjectProvisioningTables } from "./model.mjs";
|
|
2
|
-
import { SuppliedService } from "./SuppliedService.mjs";
|
|
3
|
-
import { AuthStore, EmailOtpRejected } from "@yielded/auth/AuthStore";
|
|
4
|
-
import { AuthStoreError, InvalidRegistration } from "@yielded/auth/Errors";
|
|
5
|
-
import { ExternalIdentity, ExternalIdentityMutation, IdentityConflict, IdentityUnavailable, SubjectProvisioner, SubjectProvisioningInput } from "@yielded/auth/Identity";
|
|
6
|
-
import { InvalidOAuthState, OAuthState, OAuthStateDecisions, OAuthStateStore } from "@yielded/auth/OAuth";
|
|
7
|
-
import { ConsumeChallenge, ConsumeRegistration, NewChallenge, NewRegistration, SubjectId, TokenDigest, VerifiedEmail } from "@yielded/auth/Schema";
|
|
8
|
-
import { AnyRelations } from "drizzle-orm";
|
|
9
|
-
import { Context, Effect, Layer } from "effect";
|
|
10
|
-
import { AuthStoreDecisions } from "@yielded/auth/Persistence";
|
|
11
|
-
import { EffectPgDatabase } from "drizzle-orm/effect-pglite";
|
|
12
|
-
import { AnyPgTable } from "drizzle-orm/pg-core";
|
|
13
|
-
import { EffectPgDatabase as EffectPgDatabase$1 } from "drizzle-orm/effect-postgres";
|
|
14
|
-
import { SqlError } from "effect/unstable/sql/SqlError";
|
|
15
|
-
//#region src/drizzle/pg.d.ts
|
|
16
|
-
type Database = EffectPgDatabase$1<AnyRelations> | EffectPgDatabase<AnyRelations>;
|
|
17
|
-
type TransactionOf<D extends Database> = Parameters<Parameters<D["transaction"]>[0]>[0];
|
|
18
|
-
export declare const makePgAuthStoreServices: <C extends AnyPgTable, R extends AnyPgTable>(database: Database, mapping: AuthStoreTables<C, R>) => {
|
|
19
|
-
readonly authStore: {
|
|
20
|
-
readonly issueChallenge: (input: NewChallenge) => Effect.Effect<void, import("@yielded/auth/AuthStore").IssueChallengeError>;
|
|
21
|
-
readonly consumeChallenge: (input: ConsumeChallenge) => Effect.Effect<VerifiedEmail, EmailOtpRejected | AuthStoreError>;
|
|
22
|
-
readonly issueRegistration: (input: NewRegistration) => Effect.Effect<void, AuthStoreError>;
|
|
23
|
-
readonly inspectRegistration: (tokenDigest: TokenDigest) => Effect.Effect<import("@yielded/auth/Schema").PendingRegistration, InvalidRegistration | AuthStoreError>;
|
|
24
|
-
readonly consumeRegistration: (input: ConsumeRegistration) => Effect.Effect<void, InvalidRegistration | AuthStoreError>;
|
|
25
|
-
};
|
|
26
|
-
readonly decisions: {
|
|
27
|
-
readonly consumeChallenge: (input: ConsumeChallenge) => Effect.Effect<ChallengeConsumeDecision, AuthStoreError, never>;
|
|
28
|
-
readonly consumeRegistration: (input: ConsumeRegistration) => Effect.Effect<ConsumeDecision<void>, AuthStoreError, never>;
|
|
29
|
-
};
|
|
30
|
-
};
|
|
31
|
-
export declare const makePgOAuthStateServices: <S extends AnyPgTable>(database: Database, mapping: OAuthStateTables<S>) => {
|
|
32
|
-
readonly oauthStateStore: {
|
|
33
|
-
readonly issue: (state: OAuthState) => Effect.Effect<void, AuthStoreError>;
|
|
34
|
-
readonly consume: (stateDigest: TokenDigest) => Effect.Effect<OAuthState, InvalidOAuthState | AuthStoreError>;
|
|
35
|
-
};
|
|
36
|
-
readonly decisions: {
|
|
37
|
-
readonly consumeOAuthState: (digest: string & import("effect/Brand").Brand<"effect-auth/TokenDigest">) => Effect.Effect<ConsumeDecision<OAuthState>, AuthStoreError, never>;
|
|
38
|
-
};
|
|
39
|
-
};
|
|
40
|
-
/**
|
|
41
|
-
* Owns the native outer commit. Keep rejection as a decision value inside the
|
|
42
|
-
* owner; interruption before commit rolls back. Retry an unknown commit outcome
|
|
43
|
-
* only with the same stable request identity.
|
|
44
|
-
*/
|
|
45
|
-
export declare function coordinatePgAuthStoreTransaction<D extends Database, C extends AnyPgTable, R extends AnyPgTable, A, E, Requirements, DatabaseError, DatabaseRequirements>(acquire: Effect.Effect<D, DatabaseError, DatabaseRequirements>, options: {
|
|
46
|
-
readonly mapping: AuthStoreTables<C, R>;
|
|
47
|
-
readonly transaction?: never;
|
|
48
|
-
}, body: Effect.Effect<A, E, Requirements>): Effect.Effect<A, E | DatabaseError | SqlError, Exclude<Requirements, AuthStoreDecisions> | DatabaseRequirements>;
|
|
49
|
-
export declare function coordinatePgAuthStoreTransaction<D extends Database, C extends AnyPgTable, R extends AnyPgTable, A, E, Requirements, DatabaseError, DatabaseRequirements, TxId, TxShape>(acquire: Effect.Effect<D, DatabaseError, DatabaseRequirements>, options: {
|
|
50
|
-
readonly mapping: AuthStoreTables<C, R>;
|
|
51
|
-
readonly transaction: SuppliedService<TxId, NoInfer<TransactionOf<D>>, TxShape>;
|
|
52
|
-
}, body: Effect.Effect<A, E, Requirements>): Effect.Effect<A, E | DatabaseError | SqlError, Exclude<Requirements, AuthStoreDecisions | TxId> | DatabaseRequirements>;
|
|
53
|
-
export declare function coordinatePgOAuthStateTransaction<D extends Database, S extends AnyPgTable, A, E, Requirements, DatabaseError, DatabaseRequirements>(acquire: Effect.Effect<D, DatabaseError, DatabaseRequirements>, options: {
|
|
54
|
-
readonly mapping: OAuthStateTables<S>;
|
|
55
|
-
readonly transaction?: never;
|
|
56
|
-
}, body: Effect.Effect<A, E, Requirements>): Effect.Effect<A, E | DatabaseError | SqlError, Exclude<Requirements, OAuthStateDecisions> | DatabaseRequirements>;
|
|
57
|
-
export declare function coordinatePgOAuthStateTransaction<D extends Database, S extends AnyPgTable, A, E, Requirements, DatabaseError, DatabaseRequirements, TxId, TxShape>(acquire: Effect.Effect<D, DatabaseError, DatabaseRequirements>, options: {
|
|
58
|
-
readonly mapping: OAuthStateTables<S>;
|
|
59
|
-
readonly transaction: SuppliedService<TxId, NoInfer<TransactionOf<D>>, TxShape>;
|
|
60
|
-
}, body: Effect.Effect<A, E, Requirements>): Effect.Effect<A, E | DatabaseError | SqlError, Exclude<Requirements, OAuthStateDecisions | TxId> | DatabaseRequirements>;
|
|
61
|
-
export declare function coordinatePgAuthTransaction<D extends Database, C extends AnyPgTable, R extends AnyPgTable, S extends AnyPgTable, A, E, Requirements, DatabaseError, DatabaseRequirements>(acquire: Effect.Effect<D, DatabaseError, DatabaseRequirements>, options: {
|
|
62
|
-
readonly mapping: AuthTables<C, R, S>;
|
|
63
|
-
readonly transaction?: never;
|
|
64
|
-
}, body: Effect.Effect<A, E, Requirements>): Effect.Effect<A, E | DatabaseError | SqlError, Exclude<Requirements, AuthStoreDecisions | OAuthStateDecisions> | DatabaseRequirements>;
|
|
65
|
-
export declare function coordinatePgAuthTransaction<D extends Database, C extends AnyPgTable, R extends AnyPgTable, S extends AnyPgTable, A, E, Requirements, DatabaseError, DatabaseRequirements, TxId, TxShape>(acquire: Effect.Effect<D, DatabaseError, DatabaseRequirements>, options: {
|
|
66
|
-
readonly mapping: AuthTables<C, R, S>;
|
|
67
|
-
readonly transaction: SuppliedService<TxId, NoInfer<TransactionOf<D>>, TxShape>;
|
|
68
|
-
}, body: Effect.Effect<A, E, Requirements>): Effect.Effect<A, E | DatabaseError | SqlError, Exclude<Requirements, AuthStoreDecisions | OAuthStateDecisions | TxId> | DatabaseRequirements>;
|
|
69
|
-
export declare const makePgSubjectProvisioningServices: <Subject extends AnyPgTable, Identifier extends AnyPgTable, Request extends AnyPgTable, NativeId>(database: Database, mapping: SubjectProvisioningTables<Subject, Identifier, Request, NativeId>) => {
|
|
70
|
-
readonly subjectProvisioner: {
|
|
71
|
-
readonly provision: (input: SubjectProvisioningInput) => Effect.Effect<import("@yielded/auth/Identity").ProvisioningResult, IdentityConflict | IdentityUnavailable>;
|
|
72
|
-
};
|
|
73
|
-
};
|
|
74
|
-
export declare const makePgExternalIdentityServices: <Subject extends AnyPgTable, External extends AnyPgTable, NativeId>(database: Database, mapping: ExternalIdentityTables<Subject, External, NativeId>) => {
|
|
75
|
-
readonly externalIdentityMutation: {
|
|
76
|
-
readonly bind: (subjectId: SubjectId, identity: ExternalIdentity) => Effect.Effect<void, IdentityConflict | IdentityUnavailable>;
|
|
77
|
-
};
|
|
78
|
-
};
|
|
79
|
-
//#endregion
|
|
80
|
-
//# sourceMappingURL=pg.d.mts.map
|