@pattern-js/mod-identity 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/LICENSE +21 -0
- package/README.md +53 -0
- package/dist/admin-routes.d.ts +30 -0
- package/dist/admin-routes.d.ts.map +1 -0
- package/dist/admin-routes.js +52 -0
- package/dist/admin-routes.js.map +1 -0
- package/dist/auth-provider.d.ts +16 -0
- package/dist/auth-provider.d.ts.map +1 -0
- package/dist/auth-provider.js +47 -0
- package/dist/auth-provider.js.map +1 -0
- package/dist/cookies.d.ts +19 -0
- package/dist/cookies.d.ts.map +1 -0
- package/dist/cookies.js +44 -0
- package/dist/cookies.js.map +1 -0
- package/dist/csrf.d.ts +19 -0
- package/dist/csrf.d.ts.map +1 -0
- package/dist/csrf.js +39 -0
- package/dist/csrf.js.map +1 -0
- package/dist/deliver.d.ts +28 -0
- package/dist/deliver.d.ts.map +1 -0
- package/dist/deliver.js +36 -0
- package/dist/deliver.js.map +1 -0
- package/dist/frontend.d.ts +10 -0
- package/dist/frontend.d.ts.map +1 -0
- package/dist/frontend.js +139 -0
- package/dist/frontend.js.map +1 -0
- package/dist/index.d.ts +23 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +23 -0
- package/dist/index.js.map +1 -0
- package/dist/mod.d.ts +21 -0
- package/dist/mod.d.ts.map +1 -0
- package/dist/mod.js +97 -0
- package/dist/mod.js.map +1 -0
- package/dist/ops.d.ts +26 -0
- package/dist/ops.d.ts.map +1 -0
- package/dist/ops.js +379 -0
- package/dist/ops.js.map +1 -0
- package/dist/options.d.ts +53 -0
- package/dist/options.d.ts.map +1 -0
- package/dist/options.js +22 -0
- package/dist/options.js.map +1 -0
- package/dist/pages/bootstrap.d.ts +13 -0
- package/dist/pages/bootstrap.d.ts.map +1 -0
- package/dist/pages/bootstrap.js +23 -0
- package/dist/pages/bootstrap.js.map +1 -0
- package/dist/pages/html.d.ts +16 -0
- package/dist/pages/html.d.ts.map +1 -0
- package/dist/pages/html.js +72 -0
- package/dist/pages/html.js.map +1 -0
- package/dist/pages/login.d.ts +17 -0
- package/dist/pages/login.d.ts.map +1 -0
- package/dist/pages/login.js +43 -0
- package/dist/pages/login.js.map +1 -0
- package/dist/pages/welcome.d.ts +13 -0
- package/dist/pages/welcome.d.ts.map +1 -0
- package/dist/pages/welcome.js +19 -0
- package/dist/pages/welcome.js.map +1 -0
- package/dist/service-key.d.ts +12 -0
- package/dist/service-key.d.ts.map +1 -0
- package/dist/service-key.js +16 -0
- package/dist/service-key.js.map +1 -0
- package/dist/service.d.ts +133 -0
- package/dist/service.d.ts.map +1 -0
- package/dist/service.js +208 -0
- package/dist/service.js.map +1 -0
- package/dist/store/memory.d.ts +11 -0
- package/dist/store/memory.d.ts.map +1 -0
- package/dist/store/memory.js +0 -0
- package/dist/store/memory.js.map +1 -0
- package/dist/store/migrations.d.ts +21 -0
- package/dist/store/migrations.d.ts.map +1 -0
- package/dist/store/migrations.js +87 -0
- package/dist/store/migrations.js.map +1 -0
- package/dist/store/mutex.d.ts +13 -0
- package/dist/store/mutex.d.ts.map +1 -0
- package/dist/store/mutex.js +28 -0
- package/dist/store/mutex.js.map +1 -0
- package/dist/store/sqlite.d.ts +20 -0
- package/dist/store/sqlite.d.ts.map +1 -0
- package/dist/store/sqlite.js +254 -0
- package/dist/store/sqlite.js.map +1 -0
- package/dist/store/types.d.ts +135 -0
- package/dist/store/types.d.ts.map +1 -0
- package/dist/store/types.js +23 -0
- package/dist/store/types.js.map +1 -0
- package/dist/tokens.d.ts +16 -0
- package/dist/tokens.d.ts.map +1 -0
- package/dist/tokens.js +25 -0
- package/dist/tokens.js.map +1 -0
- package/dist/workflows.d.ts +14 -0
- package/dist/workflows.d.ts.map +1 -0
- package/dist/workflows.js +96 -0
- package/dist/workflows.js.map +1 -0
- package/docs/index.md +162 -0
- package/docs/ops/identity.bootstrap.page.md +5 -0
- package/docs/ops/identity.bootstrap.submit.md +5 -0
- package/docs/ops/identity.login.page.md +5 -0
- package/docs/ops/identity.logout.md +4 -0
- package/docs/ops/identity.sessions.list.md +5 -0
- package/docs/ops/identity.sessions.revoke.md +4 -0
- package/docs/ops/identity.settings.get.md +4 -0
- package/docs/ops/identity.settings.set.md +5 -0
- package/docs/ops/identity.token.callback.md +7 -0
- package/docs/ops/identity.users.get.md +5 -0
- package/docs/ops/identity.users.invite.md +7 -0
- package/docs/ops/identity.users.list.md +5 -0
- package/docs/ops/identity.users.loginLink.md +5 -0
- package/docs/ops/identity.users.revokeSessions.md +5 -0
- package/docs/ops/identity.users.runStats.md +7 -0
- package/docs/ops/identity.users.setRoles.md +5 -0
- package/docs/ops/identity.users.toggleDisabled.md +5 -0
- package/docs/ops/identity.welcome.page.md +5 -0
- package/docs/ops/identity.whoami.md +6 -0
- package/package.json +45 -0
package/dist/service.js
ADDED
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @pattern-js/mod-identity — the identity service (§9).
|
|
3
|
+
*
|
|
4
|
+
* Registered on the engine under core's `IDENTITY_SERVICE` key; consumed by
|
|
5
|
+
* this mod's ops, by provider mods (magic-link, oidc…) and by the admin's
|
|
6
|
+
* secure-by-default check. Bridges the two meanings of "auth provider":
|
|
7
|
+
* login methods prove who a human is (interactive flows, registered here);
|
|
8
|
+
* the session AuthProvider turns the resulting cookie back into a principal
|
|
9
|
+
* on every request.
|
|
10
|
+
*
|
|
11
|
+
* Scopes are compiled from roles **at resolve time**, so editing the role
|
|
12
|
+
* map applies on the next request — sessions store no scopes.
|
|
13
|
+
*/
|
|
14
|
+
import { UniqueViolationError } from "./store/types.js";
|
|
15
|
+
import { KeyedMutex } from "./store/mutex.js";
|
|
16
|
+
import { normalizeEmail, randomToken, sha256hex } from "./tokens.js";
|
|
17
|
+
const canCloseRooms = (c) => typeof c?.closeRoom === "function";
|
|
18
|
+
export class DefaultIdentityService {
|
|
19
|
+
stores;
|
|
20
|
+
options;
|
|
21
|
+
connections;
|
|
22
|
+
methods = new Map();
|
|
23
|
+
mutex = new KeyedMutex();
|
|
24
|
+
constructor(stores, options,
|
|
25
|
+
/** The engine's connection registry — revocation closes live WS sockets. */
|
|
26
|
+
connections) {
|
|
27
|
+
this.stores = stores;
|
|
28
|
+
this.options = options;
|
|
29
|
+
this.connections = connections;
|
|
30
|
+
}
|
|
31
|
+
/* ── users ───────────────────────────────────────────────────────────── */
|
|
32
|
+
async findOrCreateByIdentity(input) {
|
|
33
|
+
const emailNorm = normalizeEmail(input.email);
|
|
34
|
+
const byIdentity = await this.stores.users.findByIdentity(input.provider, input.subject);
|
|
35
|
+
if (byIdentity)
|
|
36
|
+
return byIdentity;
|
|
37
|
+
// Same email proven through a new provider → link, don't duplicate.
|
|
38
|
+
const byEmail = await this.stores.users.findByEmailNorm(emailNorm);
|
|
39
|
+
if (byEmail) {
|
|
40
|
+
await this.stores.users.linkIdentity(byEmail.id, input.provider, input.subject);
|
|
41
|
+
return byEmail;
|
|
42
|
+
}
|
|
43
|
+
if (!input.allowCreate)
|
|
44
|
+
return null;
|
|
45
|
+
try {
|
|
46
|
+
return await this.stores.users.createUser({
|
|
47
|
+
email: input.email.trim(),
|
|
48
|
+
emailNorm,
|
|
49
|
+
name: input.name ?? null,
|
|
50
|
+
roles: input.roles ?? [],
|
|
51
|
+
identity: { provider: input.provider, subject: input.subject },
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
catch (err) {
|
|
55
|
+
if (err instanceof UniqueViolationError) {
|
|
56
|
+
// Lost a concurrent-create race — the winner is our user.
|
|
57
|
+
const winner = await this.stores.users.findByEmailNorm(emailNorm);
|
|
58
|
+
if (winner) {
|
|
59
|
+
await this.stores.users.linkIdentity(winner.id, input.provider, input.subject);
|
|
60
|
+
return winner;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
throw err;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
getUser(id) {
|
|
67
|
+
return this.stores.users.findById(id);
|
|
68
|
+
}
|
|
69
|
+
findUserByEmail(email) {
|
|
70
|
+
return this.stores.users.findByEmailNorm(normalizeEmail(email));
|
|
71
|
+
}
|
|
72
|
+
listUsers() {
|
|
73
|
+
return this.stores.users.listUsers();
|
|
74
|
+
}
|
|
75
|
+
async setRoles(userId, roles) {
|
|
76
|
+
const updated = await this.casUpdateUser(userId, { roles });
|
|
77
|
+
// Privilege change: existing sessions carry the old privilege — end them.
|
|
78
|
+
await this.revokeAllForUser(userId);
|
|
79
|
+
return updated;
|
|
80
|
+
}
|
|
81
|
+
async setDisabled(userId, disabled) {
|
|
82
|
+
const updated = await this.casUpdateUser(userId, { disabled });
|
|
83
|
+
if (disabled)
|
|
84
|
+
await this.revokeAllForUser(userId);
|
|
85
|
+
return updated;
|
|
86
|
+
}
|
|
87
|
+
/** Read-modify-write with CAS retry under the per-user mutex. */
|
|
88
|
+
casUpdateUser(userId, patch) {
|
|
89
|
+
return this.mutex.run(`user:${userId}`, async () => {
|
|
90
|
+
for (let attempt = 0; attempt < 5; attempt++) {
|
|
91
|
+
const current = await this.stores.users.findById(userId);
|
|
92
|
+
if (!current)
|
|
93
|
+
throw new Error(`user "${userId}" not found`);
|
|
94
|
+
const next = await this.stores.users.updateUser(userId, current.version, patch);
|
|
95
|
+
if (next)
|
|
96
|
+
return next;
|
|
97
|
+
}
|
|
98
|
+
throw new Error(`user "${userId}": CAS update kept losing — concurrent writer storm?`);
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
/* ── sessions ────────────────────────────────────────────────────────── */
|
|
102
|
+
async mintSession(userId, meta = {}) {
|
|
103
|
+
const token = randomToken();
|
|
104
|
+
const now = Date.now();
|
|
105
|
+
const row = await this.stores.sessions.create({
|
|
106
|
+
id: crypto.randomUUID(),
|
|
107
|
+
tokenHash: sha256hex(token),
|
|
108
|
+
userId,
|
|
109
|
+
createdAt: now,
|
|
110
|
+
lastSeenAt: now,
|
|
111
|
+
expiresAt: now + this.options.sessionTtlMs,
|
|
112
|
+
revokedAt: null,
|
|
113
|
+
userAgent: meta.userAgent ?? null,
|
|
114
|
+
ip: meta.ip ?? null,
|
|
115
|
+
});
|
|
116
|
+
return { sessionId: row.id, token, expiresAt: row.expiresAt };
|
|
117
|
+
}
|
|
118
|
+
async resolveSessionByToken(rawToken, now = Date.now()) {
|
|
119
|
+
const session = await this.stores.sessions.findByTokenHash(sha256hex(rawToken));
|
|
120
|
+
if (!session || session.revokedAt != null || session.expiresAt <= now)
|
|
121
|
+
return null;
|
|
122
|
+
const user = await this.stores.users.findById(session.userId);
|
|
123
|
+
if (!user || user.disabled)
|
|
124
|
+
return null;
|
|
125
|
+
// Sliding expiry, throttled so hot sessions don't write per request. A
|
|
126
|
+
// lost CAS just means another request already touched — the read above
|
|
127
|
+
// was fresh either way.
|
|
128
|
+
if (now - session.lastSeenAt >= this.options.touchThrottleMs) {
|
|
129
|
+
await this.stores.sessions.touch(session.id, session.version, now, now + this.options.sessionTtlMs);
|
|
130
|
+
}
|
|
131
|
+
return { session, user, scopes: this.scopesForRoles(user.roles) };
|
|
132
|
+
}
|
|
133
|
+
async revokeSession(sessionId) {
|
|
134
|
+
await this.stores.sessions.revoke(sessionId, Date.now());
|
|
135
|
+
await this.closeSessionSockets(sessionId);
|
|
136
|
+
}
|
|
137
|
+
async revokeAllForUser(userId) {
|
|
138
|
+
const ids = await this.stores.sessions.revokeAllForUser(userId, Date.now());
|
|
139
|
+
for (const id of ids)
|
|
140
|
+
await this.closeSessionSockets(id);
|
|
141
|
+
}
|
|
142
|
+
async closeSessionSockets(sessionId) {
|
|
143
|
+
if (canCloseRooms(this.connections)) {
|
|
144
|
+
await this.connections.closeRoom(`session:${sessionId}`, 4001, "session revoked").catch(() => { });
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
listSessions(userId) {
|
|
148
|
+
return userId ? this.stores.sessions.listForUser(userId) : this.stores.sessions.listAll();
|
|
149
|
+
}
|
|
150
|
+
/* ── token kernel ────────────────────────────────────────────────────── */
|
|
151
|
+
async issueToken(input) {
|
|
152
|
+
const token = randomToken();
|
|
153
|
+
const now = Date.now();
|
|
154
|
+
const row = await this.stores.tokens.create({
|
|
155
|
+
id: crypto.randomUUID(),
|
|
156
|
+
tokenHash: sha256hex(token),
|
|
157
|
+
purpose: input.purpose,
|
|
158
|
+
emailNorm: input.email ? normalizeEmail(input.email) : null,
|
|
159
|
+
data: input.data ?? null,
|
|
160
|
+
createdAt: now,
|
|
161
|
+
expiresAt: now + (input.ttlMs ?? this.options.tokenTtlMs),
|
|
162
|
+
consumedAt: null,
|
|
163
|
+
});
|
|
164
|
+
const next = typeof input.data?.next === "string" ? input.data.next : undefined;
|
|
165
|
+
const path = `${this.options.mount}/token?t=${token}${next ? `&next=${encodeURIComponent(next)}` : ""}`;
|
|
166
|
+
// Opportunistic sweep: issuing is rare enough to piggyback cleanup on.
|
|
167
|
+
await this.stores.tokens.deleteExpired(now).catch(() => { });
|
|
168
|
+
return { token, path, expiresAt: row.expiresAt };
|
|
169
|
+
}
|
|
170
|
+
async consumeToken(rawToken, purpose) {
|
|
171
|
+
const found = await this.stores.tokens.findByTokenHash(sha256hex(rawToken));
|
|
172
|
+
if (!found)
|
|
173
|
+
return null;
|
|
174
|
+
if (purpose && found.purpose !== purpose)
|
|
175
|
+
return null;
|
|
176
|
+
if (found.expiresAt <= Date.now())
|
|
177
|
+
return null;
|
|
178
|
+
return this.mutex.run(`token:${found.id}`, () => this.stores.tokens.consume(found.id, found.version, Date.now()));
|
|
179
|
+
}
|
|
180
|
+
/* ── login methods ───────────────────────────────────────────────────── */
|
|
181
|
+
registerLoginMethod(method) {
|
|
182
|
+
this.methods.set(method.id, method);
|
|
183
|
+
}
|
|
184
|
+
loginMethods() {
|
|
185
|
+
return [...this.methods.values()];
|
|
186
|
+
}
|
|
187
|
+
/* ── roles → scopes ──────────────────────────────────────────────────── */
|
|
188
|
+
scopesForRoles(roles) {
|
|
189
|
+
const out = new Set();
|
|
190
|
+
for (const role of roles)
|
|
191
|
+
for (const scope of this.options.roles[role] ?? [])
|
|
192
|
+
out.add(scope);
|
|
193
|
+
return [...out];
|
|
194
|
+
}
|
|
195
|
+
/* ── runtime settings ────────────────────────────────────────────────── */
|
|
196
|
+
// Read-through on purpose (no cache): a settings read is one indexed hit,
|
|
197
|
+
// and it keeps multiple instances honest without invalidation machinery.
|
|
198
|
+
async getSignup() {
|
|
199
|
+
const stored = await this.stores.settings.get("signup");
|
|
200
|
+
return stored === "open" || stored === "invite" ? stored : this.options.signup;
|
|
201
|
+
}
|
|
202
|
+
async setSignup(mode) {
|
|
203
|
+
if (mode !== "open" && mode !== "invite")
|
|
204
|
+
throw new Error(`invalid signup mode "${mode}"`);
|
|
205
|
+
await this.stores.settings.set("signup", mode);
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
//# sourceMappingURL=service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"service.js","sourceRoot":"","sources":["../src/service.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @pattern/mod-identity — in-memory store driver.
|
|
3
|
+
*
|
|
4
|
+
* Same contracts (including CAS semantics and the unique-email violation) as
|
|
5
|
+
* the sqlite driver, so tests exercise the exact race paths production hits.
|
|
6
|
+
* Also the fallback for Node builds without `node:sqlite`.
|
|
7
|
+
*/
|
|
8
|
+
import { type IdentityStores } from "./types.js";
|
|
9
|
+
/** In-memory identity stores (tests; Node builds without node:sqlite). */
|
|
10
|
+
export declare function memoryIdentityStores(): IdentityStores;
|
|
11
|
+
//# sourceMappingURL=memory.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"memory.d.ts","sourceRoot":"","sources":["../../src/store/memory.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAGL,KAAK,cAAc,EAOpB,MAAM,YAAY,CAAC;AAuNpB,0EAA0E;AAC1E,wBAAgB,oBAAoB,IAAI,cAAc,CAQrD"}
|
|
Binary file
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"memory.js","sourceRoot":"","sources":["../../src/store/memory.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @pattern-js/mod-identity — schema migrations.
|
|
3
|
+
*
|
|
4
|
+
* Hand-written SQL, versioned by position in the array; `runMigrations`
|
|
5
|
+
* applies anything past the recorded version inside a transaction. No
|
|
6
|
+
* tooling, no down-migrations — append-only, like the rest of the store.
|
|
7
|
+
*/
|
|
8
|
+
/** Minimal slice of node:sqlite's DatabaseSync this module needs. */
|
|
9
|
+
export interface SqlDatabase {
|
|
10
|
+
exec(sql: string): void;
|
|
11
|
+
prepare(sql: string): {
|
|
12
|
+
run(...params: unknown[]): {
|
|
13
|
+
changes: number | bigint;
|
|
14
|
+
};
|
|
15
|
+
get(...params: unknown[]): unknown;
|
|
16
|
+
all(...params: unknown[]): unknown[];
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
export declare const MIGRATIONS: string[];
|
|
20
|
+
export declare function runMigrations(db: SqlDatabase): void;
|
|
21
|
+
//# sourceMappingURL=migrations.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"migrations.d.ts","sourceRoot":"","sources":["../../src/store/migrations.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,qEAAqE;AACrE,MAAM,WAAW,WAAW;IAC1B,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG;QACpB,GAAG,CAAC,GAAG,MAAM,EAAE,OAAO,EAAE,GAAG;YAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAAA;SAAE,CAAC;QACxD,GAAG,CAAC,GAAG,MAAM,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC;QACnC,GAAG,CAAC,GAAG,MAAM,EAAE,OAAO,EAAE,GAAG,OAAO,EAAE,CAAC;KACtC,CAAC;CACH;AAED,eAAO,MAAM,UAAU,EAAE,MAAM,EA2D9B,CAAC;AAEF,wBAAgB,aAAa,CAAC,EAAE,EAAE,WAAW,GAAG,IAAI,CAoBnD"}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @pattern-js/mod-identity — schema migrations.
|
|
3
|
+
*
|
|
4
|
+
* Hand-written SQL, versioned by position in the array; `runMigrations`
|
|
5
|
+
* applies anything past the recorded version inside a transaction. No
|
|
6
|
+
* tooling, no down-migrations — append-only, like the rest of the store.
|
|
7
|
+
*/
|
|
8
|
+
export const MIGRATIONS = [
|
|
9
|
+
// v1 — identity core: users, provider identities, sessions, single-use tokens.
|
|
10
|
+
`
|
|
11
|
+
CREATE TABLE IF NOT EXISTS users (
|
|
12
|
+
id TEXT PRIMARY KEY,
|
|
13
|
+
email TEXT NOT NULL,
|
|
14
|
+
email_norm TEXT NOT NULL UNIQUE,
|
|
15
|
+
name TEXT,
|
|
16
|
+
roles TEXT NOT NULL DEFAULT '[]',
|
|
17
|
+
disabled INTEGER NOT NULL DEFAULT 0,
|
|
18
|
+
version INTEGER NOT NULL DEFAULT 1,
|
|
19
|
+
created_at INTEGER NOT NULL,
|
|
20
|
+
updated_at INTEGER NOT NULL
|
|
21
|
+
);
|
|
22
|
+
|
|
23
|
+
CREATE TABLE IF NOT EXISTS identities (
|
|
24
|
+
provider TEXT NOT NULL,
|
|
25
|
+
subject TEXT NOT NULL,
|
|
26
|
+
user_id TEXT NOT NULL REFERENCES users(id),
|
|
27
|
+
created_at INTEGER NOT NULL,
|
|
28
|
+
PRIMARY KEY (provider, subject)
|
|
29
|
+
);
|
|
30
|
+
CREATE INDEX IF NOT EXISTS idx_identities_user ON identities(user_id);
|
|
31
|
+
|
|
32
|
+
CREATE TABLE IF NOT EXISTS sessions (
|
|
33
|
+
id TEXT PRIMARY KEY,
|
|
34
|
+
token_hash TEXT NOT NULL UNIQUE,
|
|
35
|
+
user_id TEXT NOT NULL REFERENCES users(id),
|
|
36
|
+
created_at INTEGER NOT NULL,
|
|
37
|
+
last_seen_at INTEGER NOT NULL,
|
|
38
|
+
expires_at INTEGER NOT NULL,
|
|
39
|
+
revoked_at INTEGER,
|
|
40
|
+
version INTEGER NOT NULL DEFAULT 1,
|
|
41
|
+
user_agent TEXT,
|
|
42
|
+
ip TEXT
|
|
43
|
+
);
|
|
44
|
+
CREATE INDEX IF NOT EXISTS idx_sessions_user ON sessions(user_id);
|
|
45
|
+
|
|
46
|
+
CREATE TABLE IF NOT EXISTS tokens (
|
|
47
|
+
id TEXT PRIMARY KEY,
|
|
48
|
+
token_hash TEXT NOT NULL UNIQUE,
|
|
49
|
+
purpose TEXT NOT NULL,
|
|
50
|
+
email_norm TEXT,
|
|
51
|
+
data TEXT,
|
|
52
|
+
created_at INTEGER NOT NULL,
|
|
53
|
+
expires_at INTEGER NOT NULL,
|
|
54
|
+
consumed_at INTEGER,
|
|
55
|
+
version INTEGER NOT NULL DEFAULT 1
|
|
56
|
+
);
|
|
57
|
+
CREATE INDEX IF NOT EXISTS idx_tokens_purpose ON tokens(purpose);
|
|
58
|
+
`,
|
|
59
|
+
// v2 — runtime-mutable settings (signup policy toggled from the admin).
|
|
60
|
+
`
|
|
61
|
+
CREATE TABLE IF NOT EXISTS settings (
|
|
62
|
+
key TEXT PRIMARY KEY,
|
|
63
|
+
value TEXT NOT NULL
|
|
64
|
+
);
|
|
65
|
+
`,
|
|
66
|
+
];
|
|
67
|
+
export function runMigrations(db) {
|
|
68
|
+
db.exec(`CREATE TABLE IF NOT EXISTS _identity_migrations (
|
|
69
|
+
version INTEGER PRIMARY KEY,
|
|
70
|
+
applied_at INTEGER NOT NULL
|
|
71
|
+
)`);
|
|
72
|
+
const row = db.prepare("SELECT MAX(version) AS v FROM _identity_migrations").get();
|
|
73
|
+
const current = row?.v ?? 0;
|
|
74
|
+
for (let i = current; i < MIGRATIONS.length; i++) {
|
|
75
|
+
db.exec("BEGIN");
|
|
76
|
+
try {
|
|
77
|
+
db.exec(MIGRATIONS[i]);
|
|
78
|
+
db.prepare("INSERT INTO _identity_migrations (version, applied_at) VALUES (?, ?)").run(i + 1, Date.now());
|
|
79
|
+
db.exec("COMMIT");
|
|
80
|
+
}
|
|
81
|
+
catch (err) {
|
|
82
|
+
db.exec("ROLLBACK");
|
|
83
|
+
throw err;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
//# sourceMappingURL=migrations.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"migrations.js","sourceRoot":"","sources":["../../src/store/migrations.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAYH,MAAM,CAAC,MAAM,UAAU,GAAa;IAClC,+EAA+E;IAC/E;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgDC;IAED,wEAAwE;IACxE;;;;;GAKC;CACF,CAAC;AAEF,MAAM,UAAU,aAAa,CAAC,EAAe;IAC3C,EAAE,CAAC,IAAI,CAAC;;;IAGN,CAAC,CAAC;IACJ,MAAM,GAAG,GAAG,EAAE,CAAC,OAAO,CAAC,oDAAoD,CAAC,CAAC,GAAG,EAEnE,CAAC;IACd,MAAM,OAAO,GAAG,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC;IAC5B,KAAK,IAAI,CAAC,GAAG,OAAO,EAAE,CAAC,GAAG,UAAU,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACjD,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACjB,IAAI,CAAC;YACH,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAE,CAAC,CAAC;YACxB,EAAE,CAAC,OAAO,CAAC,sEAAsE,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC;YAC1G,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACpB,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;YACpB,MAAM,GAAG,CAAC;QACZ,CAAC;IACH,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @pattern-js/mod-identity — keyed in-process mutex.
|
|
3
|
+
*
|
|
4
|
+
* Serializes read-modify-write cycles per key (session id, user id) so a
|
|
5
|
+
* single instance doesn't burn CAS retries against itself. Same promise-chain
|
|
6
|
+
* pattern as the admin store's per-slug locks. Multi-instance correctness is
|
|
7
|
+
* the store's CAS clause, not this.
|
|
8
|
+
*/
|
|
9
|
+
export declare class KeyedMutex {
|
|
10
|
+
private locks;
|
|
11
|
+
run<T>(key: string, fn: () => Promise<T>): Promise<T>;
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=mutex.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mutex.d.ts","sourceRoot":"","sources":["../../src/store/mutex.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,qBAAa,UAAU;IACrB,OAAO,CAAC,KAAK,CAAoC;IAE3C,GAAG,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;CAc5D"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @pattern-js/mod-identity — keyed in-process mutex.
|
|
3
|
+
*
|
|
4
|
+
* Serializes read-modify-write cycles per key (session id, user id) so a
|
|
5
|
+
* single instance doesn't burn CAS retries against itself. Same promise-chain
|
|
6
|
+
* pattern as the admin store's per-slug locks. Multi-instance correctness is
|
|
7
|
+
* the store's CAS clause, not this.
|
|
8
|
+
*/
|
|
9
|
+
export class KeyedMutex {
|
|
10
|
+
locks = new Map();
|
|
11
|
+
async run(key, fn) {
|
|
12
|
+
const prev = this.locks.get(key) ?? Promise.resolve();
|
|
13
|
+
let release;
|
|
14
|
+
const current = new Promise((r) => (release = r));
|
|
15
|
+
this.locks.set(key, current);
|
|
16
|
+
await prev;
|
|
17
|
+
try {
|
|
18
|
+
return await fn();
|
|
19
|
+
}
|
|
20
|
+
finally {
|
|
21
|
+
release();
|
|
22
|
+
// Drop the entry once no later caller has replaced it.
|
|
23
|
+
if (this.locks.get(key) === current)
|
|
24
|
+
this.locks.delete(key);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=mutex.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mutex.js","sourceRoot":"","sources":["../../src/store/mutex.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,MAAM,OAAO,UAAU;IACb,KAAK,GAAG,IAAI,GAAG,EAAyB,CAAC;IAEjD,KAAK,CAAC,GAAG,CAAI,GAAW,EAAE,EAAoB;QAC5C,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;QACtD,IAAI,OAAoB,CAAC;QACzB,MAAM,OAAO,GAAG,IAAI,OAAO,CAAO,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,OAAO,GAAG,CAAC,CAAC,CAAC,CAAC;QACxD,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;QAC7B,MAAM,IAAI,CAAC;QACX,IAAI,CAAC;YACH,OAAO,MAAM,EAAE,EAAE,CAAC;QACpB,CAAC;gBAAS,CAAC;YACT,OAAO,EAAE,CAAC;YACV,uDAAuD;YACvD,IAAI,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,OAAO;gBAAE,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QAC9D,CAAC;IACH,CAAC;CACF"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @pattern-js/mod-identity — node:sqlite store driver.
|
|
3
|
+
*
|
|
4
|
+
* Hand-written SQL, no ORM (decided): the schema is five boring tables and the
|
|
5
|
+
* security-critical statements should read as literal SQL. CAS is a single
|
|
6
|
+
* conditional UPDATE — `WHERE id=? AND version=?` (+ `consumed_at IS NULL` for
|
|
7
|
+
* tokens), checked via `changes === 1` — which is atomic in SQLite and ports
|
|
8
|
+
* verbatim to Postgres, so a future driver is a file, not a redesign.
|
|
9
|
+
*
|
|
10
|
+
* `node:sqlite` is imported dynamically with a helpful error (same pattern as
|
|
11
|
+
* runtime-node's sqlite trace sink); the in-memory store covers builds
|
|
12
|
+
* without it.
|
|
13
|
+
*/
|
|
14
|
+
import { type IdentityStores } from "./types.js";
|
|
15
|
+
/**
|
|
16
|
+
* Open (or create) the identity database at `filePath` (":memory:" works too).
|
|
17
|
+
* Throws a helpful error when this Node build lacks `node:sqlite`.
|
|
18
|
+
*/
|
|
19
|
+
export declare function sqliteIdentityStores(filePath: string): Promise<IdentityStores>;
|
|
20
|
+
//# sourceMappingURL=sqlite.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sqlite.d.ts","sourceRoot":"","sources":["../../src/store/sqlite.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAIH,OAAO,EAEL,KAAK,cAAc,EAOpB,MAAM,YAAY,CAAC;AA6QpB;;;GAGG;AACH,wBAAsB,oBAAoB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC,CA4BpF"}
|