@betterportal/auth-default 10.6.20 → 10.6.22

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (128) hide show
  1. package/README.md +140 -10
  2. package/bsb-plugin.json +1 -1
  3. package/lib/account.d.ts +16 -0
  4. package/lib/account.d.ts.map +1 -0
  5. package/lib/account.js +274 -0
  6. package/lib/account.js.map +1 -0
  7. package/lib/accountUI.d.ts +5 -0
  8. package/lib/accountUI.d.ts.map +1 -0
  9. package/lib/accountUI.js +68 -0
  10. package/lib/accountUI.js.map +1 -0
  11. package/lib/bp-contracts/org.betterportal.auth.default.json +2031 -707
  12. package/lib/clientAddress.d.ts +10 -0
  13. package/lib/clientAddress.d.ts.map +1 -0
  14. package/lib/clientAddress.js +35 -0
  15. package/lib/clientAddress.js.map +1 -0
  16. package/lib/config.d.ts +3 -0
  17. package/lib/config.d.ts.map +1 -0
  18. package/lib/config.js +28 -0
  19. package/lib/config.js.map +1 -0
  20. package/lib/defaultAuthManifest.d.ts +7 -0
  21. package/lib/defaultAuthManifest.d.ts.map +1 -1
  22. package/lib/factors.d.ts +18 -0
  23. package/lib/factors.d.ts.map +1 -0
  24. package/lib/factors.js +95 -0
  25. package/lib/factors.js.map +1 -0
  26. package/lib/identity.d.ts +106 -0
  27. package/lib/identity.d.ts.map +1 -0
  28. package/lib/identity.js +315 -0
  29. package/lib/identity.js.map +1 -0
  30. package/lib/index.d.ts +4 -0
  31. package/lib/index.d.ts.map +1 -1
  32. package/lib/index.js +4 -0
  33. package/lib/index.js.map +1 -1
  34. package/lib/mail.d.ts +19 -0
  35. package/lib/mail.d.ts.map +1 -0
  36. package/lib/mail.js +102 -0
  37. package/lib/mail.js.map +1 -0
  38. package/lib/plugins/service-betterportal-auth-default/.bp-generated/registry.d.ts +435 -11
  39. package/lib/plugins/service-betterportal-auth-default/.bp-generated/registry.d.ts.map +1 -1
  40. package/lib/plugins/service-betterportal-auth-default/.bp-generated/registry.js +85 -0
  41. package/lib/plugins/service-betterportal-auth-default/.bp-generated/registry.js.map +1 -1
  42. package/lib/plugins/service-betterportal-auth-default/bp-routes/account/GET.d.ts +34 -0
  43. package/lib/plugins/service-betterportal-auth-default/bp-routes/account/GET.d.ts.map +1 -0
  44. package/lib/plugins/service-betterportal-auth-default/bp-routes/account/GET.js +25 -0
  45. package/lib/plugins/service-betterportal-auth-default/bp-routes/account/GET.js.map +1 -0
  46. package/lib/plugins/service-betterportal-auth-default/bp-routes/account/POST.d.ts +42 -0
  47. package/lib/plugins/service-betterportal-auth-default/bp-routes/account/POST.d.ts.map +1 -0
  48. package/lib/plugins/service-betterportal-auth-default/bp-routes/account/POST.js +27 -0
  49. package/lib/plugins/service-betterportal-auth-default/bp-routes/account/POST.js.map +1 -0
  50. package/lib/plugins/service-betterportal-auth-default/bp-routes/account/_renderer.bootstrap5/GET.d.ts +2 -0
  51. package/lib/plugins/service-betterportal-auth-default/bp-routes/account/_renderer.bootstrap5/GET.d.ts.map +1 -0
  52. package/lib/plugins/service-betterportal-auth-default/bp-routes/account/_renderer.bootstrap5/GET.js +2 -0
  53. package/lib/plugins/service-betterportal-auth-default/bp-routes/account/_renderer.bootstrap5/GET.js.map +1 -0
  54. package/lib/plugins/service-betterportal-auth-default/bp-routes/account/_renderer.bootstrap5/POST.d.ts +2 -0
  55. package/lib/plugins/service-betterportal-auth-default/bp-routes/account/_renderer.bootstrap5/POST.d.ts.map +1 -0
  56. package/lib/plugins/service-betterportal-auth-default/bp-routes/account/_renderer.bootstrap5/POST.js +2 -0
  57. package/lib/plugins/service-betterportal-auth-default/bp-routes/account/_renderer.bootstrap5/POST.js.map +1 -0
  58. package/lib/plugins/service-betterportal-auth-default/bp-routes/account/index.d.ts +3 -0
  59. package/lib/plugins/service-betterportal-auth-default/bp-routes/account/index.d.ts.map +1 -0
  60. package/lib/plugins/service-betterportal-auth-default/bp-routes/account/index.js +3 -0
  61. package/lib/plugins/service-betterportal-auth-default/bp-routes/account/index.js.map +1 -0
  62. package/lib/plugins/service-betterportal-auth-default/bp-routes/login/_renderer.bootstrap5/GET.d.ts.map +1 -1
  63. package/lib/plugins/service-betterportal-auth-default/bp-routes/login/_renderer.bootstrap5/GET.js +11 -8
  64. package/lib/plugins/service-betterportal-auth-default/bp-routes/login/_renderer.bootstrap5/GET.js.map +1 -1
  65. package/lib/plugins/service-betterportal-auth-default/bp-routes/refresh/POST.d.ts +3 -1
  66. package/lib/plugins/service-betterportal-auth-default/bp-routes/refresh/POST.d.ts.map +1 -1
  67. package/lib/plugins/service-betterportal-auth-default/bp-routes/refresh/POST.js +10 -23
  68. package/lib/plugins/service-betterportal-auth-default/bp-routes/refresh/POST.js.map +1 -1
  69. package/lib/plugins/service-betterportal-auth-default/bp-routes/register/_renderer.bootstrap5/GET.d.ts.map +1 -1
  70. package/lib/plugins/service-betterportal-auth-default/bp-routes/register/_renderer.bootstrap5/GET.js +2 -2
  71. package/lib/plugins/service-betterportal-auth-default/bp-routes/register/_renderer.bootstrap5/GET.js.map +1 -1
  72. package/lib/plugins/service-betterportal-auth-default/bp-routes/social/GET.d.ts +34 -0
  73. package/lib/plugins/service-betterportal-auth-default/bp-routes/social/GET.d.ts.map +1 -0
  74. package/lib/plugins/service-betterportal-auth-default/bp-routes/social/GET.js +26 -0
  75. package/lib/plugins/service-betterportal-auth-default/bp-routes/social/GET.js.map +1 -0
  76. package/lib/plugins/service-betterportal-auth-default/bp-routes/social/POST.d.ts +31 -0
  77. package/lib/plugins/service-betterportal-auth-default/bp-routes/social/POST.d.ts.map +1 -0
  78. package/lib/plugins/service-betterportal-auth-default/bp-routes/social/POST.js +23 -0
  79. package/lib/plugins/service-betterportal-auth-default/bp-routes/social/POST.js.map +1 -0
  80. package/lib/plugins/service-betterportal-auth-default/bp-routes/social/_renderer.bootstrap5/GET.d.ts +3 -0
  81. package/lib/plugins/service-betterportal-auth-default/bp-routes/social/_renderer.bootstrap5/GET.d.ts.map +1 -0
  82. package/lib/plugins/service-betterportal-auth-default/bp-routes/social/_renderer.bootstrap5/GET.js +36 -0
  83. package/lib/plugins/service-betterportal-auth-default/bp-routes/social/_renderer.bootstrap5/GET.js.map +1 -0
  84. package/lib/plugins/service-betterportal-auth-default/bp-routes/social/index.d.ts +3 -0
  85. package/lib/plugins/service-betterportal-auth-default/bp-routes/social/index.d.ts.map +1 -0
  86. package/lib/plugins/service-betterportal-auth-default/bp-routes/social/index.js +3 -0
  87. package/lib/plugins/service-betterportal-auth-default/bp-routes/social/index.js.map +1 -0
  88. package/lib/plugins/service-betterportal-auth-default/bp-routes/users/GET.d.ts +32 -0
  89. package/lib/plugins/service-betterportal-auth-default/bp-routes/users/GET.d.ts.map +1 -0
  90. package/lib/plugins/service-betterportal-auth-default/bp-routes/users/GET.js +39 -0
  91. package/lib/plugins/service-betterportal-auth-default/bp-routes/users/GET.js.map +1 -0
  92. package/lib/plugins/service-betterportal-auth-default/bp-routes/users/POST.d.ts +41 -0
  93. package/lib/plugins/service-betterportal-auth-default/bp-routes/users/POST.d.ts.map +1 -0
  94. package/lib/plugins/service-betterportal-auth-default/bp-routes/users/POST.js +103 -0
  95. package/lib/plugins/service-betterportal-auth-default/bp-routes/users/POST.js.map +1 -0
  96. package/lib/plugins/service-betterportal-auth-default/bp-routes/users/_renderer.bootstrap5/GET.d.ts +3 -0
  97. package/lib/plugins/service-betterportal-auth-default/bp-routes/users/_renderer.bootstrap5/GET.d.ts.map +1 -0
  98. package/lib/plugins/service-betterportal-auth-default/bp-routes/users/_renderer.bootstrap5/GET.js +19 -0
  99. package/lib/plugins/service-betterportal-auth-default/bp-routes/users/_renderer.bootstrap5/GET.js.map +1 -0
  100. package/lib/plugins/service-betterportal-auth-default/bp-routes/users/index.d.ts +3 -0
  101. package/lib/plugins/service-betterportal-auth-default/bp-routes/users/index.d.ts.map +1 -0
  102. package/lib/plugins/service-betterportal-auth-default/bp-routes/users/index.js +3 -0
  103. package/lib/plugins/service-betterportal-auth-default/bp-routes/users/index.js.map +1 -0
  104. package/lib/plugins/service-betterportal-auth-default/index.d.ts +41 -4
  105. package/lib/plugins/service-betterportal-auth-default/index.d.ts.map +1 -1
  106. package/lib/plugins/service-betterportal-auth-default/index.js +205 -9
  107. package/lib/plugins/service-betterportal-auth-default/index.js.map +1 -1
  108. package/lib/plugins/service-betterportal-auth-default/loginFlow.d.ts +17 -2
  109. package/lib/plugins/service-betterportal-auth-default/loginFlow.d.ts.map +1 -1
  110. package/lib/plugins/service-betterportal-auth-default/loginFlow.js +83 -62
  111. package/lib/plugins/service-betterportal-auth-default/loginFlow.js.map +1 -1
  112. package/lib/plugins/service-betterportal-auth-default/logoutFlow.js +1 -1
  113. package/lib/plugins/service-betterportal-auth-default/logoutFlow.js.map +1 -1
  114. package/lib/plugins/service-betterportal-auth-default/registrationFlow.d.ts +4 -2
  115. package/lib/plugins/service-betterportal-auth-default/registrationFlow.d.ts.map +1 -1
  116. package/lib/plugins/service-betterportal-auth-default/registrationFlow.js +15 -17
  117. package/lib/plugins/service-betterportal-auth-default/registrationFlow.js.map +1 -1
  118. package/lib/schemas/service-betterportal-auth-default.json +26 -2
  119. package/lib/schemas/service-betterportal-auth-default.plugin.json +27 -3
  120. package/lib/social.d.ts +40 -0
  121. package/lib/social.d.ts.map +1 -0
  122. package/lib/social.js +178 -0
  123. package/lib/social.js.map +1 -0
  124. package/lib/storage.d.ts +72 -0
  125. package/lib/storage.d.ts.map +1 -0
  126. package/lib/storage.js +427 -0
  127. package/lib/storage.js.map +1 -0
  128. package/package.json +14 -7
