@oidcraft/drizzle 0.1.0 → 0.2.0
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/dist/index.d.mts +48 -1
- package/dist/index.mjs +95 -30
- package/package.json +3 -3
package/dist/index.d.mts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
+
import { AccountStore, FullAdapter, KeyStore } from "@oidcraft/adapter";
|
|
1
2
|
import { AnyRelations } from "drizzle-orm";
|
|
2
3
|
import { SQLiteAsyncDatabase } from "drizzle-orm/sqlite-core";
|
|
3
4
|
import { PgQueryResultHKT } from "drizzle-orm/pg-core";
|
|
4
|
-
import { AccountStore, FullAdapter, KeyStore } from "@oidcraft/adapter";
|
|
5
5
|
import { PgAsyncDatabase } from "drizzle-orm/pg-core/async";
|
|
6
6
|
/**
|
|
7
7
|
* The oidcraft tables for Postgres, in `schema` or in the search path when it is omitted. A factory,
|
|
@@ -168,6 +168,21 @@ export declare const postgresTables: (schema?: string) => {
|
|
|
168
168
|
identity: undefined;
|
|
169
169
|
generated: undefined;
|
|
170
170
|
}>;
|
|
171
|
+
familyId: import("drizzle-orm/pg-core").PgBuildColumn<"oidc_artifacts", import("drizzle-orm/pg-core").PgTextBuilder<[string, ...string[]]>, {
|
|
172
|
+
name: string;
|
|
173
|
+
tableName: "oidc_artifacts";
|
|
174
|
+
dataType: "string";
|
|
175
|
+
data: string;
|
|
176
|
+
driverParam: string;
|
|
177
|
+
notNull: false;
|
|
178
|
+
hasDefault: false;
|
|
179
|
+
isPrimaryKey: false;
|
|
180
|
+
isAutoincrement: false;
|
|
181
|
+
hasRuntimeDefault: false;
|
|
182
|
+
enumValues: undefined;
|
|
183
|
+
identity: undefined;
|
|
184
|
+
generated: undefined;
|
|
185
|
+
}>;
|
|
171
186
|
userCode: import("drizzle-orm/pg-core").PgBuildColumn<"oidc_artifacts", import("drizzle-orm/pg-core").PgTextBuilder<[string, ...string[]]>, {
|
|
172
187
|
name: string;
|
|
173
188
|
tableName: "oidc_artifacts";
|
|
@@ -1207,6 +1222,22 @@ export declare const artifacts: import("drizzle-orm/sqlite-core").SQLiteTableWit
|
|
|
1207
1222
|
identity: undefined;
|
|
1208
1223
|
generated: undefined;
|
|
1209
1224
|
}, {}>;
|
|
1225
|
+
familyId: import("drizzle-orm/sqlite-core").SQLiteColumn<{
|
|
1226
|
+
name: string;
|
|
1227
|
+
tableName: "oidc_artifacts";
|
|
1228
|
+
dataType: "string";
|
|
1229
|
+
data: string;
|
|
1230
|
+
driverParam: string;
|
|
1231
|
+
notNull: false;
|
|
1232
|
+
hasDefault: false;
|
|
1233
|
+
isPrimaryKey: false;
|
|
1234
|
+
isAutoincrement: false;
|
|
1235
|
+
hasRuntimeDefault: false;
|
|
1236
|
+
enumValues: [string, ...string[]];
|
|
1237
|
+
baseColumn: never;
|
|
1238
|
+
identity: undefined;
|
|
1239
|
+
generated: undefined;
|
|
1240
|
+
}, {}>;
|
|
1210
1241
|
userCode: import("drizzle-orm/sqlite-core").SQLiteColumn<{
|
|
1211
1242
|
name: string;
|
|
1212
1243
|
tableName: "oidc_artifacts";
|
|
@@ -2168,6 +2199,22 @@ export declare const schema: {
|
|
|
2168
2199
|
identity: undefined;
|
|
2169
2200
|
generated: undefined;
|
|
2170
2201
|
}, {}>;
|
|
2202
|
+
familyId: import("drizzle-orm/sqlite-core").SQLiteColumn<{
|
|
2203
|
+
name: string;
|
|
2204
|
+
tableName: "oidc_artifacts";
|
|
2205
|
+
dataType: "string";
|
|
2206
|
+
data: string;
|
|
2207
|
+
driverParam: string;
|
|
2208
|
+
notNull: false;
|
|
2209
|
+
hasDefault: false;
|
|
2210
|
+
isPrimaryKey: false;
|
|
2211
|
+
isAutoincrement: false;
|
|
2212
|
+
hasRuntimeDefault: false;
|
|
2213
|
+
enumValues: [string, ...string[]];
|
|
2214
|
+
baseColumn: never;
|
|
2215
|
+
identity: undefined;
|
|
2216
|
+
generated: undefined;
|
|
2217
|
+
}, {}>;
|
|
2171
2218
|
userCode: import("drizzle-orm/sqlite-core").SQLiteColumn<{
|
|
2172
2219
|
name: string;
|
|
2173
2220
|
tableName: "oidc_artifacts";
|
package/dist/index.mjs
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { noAccounts } from "@oidcraft/adapter";
|
|
1
2
|
import { and, eq, gt, isNull, lte } from "drizzle-orm";
|
|
2
3
|
import { index, integer, primaryKey, sqliteTable, text, uniqueIndex } from "drizzle-orm/sqlite-core";
|
|
3
4
|
import { customType, index as index$1, integer as integer$1, pgSchema, pgTable, primaryKey as primaryKey$1, text as text$1, uniqueIndex as uniqueIndex$1 } from "drizzle-orm/pg-core";
|
|
@@ -21,6 +22,7 @@ const artifacts = sqliteTable("oidc_artifacts", {
|
|
|
21
22
|
clientId: text("client_id").notNull(),
|
|
22
23
|
accountId: text("account_id"),
|
|
23
24
|
grantId: text("grant_id"),
|
|
25
|
+
familyId: text("family_id"),
|
|
24
26
|
userCode: text("user_code"),
|
|
25
27
|
payload: text("payload", { mode: "json" }).notNull(),
|
|
26
28
|
consumedAt: integer("consumed_at", { mode: "timestamp_ms" }),
|
|
@@ -29,7 +31,9 @@ const artifacts = sqliteTable("oidc_artifacts", {
|
|
|
29
31
|
primaryKey({ columns: [table.kind, table.id] }),
|
|
30
32
|
index("oidc_artifacts_grant_idx").on(table.grantId),
|
|
31
33
|
index("oidc_artifacts_user_code_idx").on(table.userCode),
|
|
32
|
-
index("oidc_artifacts_expiry_idx").on(table.expiresAt)
|
|
34
|
+
index("oidc_artifacts_expiry_idx").on(table.expiresAt),
|
|
35
|
+
index("oidc_artifacts_client_idx").on(table.clientId),
|
|
36
|
+
index("oidc_artifacts_family_idx").on(table.familyId)
|
|
33
37
|
]);
|
|
34
38
|
const sessions = sqliteTable("oidc_sessions", {
|
|
35
39
|
id: text("id").primaryKey(),
|
|
@@ -55,7 +59,7 @@ const grants = sqliteTable("oidc_grants", {
|
|
|
55
59
|
resources: text("resources", { mode: "json" }).notNull(),
|
|
56
60
|
createdAt: integer("created_at", { mode: "timestamp_ms" }).notNull(),
|
|
57
61
|
expiresAt: integer("expires_at", { mode: "timestamp_ms" })
|
|
58
|
-
}, (table) => [uniqueIndex("oidc_grants_account_client_idx").on(table.accountId, table.clientId)]);
|
|
62
|
+
}, (table) => [uniqueIndex("oidc_grants_account_client_idx").on(table.accountId, table.clientId), index("oidc_grants_client_idx").on(table.clientId)]);
|
|
59
63
|
const identities = sqliteTable("oidc_identities", {
|
|
60
64
|
provider: text("provider").notNull(),
|
|
61
65
|
subject: text("subject").notNull(),
|
|
@@ -137,6 +141,18 @@ const POSTGRES_MIGRATIONS = [
|
|
|
137
141
|
{
|
|
138
142
|
id: "0003_realms",
|
|
139
143
|
statements: ["create table oidc_realms (id text primary key, display_name text, enabled integer not null, settings text not null, created_at bigint not null, updated_at bigint not null)"]
|
|
144
|
+
},
|
|
145
|
+
{
|
|
146
|
+
id: "0004_indexes",
|
|
147
|
+
statements: [
|
|
148
|
+
"create index oidc_artifacts_client_idx on oidc_artifacts (client_id)",
|
|
149
|
+
"create index oidc_grants_client_idx on oidc_grants (client_id)",
|
|
150
|
+
"create index oidc_sessions_expiry_idx on oidc_sessions (expires_at)"
|
|
151
|
+
]
|
|
152
|
+
},
|
|
153
|
+
{
|
|
154
|
+
id: "0005_families",
|
|
155
|
+
statements: ["alter table oidc_artifacts add column family_id text", "create index oidc_artifacts_family_idx on oidc_artifacts (family_id)"]
|
|
140
156
|
}
|
|
141
157
|
];
|
|
142
158
|
// ../sql/dist/sqlite.mjs
|
|
@@ -175,6 +191,18 @@ const SQLITE_MIGRATIONS = [
|
|
|
175
191
|
{
|
|
176
192
|
id: "0003_realms",
|
|
177
193
|
statements: ["create table oidc_realms (id text primary key, display_name text, enabled integer not null, settings text not null, created_at integer not null, updated_at integer not null)"]
|
|
194
|
+
},
|
|
195
|
+
{
|
|
196
|
+
id: "0004_indexes",
|
|
197
|
+
statements: [
|
|
198
|
+
"create index oidc_artifacts_client_idx on oidc_artifacts (client_id)",
|
|
199
|
+
"create index oidc_grants_client_idx on oidc_grants (client_id)",
|
|
200
|
+
"create index oidc_sessions_expiry_idx on oidc_sessions (expires_at)"
|
|
201
|
+
]
|
|
202
|
+
},
|
|
203
|
+
{
|
|
204
|
+
id: "0005_families",
|
|
205
|
+
statements: ["alter table oidc_artifacts add column family_id text", "create index oidc_artifacts_family_idx on oidc_artifacts (family_id)"]
|
|
178
206
|
}
|
|
179
207
|
];
|
|
180
208
|
// src/postgres-schema.ts
|
|
@@ -213,6 +241,7 @@ const postgresTables = (schema) => {
|
|
|
213
241
|
clientId: text$1("client_id").notNull(),
|
|
214
242
|
accountId: text$1("account_id"),
|
|
215
243
|
grantId: text$1("grant_id"),
|
|
244
|
+
familyId: text$1("family_id"),
|
|
216
245
|
userCode: text$1("user_code"),
|
|
217
246
|
payload: json("payload").notNull(),
|
|
218
247
|
consumedAt: millis("consumed_at"),
|
|
@@ -221,7 +250,9 @@ const postgresTables = (schema) => {
|
|
|
221
250
|
primaryKey$1({ columns: [t.kind, t.id] }),
|
|
222
251
|
index$1("oidc_artifacts_grant_idx").on(t.grantId),
|
|
223
252
|
index$1("oidc_artifacts_user_code_idx").on(t.userCode),
|
|
224
|
-
index$1("oidc_artifacts_expiry_idx").on(t.expiresAt)
|
|
253
|
+
index$1("oidc_artifacts_expiry_idx").on(t.expiresAt),
|
|
254
|
+
index$1("oidc_artifacts_client_idx").on(t.clientId),
|
|
255
|
+
index$1("oidc_artifacts_family_idx").on(t.familyId)
|
|
225
256
|
]),
|
|
226
257
|
sessions: table("oidc_sessions", {
|
|
227
258
|
id: text$1("id").primaryKey(),
|
|
@@ -233,7 +264,11 @@ const postgresTables = (schema) => {
|
|
|
233
264
|
upstreamSessionId: text$1("upstream_session_id"),
|
|
234
265
|
clients: json("clients").notNull(),
|
|
235
266
|
expiresAt: millis("expires_at").notNull()
|
|
236
|
-
}, (t) => [
|
|
267
|
+
}, (t) => [
|
|
268
|
+
index$1("oidc_sessions_account_idx").on(t.accountId),
|
|
269
|
+
index$1("oidc_sessions_upstream_idx").on(t.idp, t.upstreamSessionId),
|
|
270
|
+
index$1("oidc_sessions_expiry_idx").on(t.expiresAt)
|
|
271
|
+
]),
|
|
237
272
|
grants: table("oidc_grants", {
|
|
238
273
|
id: text$1("id").primaryKey(),
|
|
239
274
|
accountId: text$1("account_id").notNull(),
|
|
@@ -243,7 +278,7 @@ const postgresTables = (schema) => {
|
|
|
243
278
|
resources: json("resources").notNull(),
|
|
244
279
|
createdAt: millis("created_at").notNull(),
|
|
245
280
|
expiresAt: millis("expires_at")
|
|
246
|
-
}, (t) => [uniqueIndex$1("oidc_grants_account_client_idx").on(t.accountId, t.clientId)]),
|
|
281
|
+
}, (t) => [uniqueIndex$1("oidc_grants_account_client_idx").on(t.accountId, t.clientId), index$1("oidc_grants_client_idx").on(t.clientId)]),
|
|
247
282
|
identities: table("oidc_identities", {
|
|
248
283
|
provider: text$1("provider").notNull(),
|
|
249
284
|
subject: text$1("subject").notNull(),
|
|
@@ -293,6 +328,7 @@ const drizzleAdapter = (options) => {
|
|
|
293
328
|
clientId: row.clientId,
|
|
294
329
|
...row.accountId && { accountId: row.accountId },
|
|
295
330
|
...row.grantId && { grantId: row.grantId },
|
|
331
|
+
...row.familyId && { familyId: row.familyId },
|
|
296
332
|
payload: row.payload,
|
|
297
333
|
...row.consumedAt && { consumedAt: row.consumedAt },
|
|
298
334
|
expiresAt: row.expiresAt
|
|
@@ -345,12 +381,19 @@ const drizzleAdapter = (options) => {
|
|
|
345
381
|
async destroy(clientId) {
|
|
346
382
|
await db.delete(clients).where(eq(clients.clientId, clientId));
|
|
347
383
|
},
|
|
348
|
-
async list() {
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
384
|
+
async list(cursor, limit) {
|
|
385
|
+
const ordered = db.select().from(clients).where(cursor === void 0 ? void 0 : gt(clients.clientId, cursor)).orderBy(clients.clientId);
|
|
386
|
+
const rows = await (limit === void 0 ? ordered : ordered.limit(limit + 1));
|
|
387
|
+
const more = limit !== void 0 && rows.length > limit;
|
|
388
|
+
const shown = more ? rows.slice(0, limit) : rows;
|
|
389
|
+
return {
|
|
390
|
+
clients: shown.map((row) => ({
|
|
391
|
+
...row.data,
|
|
392
|
+
createdAt: row.createdAt,
|
|
393
|
+
updatedAt: row.updatedAt
|
|
394
|
+
})),
|
|
395
|
+
...more && { cursor: shown.at(-1)?.clientId }
|
|
396
|
+
};
|
|
354
397
|
}
|
|
355
398
|
},
|
|
356
399
|
artifacts: {
|
|
@@ -361,6 +404,7 @@ const drizzleAdapter = (options) => {
|
|
|
361
404
|
clientId: artifact.clientId,
|
|
362
405
|
accountId: artifact.accountId ?? null,
|
|
363
406
|
grantId: artifact.grantId ?? null,
|
|
407
|
+
familyId: artifact.familyId ?? null,
|
|
364
408
|
userCode: artifact.payload.userCode ?? null,
|
|
365
409
|
payload: artifact.payload,
|
|
366
410
|
consumedAt: artifact.consumedAt ?? null,
|
|
@@ -391,6 +435,12 @@ const drizzleAdapter = (options) => {
|
|
|
391
435
|
async revokeByGrantId(grantId) {
|
|
392
436
|
await db.delete(artifacts).where(eq(artifacts.grantId, grantId));
|
|
393
437
|
},
|
|
438
|
+
async revokeByFamilyId(familyId) {
|
|
439
|
+
await db.delete(artifacts).where(eq(artifacts.familyId, familyId));
|
|
440
|
+
},
|
|
441
|
+
async revokeByClientId(clientId) {
|
|
442
|
+
await db.delete(artifacts).where(eq(artifacts.clientId, clientId));
|
|
443
|
+
},
|
|
394
444
|
async prune(before, limit) {
|
|
395
445
|
const doomed = await db.select({
|
|
396
446
|
kind: artifacts.kind,
|
|
@@ -409,7 +459,7 @@ const drizzleAdapter = (options) => {
|
|
|
409
459
|
return (await db.select().from(sessions).where(and(eq(sessions.accountId, accountId), gt(sessions.expiresAt, now())))).map(toSession);
|
|
410
460
|
},
|
|
411
461
|
async findByUpstreamSession(provider, upstreamSessionId) {
|
|
412
|
-
return (await db.select().from(sessions).where(and(eq(sessions.idp, provider), eq(sessions.upstreamSessionId, upstreamSessionId)))).map(toSession);
|
|
462
|
+
return (await db.select().from(sessions).where(and(eq(sessions.idp, provider), eq(sessions.upstreamSessionId, upstreamSessionId), gt(sessions.expiresAt, now())))).map(toSession);
|
|
413
463
|
},
|
|
414
464
|
async upsert(session) {
|
|
415
465
|
const row = {
|
|
@@ -440,6 +490,11 @@ const drizzleAdapter = (options) => {
|
|
|
440
490
|
},
|
|
441
491
|
async destroy(id) {
|
|
442
492
|
await db.delete(sessions).where(eq(sessions.id, id));
|
|
493
|
+
},
|
|
494
|
+
async prune(before, limit) {
|
|
495
|
+
const doomed = await db.select({ id: sessions.id }).from(sessions).where(lte(sessions.expiresAt, before)).limit(limit);
|
|
496
|
+
for (const row of doomed) await db.delete(sessions).where(and(eq(sessions.id, row.id), lte(sessions.expiresAt, before)));
|
|
497
|
+
return doomed.length;
|
|
443
498
|
}
|
|
444
499
|
},
|
|
445
500
|
grants: {
|
|
@@ -465,29 +520,43 @@ const drizzleAdapter = (options) => {
|
|
|
465
520
|
createdAt: grant.createdAt,
|
|
466
521
|
expiresAt: grant.expiresAt ?? null
|
|
467
522
|
};
|
|
523
|
+
const { id: _id, createdAt: _createdAt, ...changed } = row;
|
|
468
524
|
await db.insert(grants).values(row).onConflictDoUpdate({
|
|
469
|
-
target: grants.
|
|
470
|
-
set:
|
|
525
|
+
target: [grants.accountId, grants.clientId],
|
|
526
|
+
set: changed
|
|
471
527
|
});
|
|
472
528
|
},
|
|
473
529
|
async destroy(id) {
|
|
474
530
|
await db.delete(grants).where(eq(grants.id, id));
|
|
531
|
+
},
|
|
532
|
+
async destroyByClientId(clientId) {
|
|
533
|
+
await db.delete(grants).where(eq(grants.clientId, clientId));
|
|
475
534
|
}
|
|
476
535
|
},
|
|
477
536
|
accounts: options.accounts ?? noAccounts,
|
|
478
537
|
keys: options.keys,
|
|
479
|
-
replay: {
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
538
|
+
replay: {
|
|
539
|
+
async claim(namespace, value, ttl) {
|
|
540
|
+
const expiresAt = new Date(Date.now() + ttl * 1e3);
|
|
541
|
+
return (await db.insert(replay).values({
|
|
542
|
+
namespace,
|
|
543
|
+
value,
|
|
544
|
+
expiresAt
|
|
545
|
+
}).onConflictDoUpdate({
|
|
546
|
+
target: [replay.namespace, replay.value],
|
|
547
|
+
set: { expiresAt },
|
|
548
|
+
setWhere: lte(replay.expiresAt, now())
|
|
549
|
+
}).returning({ value: replay.value })).length === 1;
|
|
550
|
+
},
|
|
551
|
+
async prune(before, limit) {
|
|
552
|
+
const doomed = await db.select({
|
|
553
|
+
namespace: replay.namespace,
|
|
554
|
+
value: replay.value
|
|
555
|
+
}).from(replay).where(lte(replay.expiresAt, before)).limit(limit);
|
|
556
|
+
for (const row of doomed) await db.delete(replay).where(and(eq(replay.namespace, row.namespace), eq(replay.value, row.value), lte(replay.expiresAt, before)));
|
|
557
|
+
return doomed.length;
|
|
558
|
+
}
|
|
559
|
+
},
|
|
491
560
|
credentials: {
|
|
492
561
|
async find(accountId) {
|
|
493
562
|
const [row] = await db.select().from(credentials).where(eq(credentials.accountId, accountId)).limit(1);
|
|
@@ -561,10 +630,6 @@ const drizzleAdapter = (options) => {
|
|
|
561
630
|
}
|
|
562
631
|
};
|
|
563
632
|
};
|
|
564
|
-
const noAccounts = {
|
|
565
|
-
async find() {},
|
|
566
|
-
async claims() {}
|
|
567
|
-
};
|
|
568
633
|
const credentialRow = (credential) => ({
|
|
569
634
|
accountId: credential.accountId,
|
|
570
635
|
username: credential.username,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@oidcraft/drizzle",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "A Drizzle storage adapter for @oidcraft/provider, on Postgres or SQLite.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Fl0r14n <florian.chis@gmail.com>",
|
|
@@ -41,11 +41,11 @@
|
|
|
41
41
|
"verify:entries": "bun run verify-entries.ts"
|
|
42
42
|
},
|
|
43
43
|
"peerDependencies": {
|
|
44
|
-
"@oidcraft/adapter": "^0.
|
|
44
|
+
"@oidcraft/adapter": "^0.2.0",
|
|
45
45
|
"drizzle-orm": ">=1.0.0-rc.5"
|
|
46
46
|
},
|
|
47
47
|
"devDependencies": {
|
|
48
|
-
"@oidcraft/adapter": "^0.
|
|
48
|
+
"@oidcraft/adapter": "^0.2.0",
|
|
49
49
|
"@oidcraft/sql": "0.0.0",
|
|
50
50
|
"@types/pg": "^8.23.1",
|
|
51
51
|
"drizzle-orm": "1.0.0-rc.5",
|