1import { assert, it } from "@effect/vitest";
2import * as Effect from "effect/Effect";
3import * as Layer from "effect/Layer";
4import * as SqlClient from "effect/sql/SqlClient";
5
6import { runMigrations } from "../Migrations.ts";
7import * as NodeSqliteClient from "@t3tools/shared/nodeSqliteClient";
8
9const layer = it.layer(Layer.mergeAll(NodeSqliteClient.layer({ filename: ":memory:" })));
10
11layer("031_AuthAuthorizationScopes", (it) => {
12 it.effect("invalidates role-based auth records and installs scoped auth tables", () =>
13 Effect.gen(function* () {
14 const sql = yield* SqlClient.SqlClient;
15
16 yield* runMigrations({ toMigrationInclusive: 30 });
17
18 yield* sql`
19 INSERT INTO auth_pairing_links (
20 id,
21 credential,
22 method,
23 role,
24 subject,
25 created_at,
26 expires_at
27 )
28 VALUES (
29 'link-owner',
30 'bootstrap-owner',
31 'desktop-bootstrap',
32 'owner',
33 'desktop',
34 '2026-05-29T00:00:00.000Z',
35 '2026-05-29T01:00:00.000Z'
36 )
37 `;
38 yield* sql`
39 INSERT INTO auth_sessions (
40 session_id,
41 subject,
42 role,
43 method,
44 issued_at,
45 expires_at
46 )
47 VALUES (
48 'session-owner',
49 'desktop',
50 'owner',
51 'browser-session-cookie',
52 '2026-05-29T00:00:00.000Z',
53 '2026-05-29T01:00:00.000Z'
54 )
55 `;
56
57 yield* runMigrations({ toMigrationInclusive: 31 });
58
59 const pairingColumns = yield* sql<{ readonly name: string }>`
60 PRAGMA table_info(auth_pairing_links)
61 `;
62 const sessionColumns = yield* sql<{ readonly name: string }>`
63 PRAGMA table_info(auth_sessions)
64 `;
65 const pairingRows = yield* sql<{ readonly id: string }>`
66 SELECT id FROM auth_pairing_links
67 `;
68 const sessionRows = yield* sql<{ readonly sessionId: string }>`
69 SELECT session_id AS "sessionId" FROM auth_sessions
70 `;
71
72 assert.isTrue(pairingColumns.some((column) => column.name === "scopes"));
73 assert.isFalse(pairingColumns.some((column) => column.name === "role"));
74 assert.isTrue(sessionColumns.some((column) => column.name === "scopes"));
75 assert.isFalse(sessionColumns.some((column) => column.name === "role"));
76 assert.deepStrictEqual(pairingRows, []);
77 assert.deepStrictEqual(sessionRows, []);
78 }),
79 );
80});