package/lib/storage.js ADDED
@@ -0,0 +1,427 @@
1
+ import { createHash, randomUUID } from "node:crypto";
2
+ import { existsSync, mkdirSync, readFileSync, renameSync, unlinkSync, writeFileSync, openSync, closeSync, fsyncSync } from "node:fs";
3
+ import { hostname } from "node:os";
4
+ import { dirname, resolve } from "node:path";
5
+ import { isDeepStrictEqual } from "node:util";
6
+ import { Pool } from "pg";
7
+ const key = (kind, id, scope) => JSON.stringify([scope.tenantId, scope.appId, kind, id]);
8
+ const sameScope = (a, b) => a.tenantId === b.tenantId && a.appId === b.appId;
9
+ /** Atomic replace includes a directory fsync so a completed write survives restart. */
10
+ export function atomicWrite(path, data) {
11
+ mkdirSync(dirname(path), { recursive: true });
12
+ const temp = `${path}.${randomUUID()}.tmp`;
13
+ const fd = openSync(temp, "wx", 0o600);
14
+ try {
15
+ writeFileSync(fd, JSON.stringify(data));
16
+ fsyncSync(fd);
17
+ }
18
+ finally {
19
+ closeSync(fd);
20
+ }
21
+ renameSync(temp, path);
22
+ const dir = openSync(dirname(path), "r");
23
+ try {
24
+ fsyncSync(dir);
25
+ }
26
+ finally {
27
+ closeSync(dir);
28
+ }
29
+ }
30
+ function validateRecords(data) {
31
+ if (!data || typeof data !== "object")
32
+ throw new Error("Invalid auth store");
33
+ const file = data;
34
+ if (file.version !== 2 || !Array.isArray(file.records))
35
+ throw new Error("Unsupported auth store version");
36
+ const seen = new Set();
37
+ for (const row of file.records) {
38
+ if (!row || typeof row.kind !== "string" || !row.scope || typeof row.scope.tenantId !== "string"
39
+ || typeof row.scope.appId !== "string" || !row.value || typeof row.value.id !== "string")
40
+ throw new Error("Malformed auth record");
41
+ const id = key(row.kind, row.value.id, row.scope);
42
+ if (seen.has(id))
43
+ throw new Error("Duplicate auth record");
44
+ seen.add(id);
45
+ }
46
+ return file;
47
+ }
48
+ /** Only a demonstrably dead writer on this host may be recovered automatically. */
49
+ function lockFile(path) {
50
+ mkdirSync(dirname(path), { recursive: true });
51
+ const lock = `${path}.lock`;
52
+ const processStart = (pid) => {
53
+ try {
54
+ return readFileSync(`/proc/${pid}/stat`, "utf8").split(") ")[1].split(" ")[19];
55
+ }
56
+ catch {
57
+ return undefined;
58
+ }
59
+ };
60
+ const owner = JSON.stringify({ pid: process.pid, host: hostname(), start: processStart(process.pid), nonce: randomUUID() });
61
+ const acquire = () => {
62
+ const fd = openSync(lock, "wx", 0o600);
63
+ try {
64
+ writeFileSync(fd, owner);
65
+ fsyncSync(fd);
66
+ }
67
+ finally {
68
+ closeSync(fd);
69
+ }
70
+ };
71
+ try {
72
+ acquire();
73
+ }
74
+ catch (error) {
75
+ if (error.code !== "EEXIST")
76
+ throw error;
77
+ const recovery = `${lock}.recover`;
78
+ let recoveryFd;
79
+ try {
80
+ recoveryFd = openSync(recovery, "wx", 0o600);
81
+ }
82
+ catch {
83
+ throw new Error(`Auth lock recovery is already active; verify ownership of ${recovery}`);
84
+ }
85
+ try {
86
+ const previous = readFileSync(lock, "utf8");
87
+ let dead = false;
88
+ try {
89
+ const record = JSON.parse(previous);
90
+ if (record.host === hostname() && Number.isInteger(record.pid) && record.pid > 0) {
91
+ try {
92
+ process.kill(record.pid, 0);
93
+ }
94
+ catch (failure) {
95
+ dead = failure.code === "ESRCH";
96
+ }
97
+ const start = processStart(record.pid);
98
+ if (record.start && start && record.start !== start)
99
+ dead = true;
100
+ }
101
+ }
102
+ catch { /* Ambiguous ownership requires operator recovery. */ }
103
+ if (!dead || readFileSync(lock, "utf8") !== previous)
104
+ throw new Error(`Auth store already has an owner; verify the previous process stopped before removing ${lock}`, { cause: error });
105
+ unlinkSync(lock);
106
+ acquire(); // An intervening new owner wins; never steal its lock.
107
+ }
108
+ finally {
109
+ closeSync(recoveryFd);
110
+ unlinkSync(recovery);
111
+ }
112
+ }
113
+ return () => { if (existsSync(lock) && readFileSync(lock, "utf8") === owner)
114
+ unlinkSync(lock); };
115
+ }
116
+ export class JsonAuthStorage {
117
+ path;
118
+ mode = "simple";
119
+ data;
120
+ tail = Promise.resolve();
121
+ release;
122
+ closed = false;
123
+ closing = false;
124
+ constructor(path) {
125
+ this.path = path;
126
+ const marker = `${path}.mode.json`;
127
+ if (existsSync(marker))
128
+ throw new Error("This installation requires Advanced mode; Simple downgrade is unsupported");
129
+ this.release = lockFile(path);
130
+ try {
131
+ this.data = existsSync(path) ? validateRecords(JSON.parse(readFileSync(path, "utf8"))) : { version: 2, records: [] };
132
+ if (new Set(this.data.records.filter(r => r.kind === "user").map(r => r.scope.tenantId)).size > 1)
133
+ throw new Error("Simple auth supports one tenant; select Advanced mode");
134
+ }
135
+ catch (error) {
136
+ this.release();
137
+ throw error;
138
+ }
139
+ }
140
+ transaction(_scope, work) {
141
+ if (this.closing)
142
+ return Promise.reject(new Error("Auth store is closed"));
143
+ const run = this.tail.then(async () => {
144
+ if (this.closed)
145
+ throw new Error("Auth store is closed");
146
+ const draft = structuredClone(this.data);
147
+ let dirty = false;
148
+ const filteredPage = (kind, scope, predicate, options = {}) => structuredClone(draft.records
149
+ .filter(row => row.kind === kind && sameScope(row.scope, scope) && predicate(row.value)).map(row => row.value)
150
+ .filter(row => !options.after || (options.descending ? row.id < options.after : row.id > options.after))
151
+ .sort((a, b) => (a.id < b.id ? -1 : a.id > b.id ? 1 : 0) * (options.descending ? -1 : 1)).slice(0, Math.max(1, Math.min(501, options.limit ?? 100))));
152
+ const result = await work({
153
+ pruneSessions: async (scope, now) => {
154
+ const retained = draft.records.filter(row => row.kind !== "session" || !sameScope(row.scope, scope) || (row.value.revoked !== true && Number(row.value.expiresAt) > now));
155
+ if (retained.length !== draft.records.length) {
156
+ draft.records = retained;
157
+ dirty = true;
158
+ }
159
+ },
160
+ activeSessions: async (scope, userId, now, options) => filteredPage("session", scope, value => value.userId === userId && value.revoked === false && Number(value.expiresAt) > now, options),
161
+ failedMail: async (scope, options) => filteredPage("mail", scope, value => value.state === "failed", options),
162
+ get: async (kind, id, scope) => structuredClone(draft.records.find(row => key(row.kind, row.value.id, row.scope) === key(kind, id, scope))?.value),
163
+ list: async (kind, scope) => structuredClone(draft.records.filter(row => row.kind === kind && (!scope || sameScope(row.scope, scope))).map(row => row.value)),
164
+ dueMail: async (now, limit) => structuredClone(draft.records.filter(row => row.kind === "mail" && ["pending", "sending"].includes(String(row.value.state)) && Number(row.value.nextAttempt) <= now)
165
+ .sort((a, b) => Number(a.value.nextAttempt) - Number(b.value.nextAttempt) || a.value.id.localeCompare(b.value.id)).slice(0, Math.max(1, Math.min(100, limit))).map(row => row.value)),
166
+ page: async (kind, scope, options) => filteredPage(kind, scope, () => true, options),
167
+ put: async (kind, scope, value) => {
168
+ const i = draft.records.findIndex(row => key(row.kind, row.value.id, row.scope) === key(kind, value.id, scope));
169
+ const row = structuredClone({ kind, scope, value });
170
+ if (i < 0)
171
+ draft.records.push(row);
172
+ else
173
+ draft.records[i] = row;
174
+ dirty = true;
175
+ },
176
+ remove: async (kind, id, scope) => { draft.records = draft.records.filter(row => key(row.kind, row.value.id, row.scope) !== key(kind, id, scope)); dirty = true; }
177
+ });
178
+ if (dirty) {
179
+ atomicWrite(this.path, draft);
180
+ this.data = draft;
181
+ }
182
+ return result;
183
+ });
184
+ this.tail = run.catch(() => undefined);
185
+ return run;
186
+ }
187
+ async close() { this.closing = true; await this.tail; if (!this.closed) {
188
+ this.closed = true;
189
+ this.release();
190
+ } }
191
+ }
192
+ function pgTransaction(client, installationId) {
193
+ const filteredPage = async (scope, predicate, parameters, options = {}) => {
194
+ const comparison = options.descending ? "<" : ">";
195
+ const order = options.descending ? "DESC" : "ASC";
196
+ const values = [installationId, scope.tenantId, scope.appId, ...parameters];
197
+ values.push(options.after || null, Math.max(1, Math.min(501, options.limit ?? 100)));
198
+ const cursor = values.length - 1;
199
+ const result = await client.query(`SELECT value FROM bp_auth_records WHERE installation=$1 AND tenant=$2 AND app=$3 AND ${predicate} AND ($${cursor}::text IS NULL OR id ${comparison} $${cursor}) ORDER BY id ${order} LIMIT $${values.length}`, values);
200
+ return result.rows.map(row => row.value);
201
+ };
202
+ return {
203
+ pruneSessions: async (scope, now) => {
204
+ await client.query("DELETE FROM bp_auth_records WHERE installation=$1 AND tenant=$2 AND app=$3 AND kind='session' AND (value->>'expiresAt')::bigint <= $4", [installationId, scope.tenantId, scope.appId, now]);
205
+ await client.query("DELETE FROM bp_auth_records WHERE installation=$1 AND tenant=$2 AND app=$3 AND kind='session' AND value->>'revoked'='true'", [installationId, scope.tenantId, scope.appId]);
206
+ },
207
+ activeSessions: (scope, userId, now, options) => filteredPage(scope, "kind='session' AND value->>'userId'=$4 AND value->>'revoked'='false' AND (value->>'expiresAt')::bigint > $5", [userId, now], options),
208
+ failedMail: (scope, options) => filteredPage(scope, "kind='mail' AND value->>'state'='failed'", [], options),
209
+ get: async (kind, id, scope) => {
210
+ const r = await client.query("SELECT value FROM bp_auth_records WHERE installation=$1 AND tenant=$2 AND app=$3 AND kind=$4 AND id=$5", [installationId, scope.tenantId, scope.appId, kind, id]);
211
+ return r.rows[0]?.value;
212
+ },
213
+ list: async (kind, scope) => {
214
+ const r = scope
215
+ ? await client.query("SELECT value FROM bp_auth_records WHERE installation=$1 AND tenant=$2 AND app=$3 AND kind=$4 ORDER BY id", [installationId, scope.tenantId, scope.appId, kind])
216
+ : await client.query("SELECT value FROM bp_auth_records WHERE installation=$1 AND kind=$2 ORDER BY tenant,app,id", [installationId, kind]);
217
+ return r.rows.map(row => row.value);
218
+ },
219
+ page: async (kind, scope, options = {}) => {
220
+ const comparison = options.descending ? "<" : ">";
221
+ const order = options.descending ? "DESC" : "ASC";
222
+ const result = await client.query(`SELECT value FROM bp_auth_records WHERE installation=$1 AND tenant=$2 AND app=$3 AND kind=$4 AND ($5::text IS NULL OR id ${comparison} $5) ORDER BY id ${order} LIMIT $6`, [installationId, scope.tenantId, scope.appId, kind, options.after || null, Math.max(1, Math.min(501, options.limit ?? 100))]);
223
+ return result.rows.map(row => row.value);
224
+ },
225
+ dueMail: async (now, limit) => {
226
+ const result = await client.query("SELECT value FROM bp_auth_records WHERE installation=$1 AND kind='mail' AND value->>'state' IN ('pending','sending') AND (value->>'nextAttempt')::bigint <= $2 ORDER BY (value->>'nextAttempt')::bigint,id LIMIT $3", [installationId, now, Math.max(1, Math.min(100, limit))]);
227
+ return result.rows.map(row => row.value);
228
+ },
229
+ put: async (kind, scope, value) => {
230
+ await client.query("INSERT INTO bp_auth_records(installation,tenant,app,kind,id,value) VALUES($1,$2,$3,$4,$5,$6) ON CONFLICT(installation,tenant,app,kind,id) DO UPDATE SET value=EXCLUDED.value", [installationId, scope.tenantId, scope.appId, kind, value.id, value]);
231
+ },
232
+ remove: async (kind, id, scope) => { await client.query("DELETE FROM bp_auth_records WHERE installation=$1 AND tenant=$2 AND app=$3 AND kind=$4 AND id=$5", [installationId, scope.tenantId, scope.appId, kind, id]); }
233
+ };
234
+ }
235
+ export class PostgresAuthStorage {
236
+ installationId;
237
+ mode = "advanced";
238
+ pool;
239
+ constructor(connectionString, installationId) {
240
+ this.installationId = installationId;
241
+ if (!connectionString)
242
+ throw new Error("Advanced auth requires PostgreSQL");
243
+ this.pool = new Pool({ connectionString, max: 10, connectionTimeoutMillis: 10000, idleTimeoutMillis: 30000 });
244
+ }
245
+ async initialize() {
246
+ const client = await this.pool.connect();
247
+ try {
248
+ await client.query("BEGIN");
249
+ await client.query("SELECT pg_advisory_xact_lock(hashtextextended('betterportal-auth-schema',0))");
250
+ await client.query(`CREATE TABLE IF NOT EXISTS bp_auth_records (
251
+ installation text NOT NULL, tenant text NOT NULL, app text NOT NULL, kind text NOT NULL, id text NOT NULL,
252
+ value jsonb NOT NULL CHECK(jsonb_typeof(value)='object' AND value->>'id'=id),
253
+ PRIMARY KEY(installation,tenant,app,kind,id))`);
254
+ await client.query("CREATE INDEX IF NOT EXISTS bp_auth_record_kind ON bp_auth_records(installation,kind,tenant,app)");
255
+ await client.query("CREATE INDEX IF NOT EXISTS bp_auth_mail_due ON bp_auth_records(installation,((value->>'nextAttempt')::bigint),id) WHERE kind='mail' AND value->>'state' IN ('pending','sending')");
256
+ await client.query("CREATE INDEX IF NOT EXISTS bp_auth_session_expiry ON bp_auth_records(installation,tenant,app,((value->>'expiresAt')::bigint)) WHERE kind='session'");
257
+ await client.query("CREATE INDEX IF NOT EXISTS bp_auth_session_revoked ON bp_auth_records(installation,tenant,app,id) WHERE kind='session' AND value->>'revoked'='true'");
258
+ await client.query("CREATE INDEX IF NOT EXISTS bp_auth_session_user ON bp_auth_records(installation,tenant,app,(value->>'userId'),id) WHERE kind='session' AND value->>'revoked'='false'");
259
+ await client.query("CREATE INDEX IF NOT EXISTS bp_auth_mail_failed ON bp_auth_records(installation,tenant,app,id) WHERE kind='mail' AND value->>'state'='failed'");
260
+ await client.query("COMMIT");
261
+ }
262
+ catch (error) {
263
+ await client.query("ROLLBACK");
264
+ throw error;
265
+ }
266
+ finally {
267
+ client.release();
268
+ }
269
+ }
270
+ async transaction(scope, work) {
271
+ const client = await this.pool.connect();
272
+ try {
273
+ await client.query("BEGIN");
274
+ // Tenant serialization also fences first-user isolation decisions against app creation.
275
+ await client.query("SELECT pg_advisory_xact_lock(hashtextextended($1,0))", [JSON.stringify([this.installationId, scope.tenantId])]);
276
+ const result = await work(pgTransaction(client, this.installationId));
277
+ await client.query("COMMIT");
278
+ return result;
279
+ }
280
+ catch (error) {
281
+ await client.query("ROLLBACK");
282
+ throw error;
283
+ }
284
+ finally {
285
+ client.release();
286
+ }
287
+ }
288
+ async close() { await this.pool.end(); }
289
+ }
290
+ /** Import only known legacy fields. Unknown schema versions never trigger a destructive fallback. */
291
+ export function importLegacy(raw, appIds) {
292
+ const file = raw;
293
+ if (file.version === 2)
294
+ return validateRecords(raw);
295
+ if (file.version !== 1 || !Array.isArray(file.users))
296
+ throw new Error("Unsupported legacy auth store");
297
+ const records = [];
298
+ const tenants = new Set();
299
+ const identifiers = new Map();
300
+ // Legacy usernames were case-sensitive, and email addresses were not unique.
301
+ // Collect ownership before emitting records so a collision never chooses a winner.
302
+ for (const user of file.users) {
303
+ if (typeof user.id !== "string" || typeof user.tenantId !== "string" || typeof user.username !== "string" || typeof user.passwordHash !== "string")
304
+ throw new Error("Malformed legacy user");
305
+ const scope = { tenantId: user.tenantId, appId: "" };
306
+ for (const id of new Set([user.username.trim().toLowerCase(), ...(typeof user.email === "string" && user.email ? [user.email.trim().toLowerCase()] : [])])) {
307
+ const indexKey = key("identifier", id, scope);
308
+ const entry = identifiers.get(indexKey) ?? { scope, id, users: new Set() };
309
+ entry.users.add(user.id);
310
+ identifiers.set(indexKey, entry);
311
+ }
312
+ }
313
+ for (const user of file.users) {
314
+ if (typeof user.id !== "string" || typeof user.tenantId !== "string" || typeof user.username !== "string" || typeof user.passwordHash !== "string")
315
+ throw new Error("Malformed legacy user");
316
+ tenants.add(user.tenantId);
317
+ const scope = { tenantId: user.tenantId, appId: "" };
318
+ const email = typeof user.email === "string" ? user.email.trim().toLowerCase() : "";
319
+ const ambiguousEmail = !!email && identifiers.get(key("identifier", email, scope)).users.size > 1;
320
+ // Preserve existing password access without treating a stored email as verified ownership.
321
+ const value = { ...user, id: user.id, appId: "", legacyUsernameLogin: true, bootstrapAdmin: Object.values(user.appRoles ?? {}).some(roles => roles.includes("*")), emailVerified: false, refreshVersion: Number(user.refreshVersion ?? 0) + 1 };
322
+ if (ambiguousEmail) {
323
+ value.legacyEmail = user.email;
324
+ delete value.email;
325
+ }
326
+ else if (email)
327
+ value.email = email;
328
+ records.push({ kind: "user", scope, value });
329
+ if (identifiers.get(key("identifier", user.username.trim().toLowerCase(), scope)).users.size > 1) {
330
+ records.push({ kind: "legacy-username", scope, value: { id: user.username, userId: user.id } });
331
+ }
332
+ const roles = user.appRoles ?? {};
333
+ for (const appId of new Set([...(appIds[user.tenantId] ?? []), ...Object.keys(roles)])) {
334
+ records.push({ kind: "roles", scope: { tenantId: user.tenantId, appId }, value: { id: user.id, roles: roles[appId] ?? [], initialized: true } });
335
+ }
336
+ }
337
+ for (const entry of identifiers.values())
338
+ records.push({ kind: "identifier", scope: entry.scope, value: entry.users.size === 1
339
+ ? { id: entry.id, userId: [...entry.users][0] }
340
+ : { id: entry.id, ambiguous: true } });
341
+ for (const tenantId of tenants)
342
+ records.push({ kind: "tenant", scope: { tenantId, appId: "" }, value: { id: tenantId, isolation: "tenant", lockedAt: Date.now(), bootstrapComplete: true } });
343
+ for (const [id, expiresAt] of Object.entries(file.revokedRefreshTokens ?? {}))
344
+ records.push({ kind: "legacy-revocation", scope: { tenantId: "", appId: "" }, value: { id, expiresAt } });
345
+ return validateRecords({ version: 2, records });
346
+ }
347
+ export async function openAuthStorage(options) {
348
+ const path = resolve(options.path);
349
+ if (options.mode === "simple") {
350
+ if (existsSync(`${path}.mode.json`))
351
+ throw new Error("Advanced-to-Simple downgrade is unsupported");
352
+ if (existsSync(path)) {
353
+ const raw = JSON.parse(readFileSync(path, "utf8"));
354
+ if (raw.version === 1) {
355
+ const release = lockFile(path);
356
+ try {
357
+ const current = JSON.parse(readFileSync(path, "utf8"));
358
+ const imported = importLegacy(current, options.appIds);
359
+ if (new Set(imported.records.filter(r => r.kind === "tenant").map(r => r.scope.tenantId)).size > 1)
360
+ throw new Error("Legacy store contains multiple tenants; select Advanced mode");
361
+ if (!existsSync(`${path}.v1.backup`))
362
+ atomicWrite(`${path}.v1.backup`, current);
363
+ atomicWrite(path, imported);
364
+ }
365
+ finally {
366
+ release();
367
+ }
368
+ }
369
+ }
370
+ return new JsonAuthStorage(path);
371
+ }
372
+ const storage = new PostgresAuthStorage(options.connectionString ?? "", options.installationId);
373
+ const markerPath = `${path}.mode.json`;
374
+ if (existsSync(markerPath)) {
375
+ const marker = JSON.parse(readFileSync(markerPath, "utf8"));
376
+ if (marker.installationId !== options.installationId)
377
+ throw new Error("Auth installation identity mismatch");
378
+ }
379
+ atomicWrite(markerPath, { mode: "advanced", installationId: options.installationId, state: "migrating" });
380
+ try {
381
+ await storage.initialize();
382
+ const release = existsSync(path) ? lockFile(path) : () => undefined;
383
+ try {
384
+ const source = existsSync(path) ? readFileSync(path, "utf8") : undefined;
385
+ const checksum = source ? createHash("sha256").update(source).digest("hex") : "empty";
386
+ const scope = { tenantId: "", appId: "" };
387
+ await storage.transaction(scope, async (tx) => {
388
+ const ledger = await tx.get("migration", "simple", scope);
389
+ if (ledger) {
390
+ if (source && ledger.checksum !== checksum)
391
+ throw new Error("Leftover Simple store differs from the committed import");
392
+ return;
393
+ }
394
+ if ((await tx.list("user")).length)
395
+ throw new Error("Advanced store contains users without a matching migration ledger");
396
+ if (source) {
397
+ const imported = importLegacy(JSON.parse(source), options.appIds);
398
+ if (!existsSync(`${path}.advanced.backup`))
399
+ atomicWrite(`${path}.advanced.backup`, JSON.parse(source));
400
+ for (const row of imported.records) {
401
+ if (row.kind === "session")
402
+ row.value.revoked = true;
403
+ await tx.put(row.kind, row.scope, row.value);
404
+ }
405
+ for (const row of imported.records)
406
+ if (!isDeepStrictEqual(await tx.get(row.kind, row.value.id, row.scope), row.value))
407
+ throw new Error("Auth migration record verification failed");
408
+ if ((await tx.list("user")).length !== imported.records.filter(row => row.kind === "user").length)
409
+ throw new Error("Auth migration verification failed");
410
+ }
411
+ await tx.put("migration", scope, { id: "simple", checksum, completedAt: Date.now(), schemaVersion: 1 });
412
+ });
413
+ atomicWrite(markerPath, { mode: "advanced", installationId: options.installationId, state: "complete" });
414
+ if (source)
415
+ unlinkSync(path);
416
+ }
417
+ finally {
418
+ release();
419
+ }
420
+ return storage;
421
+ }
422
+ catch (error) {
423
+ await storage.close();
424
+ throw error;
425
+ }
426
+ }
427
+ //# sourceMappingURL=storage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"storage.js","sourceRoot":"","sources":["../src/storage.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@betterportal/auth-default",
3
- "version": "10.6.20",
3
+ "version": "10.6.22",
4
4
  "description": "BetterPortal v10 default auth service for Node.js",
5
5
  "main": "lib/index.js",
6
6
  "types": "src/index.ts",
@@ -30,17 +30,24 @@
30
30
  "type": "module",
31
31
  "devDependencies": {
32
32
  "@types/bcrypt": "^6.0.0",
33
- "@types/node": "^26.4.0",
33
+ "@types/node": "^26.5.1",
34
+ "@types/pg": "^8.23.1",
34
35
  "tsx": "^4.23.12",
35
36
  "typescript": "^6.0.3"
36
37
  },
37
38
  "dependencies": {
38
- "@betterportal/framework": "10.6.20",
39
- "@betterportal/plugin-bsb": "10.6.20",
40
- "@bsb/base": "^9.7.0",
41
- "anyvali": "^1.1.5",
39
+ "@betterportal/framework": "10.6.22",
40
+ "@betterportal/plugin-bsb": "10.6.22",
41
+ "@bsb/base": "^9.7.3",
42
+ "@simplewebauthn/browser": "^14.0.0",
43
+ "@simplewebauthn/server": "^14.0.1",
44
+ "anyvali": "^1.1.6",
45
+ "argon2": "^0.45.1",
42
46
  "bcrypt": "^6.0.0",
43
- "jsx-htmx": "4.0.0"
47
+ "jsx-htmx": "4.0.100",
48
+ "openid-client": "^6.8.8",
49
+ "otplib": "^13.5.0",
50
+ "pg": "^8.23.0"
44
51
  },
45
52
  "files": [
46
53
  "lib/**/*",