pipework 0.83.0 → 0.84.1

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 (46) hide show
  1. package/CHANGELOG.md +13 -0
  2. package/dist/REFERENCE.md +1477 -0
  3. package/dist/auth/auth/audit.d.ts +7 -0
  4. package/dist/auth/auth/audit.d.ts.map +1 -0
  5. package/dist/auth/auth/audit.js +28 -0
  6. package/dist/auth/auth/audit.js.map +1 -0
  7. package/dist/auth/auth/email-links.d.ts +103 -0
  8. package/dist/auth/auth/email-links.d.ts.map +1 -0
  9. package/dist/auth/auth/email-links.js +166 -0
  10. package/dist/auth/auth/email-links.js.map +1 -0
  11. package/dist/auth/auth/index.d.ts +2 -0
  12. package/dist/auth/auth/index.d.ts.map +1 -1
  13. package/dist/auth/auth/index.js +1 -0
  14. package/dist/auth/auth/index.js.map +1 -1
  15. package/dist/auth/auth/namespace.d.ts +3 -0
  16. package/dist/auth/auth/namespace.d.ts.map +1 -1
  17. package/dist/auth/auth/namespace.js +3 -0
  18. package/dist/auth/auth/namespace.js.map +1 -1
  19. package/dist/auth/auth/schema.d.ts +45 -0
  20. package/dist/auth/auth/schema.d.ts.map +1 -1
  21. package/dist/auth/auth/schema.js +27 -0
  22. package/dist/auth/auth/schema.js.map +1 -1
  23. package/dist/auth/auth/sign-in.d.ts.map +1 -1
  24. package/dist/auth/auth/sign-in.js +2 -21
  25. package/dist/auth/auth/sign-in.js.map +1 -1
  26. package/dist/core/config/namespace.d.ts +1 -0
  27. package/dist/core/config/namespace.d.ts.map +1 -1
  28. package/dist/core/config/schema.d.ts +1 -0
  29. package/dist/core/config/schema.d.ts.map +1 -1
  30. package/dist/core/config/schema.js +2 -0
  31. package/dist/core/config/schema.js.map +1 -1
  32. package/dist/data/migrate/internal-definitions.d.ts.map +1 -1
  33. package/dist/data/migrate/internal-definitions.js +5 -0
  34. package/dist/data/migrate/internal-definitions.js.map +1 -1
  35. package/dist/infra/email/mail.d.ts +13 -0
  36. package/dist/infra/email/mail.d.ts.map +1 -1
  37. package/dist/infra/email/mail.js +32 -2
  38. package/dist/infra/email/mail.js.map +1 -1
  39. package/dist/infra/email/sigv4.d.ts +24 -0
  40. package/dist/infra/email/sigv4.d.ts.map +1 -0
  41. package/dist/infra/email/sigv4.js +55 -0
  42. package/dist/infra/email/sigv4.js.map +1 -0
  43. package/dist/test/savepoints.d.ts.map +1 -1
  44. package/dist/test/savepoints.js +28 -7
  45. package/dist/test/savepoints.js.map +1 -1
  46. package/package.json +1 -1
@@ -0,0 +1,7 @@
1
+ import type { DB } from '../../data/db/index.js';
2
+ /**
3
+ * Writes an audit record with no tenant and no actor (the person is not yet signed in)
4
+ * under the Flow's open trace step; does nothing when no step is open. A failure is logged, not thrown.
5
+ */
6
+ export declare function auditUnauthenticated(db: DB, entity: string, verb: string, entityId: string | null, details: Record<string, unknown>): Promise<void>;
7
+ //# sourceMappingURL=audit.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"audit.d.ts","sourceRoot":"","sources":["../../../src/auth/auth/audit.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,wBAAwB,CAAA;AAIhD;;;GAGG;AACH,wBAAsB,oBAAoB,CACxC,EAAE,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,EAAE,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC9F,OAAO,CAAC,IAAI,CAAC,CAiBf"}
@@ -0,0 +1,28 @@
1
+ import { sql } from '../../data/db/sql.js';
2
+ import { getContext } from '../../request/context/store.js';
3
+ import { getBaseLogger } from '../../core/logging/index.js';
4
+ /**
5
+ * Writes an audit record with no tenant and no actor (the person is not yet signed in)
6
+ * under the Flow's open trace step; does nothing when no step is open. A failure is logged, not thrown.
7
+ */
8
+ export async function auditUnauthenticated(db, entity, verb, entityId, details) {
9
+ const flow = getContext();
10
+ const trace = flow?.trace;
11
+ const stepId = trace?.buffer.openStepId ?? null;
12
+ if (trace === undefined || trace === null || stepId === null)
13
+ return;
14
+ try {
15
+ await db.transaction(async (sp) => {
16
+ await sp.execute(sql `
17
+ INSERT INTO audit_record
18
+ (trace_day, trace_id, trace_step_id, tenant_id, actor_id, entity, verb, entity_id, after, occurred_at)
19
+ VALUES (${trace.openedDay}, ${trace.id}, ${stepId}, NULL, NULL,
20
+ ${entity}, ${verb}, ${entityId}, ${JSON.stringify(details)}::jsonb, now())
21
+ `);
22
+ });
23
+ }
24
+ catch (err) {
25
+ getBaseLogger().error({ err, traceId: trace.id }, `Failed to write the ${entity} ${verb} audit record`);
26
+ }
27
+ }
28
+ //# sourceMappingURL=audit.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"audit.js","sourceRoot":"","sources":["../../../src/auth/auth/audit.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,sBAAsB,CAAA;AAE1C,OAAO,EAAE,UAAU,EAAE,MAAM,gCAAgC,CAAA;AAC3D,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAA;AAE3D;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,oBAAoB,CACxC,EAAM,EAAE,MAAc,EAAE,IAAY,EAAE,QAAuB,EAAE,OAAgC;IAE/F,MAAM,IAAI,GAAG,UAAU,EAAE,CAAA;IACzB,MAAM,KAAK,GAAG,IAAI,EAAE,KAAK,CAAA;IACzB,MAAM,MAAM,GAAG,KAAK,EAAE,MAAM,CAAC,UAAU,IAAI,IAAI,CAAA;IAC/C,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,IAAI,IAAI,MAAM,KAAK,IAAI;QAAE,OAAM;IACpE,IAAI,CAAC;QACH,MAAM,EAAE,CAAC,WAAW,CAAC,KAAK,EAAE,EAAM,EAAE,EAAE;YACpC,MAAM,EAAE,CAAC,OAAO,CAAC,GAAG,CAAA;;;kBAGR,KAAK,CAAC,SAAS,KAAK,KAAK,CAAC,EAAE,KAAK,MAAM;YAC7C,MAAM,KAAK,IAAI,KAAK,QAAQ,KAAK,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC;OAC7D,CAAC,CAAA;QACJ,CAAC,CAAC,CAAA;IACJ,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,aAAa,EAAE,CAAC,KAAK,CAAC,EAAE,GAAG,EAAE,OAAO,EAAE,KAAK,CAAC,EAAE,EAAE,EAAE,uBAAuB,MAAM,IAAI,IAAI,eAAe,CAAC,CAAA;IACzG,CAAC;AACH,CAAC"}
@@ -0,0 +1,103 @@
1
+ import type { DB } from '../../data/db/index.js';
2
+ import type { Mail } from '../../infra/email/mail.js';
3
+ import type { Passwords } from './passwords.js';
4
+ import type { Sessions } from './sessions.js';
5
+ export type EmailLinkPurpose = 'reset' | 'verify';
6
+ export interface EmailLinkPurposeConfig {
7
+ /** The name of the app's mail template; it reads `data.url`. */
8
+ readonly template: string;
9
+ readonly expiresInSeconds: number;
10
+ /** The link the person opens, built from the token. */
11
+ readonly url: (token: string) => string;
12
+ }
13
+ export interface RequestLimit {
14
+ readonly max: number;
15
+ readonly windowSeconds: number;
16
+ }
17
+ export interface EmailLinksConfig {
18
+ readonly mail: Mail<any>;
19
+ readonly passwords: Passwords;
20
+ /** When set, a completed reset revokes the user's refresh tokens and bumps their auth version. */
21
+ readonly sessions?: Pick<Sessions, 'revokeAll' | 'bumpVersion'>;
22
+ /** Keys the token. At least 32 bytes; without it a copy of the database cannot make a token. */
23
+ readonly secret: string;
24
+ /** Finds the user for an address (given trimmed, NFC and lower-cased), or null. Runs in the request's transaction. */
25
+ readonly lookup: (db: DB, address: string) => Promise<{
26
+ userId: string;
27
+ } | null>;
28
+ readonly purposes: {
29
+ readonly reset?: EmailLinkPurposeConfig;
30
+ readonly verify?: EmailLinkPurposeConfig;
31
+ };
32
+ /** Defaults: 5 per address and 20 per client within 3600 seconds. */
33
+ readonly limits?: {
34
+ readonly perAddress?: RequestLimit;
35
+ readonly perClient?: RequestLimit;
36
+ };
37
+ /** Every `request` takes at least this long. Default 250. */
38
+ readonly minResponseMs?: number;
39
+ }
40
+ export type EmailLinkState = 'active' | 'used' | 'expired' | 'ended' | 'unknown';
41
+ export type EmailLinkRefusal = 'unknown' | 'used' | 'expired' | 'ended' | 'wrong-purpose';
42
+ export interface EmailLinks {
43
+ /**
44
+ * Asks for a link. Answers `{ ok: true }` for a known address, an unknown one and an over-limit one alike,
45
+ * and takes at least `minResponseMs` for each. Only a known, within-limit address gets a message.
46
+ * Runs in `db` (the caller's transaction): a rollback drops the link and the message. The limit counts
47
+ * are kept on `pipe.system()`, so they survive a rollback. Needs an active Flow.
48
+ */
49
+ request(db: DB, input: {
50
+ purpose: EmailLinkPurpose;
51
+ address: string;
52
+ client?: string;
53
+ }): Promise<{
54
+ ok: true;
55
+ }>;
56
+ /** The state of a link, without using it. */
57
+ check(db: DB, token: string): Promise<{
58
+ state: EmailLinkState;
59
+ purpose?: EmailLinkPurpose;
60
+ userId?: string;
61
+ }>;
62
+ /** Uses a link of `purpose` in one atomic statement: of two concurrent uses exactly one succeeds. */
63
+ use(db: DB, token: string, purpose: EmailLinkPurpose): Promise<{
64
+ ok: true;
65
+ userId: string;
66
+ address: string;
67
+ } | {
68
+ ok: false;
69
+ reason: EmailLinkRefusal;
70
+ }>;
71
+ /**
72
+ * Uses a reset link, hashes the new password, calls `store(db, userId, hash)` (the app keeps the hash),
73
+ * ends the user's other reset links and, when `sessions` is configured, revokes all their refresh tokens
74
+ * and bumps their auth version. A link that cannot be used changes nothing. The caller starts the new session.
75
+ */
76
+ completeReset(db: DB, token: string, newPassword: string, options: {
77
+ store: (db: DB, userId: string, passwordHash: string) => Promise<void>;
78
+ }): Promise<{
79
+ ok: true;
80
+ userId: string;
81
+ } | {
82
+ ok: false;
83
+ reason: EmailLinkRefusal;
84
+ }>;
85
+ /** Ends the user's outstanding reset links (call it when a password changes). */
86
+ endResets(db: DB, userId: string): Promise<void>;
87
+ }
88
+ /**
89
+ * Creates emailed single-use links that prove control of an address: password reset and address
90
+ * verification. Needs blueprint `emailLinks: {}` (tables `pipework_email_links`, `pipework_email_link_requests`)
91
+ * and `email: {}`; the app's mail module must run `mail.jobs`.
92
+ *
93
+ * The token is `base64url(HMAC-SHA256(secret, id || nonce))`. The link table holds only its sha256, and the
94
+ * stored message holds only a reference: the url is computed when the message is delivered, so no copy of the
95
+ * database holds a token or can make one without `secret`.
96
+ *
97
+ * Requesting, using and completing a reset are flow steps (`pipework/auth:email-link-request`,
98
+ * `pipework/auth:email-link-use`) and are audited (`PasswordReset:requested`, `PasswordReset:completed`,
99
+ * `PasswordReset:link-used`, `EmailAddress:verification-requested`, `EmailAddress:verified`; no tenant), never with the token,
100
+ * the password or an address that matched no user.
101
+ */
102
+ export declare function createEmailLinks(config: EmailLinksConfig): EmailLinks;
103
+ //# sourceMappingURL=email-links.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"email-links.d.ts","sourceRoot":"","sources":["../../../src/auth/auth/email-links.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,166 @@
1
+ import { createHash, createHmac, randomBytes, randomUUID } from 'node:crypto';
2
+ import { sql } from '../../data/db/sql.js';
3
+ import { pipeSystem } from '../../data/db/db.js';
4
+ import { getBaseLogger } from '../../core/logging/index.js';
5
+ import { __flowStep } from '../../trace/runtime/flow-step.js';
6
+ import { auditUnauthenticated } from './audit.js';
7
+ const LATE_NAME = 'pipework.emailLink';
8
+ const sha256 = (value) => createHash('sha256').update(value).digest('hex');
9
+ const normalize = (address) => address.normalize('NFC').trim().toLowerCase();
10
+ const sleep = (ms) => new Promise(resolve => setTimeout(resolve, ms));
11
+ /**
12
+ * Creates emailed single-use links that prove control of an address: password reset and address
13
+ * verification. Needs blueprint `emailLinks: {}` (tables `pipework_email_links`, `pipework_email_link_requests`)
14
+ * and `email: {}`; the app's mail module must run `mail.jobs`.
15
+ *
16
+ * The token is `base64url(HMAC-SHA256(secret, id || nonce))`. The link table holds only its sha256, and the
17
+ * stored message holds only a reference: the url is computed when the message is delivered, so no copy of the
18
+ * database holds a token or can make one without `secret`.
19
+ *
20
+ * Requesting, using and completing a reset are flow steps (`pipework/auth:email-link-request`,
21
+ * `pipework/auth:email-link-use`) and are audited (`PasswordReset:requested`, `PasswordReset:completed`,
22
+ * `PasswordReset:link-used`, `EmailAddress:verification-requested`, `EmailAddress:verified`; no tenant), never with the token,
23
+ * the password or an address that matched no user.
24
+ */
25
+ export function createEmailLinks(config) {
26
+ if (Buffer.byteLength(config.secret, 'utf8') < 32) {
27
+ throw new Error('[pipework] auth.emailLinks: "secret" must be at least 32 bytes.');
28
+ }
29
+ const perAddress = config.limits?.perAddress ?? { max: 5, windowSeconds: 3600 };
30
+ const perClient = config.limits?.perClient ?? { max: 20, windowSeconds: 3600 };
31
+ const minResponseMs = config.minResponseMs ?? 250;
32
+ const tokenFor = (id, nonce) => createHmac('sha256', config.secret).update(id).update('\0').update(nonce).digest('base64url');
33
+ function purposeConfig(purpose) {
34
+ const found = config.purposes[purpose];
35
+ if (found === undefined)
36
+ throw new Error(`[pipework] auth.emailLinks: no "${purpose}" purpose is configured.`);
37
+ return found;
38
+ }
39
+ config.mail.registerLateData(LATE_NAME, async (db, ref) => {
40
+ const row = (await db.execute(sql `SELECT purpose, nonce FROM pipework_email_links WHERE id = ${ref}::uuid`))[0];
41
+ if (row === undefined)
42
+ throw new Error('[pipework] auth.emailLinks: the link behind a message no longer exists.');
43
+ return { url: purposeConfig(row['purpose']).url(tokenFor(ref, row['nonce'])) };
44
+ });
45
+ // Counts the request against a key and says whether it is over the limit. Atomic per key.
46
+ async function countRequest(db, key, limit) {
47
+ const rows = await db.execute(sql `
48
+ INSERT INTO pipework_email_link_requests AS r (key, count, window_start)
49
+ VALUES (${key}, 1, now())
50
+ ON CONFLICT (key) DO UPDATE SET
51
+ count = CASE WHEN r.window_start < now() - ${limit.windowSeconds}::int * interval '1 second' THEN 1 ELSE r.count + 1 END,
52
+ window_start = CASE WHEN r.window_start < now() - ${limit.windowSeconds}::int * interval '1 second' THEN now() ELSE r.window_start END
53
+ RETURNING count`);
54
+ return Number(rows[0]['count']) > limit.max;
55
+ }
56
+ const requestStep = __flowStep({ ref: 'pipework/auth:email-link-request' }, async (db, input) => {
57
+ const purposeCfg = purposeConfig(input.purpose);
58
+ const system = pipeSystem();
59
+ const address = normalize(input.address);
60
+ const over = [await countRequest(system, 'address:' + sha256(address), perAddress)];
61
+ if (input.client !== undefined && input.client !== '')
62
+ over.push(await countRequest(system, 'client:' + input.client, perClient));
63
+ const verbs = input.purpose === 'reset'
64
+ ? { entity: 'PasswordReset', verb: 'requested' }
65
+ : { entity: 'EmailAddress', verb: 'verification-requested' };
66
+ const client = input.client ?? null;
67
+ if (over.some(Boolean)) {
68
+ getBaseLogger().warn({ event: 'email link refused', purpose: input.purpose, client }, 'email link request over its limit');
69
+ await auditUnauthenticated(system, verbs.entity, verbs.verb, null, { purpose: input.purpose, client, outcome: 'limited' });
70
+ return;
71
+ }
72
+ const found = await config.lookup(db, address);
73
+ if (found === null) {
74
+ await auditUnauthenticated(system, verbs.entity, verbs.verb, null, { purpose: input.purpose, client, outcome: 'unknown' });
75
+ return;
76
+ }
77
+ const id = randomUUID();
78
+ const nonce = randomBytes(16).toString('base64url');
79
+ const tokenHash = sha256(tokenFor(id, nonce));
80
+ await db.execute(sql `
81
+ UPDATE pipework_email_links SET ended_at = now()
82
+ WHERE user_id = ${found.userId} AND purpose = ${input.purpose}
83
+ AND used_at IS NULL AND ended_at IS NULL AND expires_at > now()`);
84
+ await db.execute(sql `
85
+ INSERT INTO pipework_email_links (id, purpose, user_id, address, token_hash, nonce, expires_at)
86
+ VALUES (${id}::uuid, ${input.purpose}, ${found.userId}, ${address}, ${tokenHash}, ${nonce},
87
+ now() + ${purposeCfg.expiresInSeconds}::int * interval '1 second')`);
88
+ await config.mail.send(db, {
89
+ to: address, template: purposeCfg.template, data: {}, key: `pipework.emailLink:${id}`,
90
+ lateData: { name: LATE_NAME, ref: id },
91
+ });
92
+ await auditUnauthenticated(system, verbs.entity, verbs.verb, found.userId, { purpose: input.purpose, client, outcome: 'sent' });
93
+ });
94
+ async function request(db, input) {
95
+ const started = performance.now();
96
+ try {
97
+ await requestStep(db, input);
98
+ }
99
+ finally {
100
+ for (let wait = minResponseMs - (performance.now() - started); wait > 0; wait = minResponseMs - (performance.now() - started)) {
101
+ await sleep(Math.ceil(wait));
102
+ }
103
+ }
104
+ return { ok: true };
105
+ }
106
+ async function check(db, token) {
107
+ const row = (await db.execute(sql `
108
+ SELECT purpose, user_id, used_at IS NOT NULL AS used, ended_at IS NOT NULL AS ended, expires_at <= now() AS expired
109
+ FROM pipework_email_links WHERE token_hash = ${sha256(token)}`))[0];
110
+ if (row === undefined)
111
+ return { state: 'unknown' };
112
+ const state = row['used'] === true ? 'used' : row['ended'] === true ? 'ended' : row['expired'] === true ? 'expired' : 'active';
113
+ return { state, purpose: row['purpose'], userId: row['user_id'] };
114
+ }
115
+ async function consume(db, token, purpose) {
116
+ const hash = sha256(token);
117
+ const rows = await db.execute(sql `
118
+ UPDATE pipework_email_links SET used_at = now()
119
+ WHERE token_hash = ${hash} AND purpose = ${purpose}
120
+ AND used_at IS NULL AND ended_at IS NULL AND expires_at > now()
121
+ RETURNING user_id, address`);
122
+ if (rows.length > 0)
123
+ return { ok: true, userId: rows[0]['user_id'], address: rows[0]['address'] };
124
+ const seen = await check(db, token);
125
+ if (seen.state === 'unknown')
126
+ return { ok: false, reason: 'unknown' };
127
+ if (seen.purpose !== purpose)
128
+ return { ok: false, reason: 'wrong-purpose' };
129
+ return { ok: false, reason: seen.state === 'active' ? 'used' : seen.state };
130
+ }
131
+ const useStep = __flowStep({ ref: 'pipework/auth:email-link-use' }, async (db, token, purpose) => {
132
+ const result = await consume(db, token, purpose);
133
+ if (result.ok) {
134
+ const [entity, verb] = purpose === 'verify' ? ['EmailAddress', 'verified'] : ['PasswordReset', 'link-used'];
135
+ await auditUnauthenticated(pipeSystem(), entity, verb, result.userId, { purpose });
136
+ }
137
+ return result;
138
+ });
139
+ async function endResets(db, userId) {
140
+ await db.execute(sql `
141
+ UPDATE pipework_email_links SET ended_at = now()
142
+ WHERE user_id = ${userId} AND purpose = 'reset' AND used_at IS NULL AND ended_at IS NULL`);
143
+ }
144
+ const completeStep = __flowStep({ ref: 'pipework/auth:email-link-use' }, async (db, token, newPassword, options) => {
145
+ const used = await consume(db, token, 'reset');
146
+ if (!used.ok)
147
+ return used;
148
+ const hash = await config.passwords.hash(newPassword);
149
+ await options.store(db, used.userId, hash);
150
+ await endResets(db, used.userId);
151
+ if (config.sessions !== undefined) {
152
+ await config.sessions.revokeAll(db, used.userId);
153
+ await config.sessions.bumpVersion(db, used.userId);
154
+ }
155
+ await auditUnauthenticated(pipeSystem(), 'PasswordReset', 'completed', used.userId, { purpose: 'reset' });
156
+ return { ok: true, userId: used.userId };
157
+ });
158
+ return {
159
+ request,
160
+ check,
161
+ use: (db, token, purpose) => useStep(db, token, purpose),
162
+ completeReset: (db, token, newPassword, options) => completeStep(db, token, newPassword, options),
163
+ endResets,
164
+ };
165
+ }
166
+ //# sourceMappingURL=email-links.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"email-links.js","sourceRoot":"","sources":["../../../src/auth/auth/email-links.ts"],"names":[],"mappings":"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"}
@@ -12,4 +12,6 @@ export { createPasswords } from './passwords.js';
12
12
  export type { Passwords, PasswordsConfig, ScryptParams, VerifyResult } from './passwords.js';
13
13
  export { createSignIn } from './sign-in.js';
14
14
  export type { SignIn, SignInConfig, SignInAttempt, SignInResult } from './sign-in.js';
15
+ export { createEmailLinks } from './email-links.js';
16
+ export type { EmailLinks, EmailLinksConfig, EmailLinkPurpose, EmailLinkPurposeConfig, EmailLinkState, EmailLinkRefusal, RequestLimit } from './email-links.js';
15
17
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/auth/auth/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,YAAY,EAAE,WAAW,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAA;AAClF,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AACzC,YAAY,EAAE,YAAY,EAAE,cAAc,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,YAAY,CAAA;AAChG,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAA;AAC9C,YAAY,EAAE,WAAW,EAAE,sBAAsB,EAAE,MAAM,eAAe,CAAA;AACxE,YAAY,EAAE,QAAQ,EAAE,aAAa,EAAE,SAAS,EAAE,YAAY,EAAE,eAAe,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,eAAe,CAAA;AACjI,YAAY,EAAE,YAAY,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAA;AACrE,OAAO,EAAE,mBAAmB,EAAE,oBAAoB,EAAE,sBAAsB,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAA;AAClH,OAAO,EAAE,sBAAsB,EAAE,MAAM,gBAAgB,CAAA;AACvD,YAAY,EAAE,cAAc,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,eAAe,EAAE,aAAa,EAAE,OAAO,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAA;AAC7K,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAA;AAChD,YAAY,EAAE,SAAS,EAAE,eAAe,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAA;AAC5F,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAA;AAC3C,YAAY,EAAE,MAAM,EAAE,YAAY,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,cAAc,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/auth/auth/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,YAAY,EAAE,WAAW,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAA;AAClF,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AACzC,YAAY,EAAE,YAAY,EAAE,cAAc,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,YAAY,CAAA;AAChG,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAA;AAC9C,YAAY,EAAE,WAAW,EAAE,sBAAsB,EAAE,MAAM,eAAe,CAAA;AACxE,YAAY,EAAE,QAAQ,EAAE,aAAa,EAAE,SAAS,EAAE,YAAY,EAAE,eAAe,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,eAAe,CAAA;AACjI,YAAY,EAAE,YAAY,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAA;AACrE,OAAO,EAAE,mBAAmB,EAAE,oBAAoB,EAAE,sBAAsB,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAA;AAClH,OAAO,EAAE,sBAAsB,EAAE,MAAM,gBAAgB,CAAA;AACvD,YAAY,EAAE,cAAc,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,eAAe,EAAE,aAAa,EAAE,OAAO,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAA;AAC7K,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAA;AAChD,YAAY,EAAE,SAAS,EAAE,eAAe,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAA;AAC5F,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAA;AAC3C,YAAY,EAAE,MAAM,EAAE,YAAY,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,cAAc,CAAA;AACrF,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAA;AACnD,YAAY,EAAE,UAAU,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,sBAAsB,EAAE,cAAc,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAA"}
@@ -4,4 +4,5 @@ export { resolveCookieConfig, buildSetCookieHeader, buildClearCookieHeader, pars
4
4
  export { createMultiOrgSessions } from './multi-org.js';
5
5
  export { createPasswords } from './passwords.js';
6
6
  export { createSignIn } from './sign-in.js';
7
+ export { createEmailLinks } from './email-links.js';
7
8
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/auth/auth/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AAEzC,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAA;AAI9C,OAAO,EAAE,mBAAmB,EAAE,oBAAoB,EAAE,sBAAsB,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAA;AAClH,OAAO,EAAE,sBAAsB,EAAE,MAAM,gBAAgB,CAAA;AAEvD,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAA;AAEhD,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/auth/auth/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AAEzC,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAA;AAI9C,OAAO,EAAE,mBAAmB,EAAE,oBAAoB,EAAE,sBAAsB,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAA;AAClH,OAAO,EAAE,sBAAsB,EAAE,MAAM,gBAAgB,CAAA;AAEvD,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAA;AAEhD,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAA;AAE3C,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAA"}
@@ -2,6 +2,7 @@ import { createSessions } from './sessions.js';
2
2
  import { createMultiOrgSessions } from './multi-org.js';
3
3
  import { createPasswords } from './passwords.js';
4
4
  import { createSignIn } from './sign-in.js';
5
+ import { createEmailLinks } from './email-links.js';
5
6
  import { runAuthChain } from './chain.js';
6
7
  import { resolveCookieConfig, parseCookieHeader, buildSetCookieHeader, buildClearCookieHeader } from './cookie.js';
7
8
  /** Authentication namespace — session management, multi-org support, auth chain resolution. */
@@ -14,6 +15,8 @@ export declare const auth: {
14
15
  passwords: typeof createPasswords;
15
16
  /** Guarded password sign-in that slows, then refuses, repeated failures per account and per client. */
16
17
  signIn: typeof createSignIn;
18
+ /** Emailed single-use links that prove control of an address: password reset and address verification; the token is never stored. */
19
+ emailLinks: typeof createEmailLinks;
17
20
  /** Executes an auth chain (strategy pipeline) to resolve auth + tenant from a request. */
18
21
  runChain: typeof runAuthChain;
19
22
  /** Resolves CookieConfig with defaults for secure cookie-based token delivery. */
@@ -1 +1 @@
1
- {"version":3,"file":"namespace.d.ts","sourceRoot":"","sources":["../../../src/auth/auth/namespace.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAA;AAC9C,OAAO,EAAE,sBAAsB,EAAE,MAAM,gBAAgB,CAAA;AACvD,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAA;AAChD,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAA;AAC3C,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AACzC,OAAO,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,oBAAoB,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAA;AAElH,+FAA+F;AAC/F,eAAO,MAAM,IAAI;IACf,gGAAgG;;IAEhG,wFAAwF;;IAExF,6FAA6F;;IAE7F,uGAAuG;;IAEvG,0FAA0F;;IAE1F,kFAAkF;;IAElF,0DAA0D;;IAE1D,4EAA4E;;IAE5E,iEAAiE;;CAElE,CAAA"}
1
+ {"version":3,"file":"namespace.d.ts","sourceRoot":"","sources":["../../../src/auth/auth/namespace.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAA;AAC9C,OAAO,EAAE,sBAAsB,EAAE,MAAM,gBAAgB,CAAA;AACvD,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAA;AAChD,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAA;AAC3C,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAA;AACnD,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AACzC,OAAO,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,oBAAoB,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAA;AAElH,+FAA+F;AAC/F,eAAO,MAAM,IAAI;IACf,gGAAgG;;IAEhG,wFAAwF;;IAExF,6FAA6F;;IAE7F,uGAAuG;;IAEvG,qIAAqI;;IAErI,0FAA0F;;IAE1F,kFAAkF;;IAElF,0DAA0D;;IAE1D,4EAA4E;;IAE5E,iEAAiE;;CAElE,CAAA"}
@@ -2,6 +2,7 @@ import { createSessions } from './sessions.js';
2
2
  import { createMultiOrgSessions } from './multi-org.js';
3
3
  import { createPasswords } from './passwords.js';
4
4
  import { createSignIn } from './sign-in.js';
5
+ import { createEmailLinks } from './email-links.js';
5
6
  import { runAuthChain } from './chain.js';
6
7
  import { resolveCookieConfig, parseCookieHeader, buildSetCookieHeader, buildClearCookieHeader } from './cookie.js';
7
8
  /** Authentication namespace — session management, multi-org support, auth chain resolution. */
@@ -14,6 +15,8 @@ export const auth = {
14
15
  passwords: createPasswords,
15
16
  /** Guarded password sign-in that slows, then refuses, repeated failures per account and per client. */
16
17
  signIn: createSignIn,
18
+ /** Emailed single-use links that prove control of an address: password reset and address verification; the token is never stored. */
19
+ emailLinks: createEmailLinks,
17
20
  /** Executes an auth chain (strategy pipeline) to resolve auth + tenant from a request. */
18
21
  runChain: runAuthChain,
19
22
  /** Resolves CookieConfig with defaults for secure cookie-based token delivery. */
@@ -1 +1 @@
1
- {"version":3,"file":"namespace.js","sourceRoot":"","sources":["../../../src/auth/auth/namespace.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAA;AAC9C,OAAO,EAAE,sBAAsB,EAAE,MAAM,gBAAgB,CAAA;AACvD,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAA;AAChD,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAA;AAC3C,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AACzC,OAAO,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,oBAAoB,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAA;AAElH,+FAA+F;AAC/F,MAAM,CAAC,MAAM,IAAI,GAAG;IAClB,gGAAgG;IAChG,cAAc;IACd,wFAAwF;IACxF,cAAc,EAAE,sBAAsB;IACtC,6FAA6F;IAC7F,SAAS,EAAE,eAAe;IAC1B,uGAAuG;IACvG,MAAM,EAAE,YAAY;IACpB,0FAA0F;IAC1F,QAAQ,EAAE,YAAY;IACtB,kFAAkF;IAClF,aAAa,EAAE,mBAAmB;IAClC,0DAA0D;IAC1D,WAAW,EAAE,iBAAiB;IAC9B,4EAA4E;IAC5E,cAAc,EAAE,oBAAoB;IACpC,iEAAiE;IACjE,gBAAgB,EAAE,sBAAsB;CACzC,CAAA"}
1
+ {"version":3,"file":"namespace.js","sourceRoot":"","sources":["../../../src/auth/auth/namespace.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAA;AAC9C,OAAO,EAAE,sBAAsB,EAAE,MAAM,gBAAgB,CAAA;AACvD,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAA;AAChD,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAA;AAC3C,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAA;AACnD,OAAO,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AACzC,OAAO,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,oBAAoB,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAA;AAElH,+FAA+F;AAC/F,MAAM,CAAC,MAAM,IAAI,GAAG;IAClB,gGAAgG;IAChG,cAAc;IACd,wFAAwF;IACxF,cAAc,EAAE,sBAAsB;IACtC,6FAA6F;IAC7F,SAAS,EAAE,eAAe;IAC1B,uGAAuG;IACvG,MAAM,EAAE,YAAY;IACpB,qIAAqI;IACrI,UAAU,EAAE,gBAAgB;IAC5B,0FAA0F;IAC1F,QAAQ,EAAE,YAAY;IACtB,kFAAkF;IAClF,aAAa,EAAE,mBAAmB;IAClC,0DAA0D;IAC1D,WAAW,EAAE,iBAAiB;IAC9B,4EAA4E;IAC5E,cAAc,EAAE,oBAAoB;IACpC,iEAAiE;IACjE,gBAAgB,EAAE,sBAAsB;CACzC,CAAA"}
@@ -101,4 +101,49 @@ export declare const signinAttempts: import("../../data/domain/types.js").Define
101
101
  nullable: true;
102
102
  }>;
103
103
  }, "pipework_signin_attempts">;
104
+ export declare const emailLinks: import("../../data/domain/types.js").DefinedTable<{
105
+ id: import("../../data/domain/types.js").FieldDescriptor<string, {
106
+ primaryKey: true;
107
+ }> & import("../../data/domain/field.js").FieldModifiers<string, {
108
+ primaryKey: true;
109
+ }>;
110
+ purpose: import("../../data/domain/types.js").FieldDescriptor<string, {}> & import("../../data/domain/field.js").FieldModifiers<string, {}>;
111
+ userId: import("../../data/domain/types.js").FieldDescriptor<string, {}> & import("../../data/domain/field.js").FieldModifiers<string, {}>;
112
+ address: import("../../data/domain/types.js").FieldDescriptor<string, {}> & import("../../data/domain/field.js").FieldModifiers<string, {}>;
113
+ tokenHash: import("../../data/domain/types.js").FieldDescriptor<string, {}> & import("../../data/domain/field.js").FieldModifiers<string, {}>;
114
+ nonce: import("../../data/domain/types.js").FieldDescriptor<string, {}> & import("../../data/domain/field.js").FieldModifiers<string, {}>;
115
+ createdAt: import("../../data/domain/types.js").FieldDescriptor<Date, {
116
+ hasDefault: true;
117
+ }> & import("../../data/domain/field.js").FieldModifiers<Date, {
118
+ hasDefault: true;
119
+ }>;
120
+ expiresAt: import("../../data/domain/types.js").FieldDescriptor<Date, {}> & import("../../data/domain/field.js").FieldModifiers<Date, {}>;
121
+ usedAt: import("../../data/domain/types.js").FieldDescriptor<Date | null, {
122
+ nullable: true;
123
+ }> & import("../../data/domain/field.js").FieldModifiers<Date | null, {
124
+ nullable: true;
125
+ }>;
126
+ endedAt: import("../../data/domain/types.js").FieldDescriptor<Date | null, {
127
+ nullable: true;
128
+ }> & import("../../data/domain/field.js").FieldModifiers<Date | null, {
129
+ nullable: true;
130
+ }>;
131
+ }, "pipework_email_links">;
132
+ export declare const emailLinkRequests: import("../../data/domain/types.js").DefinedTable<{
133
+ key: import("../../data/domain/types.js").FieldDescriptor<string, {
134
+ primaryKey: true;
135
+ }> & import("../../data/domain/field.js").FieldModifiers<string, {
136
+ primaryKey: true;
137
+ }>;
138
+ count: import("../../data/domain/types.js").FieldDescriptor<number, {
139
+ hasDefault: true;
140
+ }> & import("../../data/domain/field.js").FieldModifiers<number, {
141
+ hasDefault: true;
142
+ }>;
143
+ windowStart: import("../../data/domain/types.js").FieldDescriptor<Date, {
144
+ hasDefault: true;
145
+ }> & import("../../data/domain/field.js").FieldModifiers<Date, {
146
+ hasDefault: true;
147
+ }>;
148
+ }, "pipework_email_link_requests">;
104
149
  //# sourceMappingURL=schema.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../../src/auth/auth/schema.ts"],"names":[],"mappings":"AAoBA,eAAO,MAAM,gBAAgB,EAAE,WAAW,CAAC,MAAM,CAE/C,CAAA;AAEF,eAAO,MAAM,aAAa;;;;;;;;;;;;;;;;;;;;;;;;;;;6BAexB,CAAA;AAEF,eAAO,MAAM,YAAY;;;;;;;;;;;;;;;;4BAIvB,CAAA;AAEF,eAAO,MAAM,QAAQ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;wBAanB,CAAA;AAIF,eAAO,MAAM,cAAc;;;;;;;;;;;;;;;;;;;;;;;;;;8BAMzB,CAAA"}
1
+ {"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../../src/auth/auth/schema.ts"],"names":[],"mappings":"AAoBA,eAAO,MAAM,gBAAgB,EAAE,WAAW,CAAC,MAAM,CAG/C,CAAA;AAEF,eAAO,MAAM,aAAa;;;;;;;;;;;;;;;;;;;;;;;;;;;6BAexB,CAAA;AAEF,eAAO,MAAM,YAAY;;;;;;;;;;;;;;;;4BAIvB,CAAA;AAEF,eAAO,MAAM,QAAQ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;wBAanB,CAAA;AAIF,eAAO,MAAM,cAAc;;;;;;;;;;;;;;;;;;;;;;;;;;8BAMzB,CAAA;AAKF,eAAO,MAAM,UAAU;;;;;;;;;;;;;;;;;;;;;;;;;;;0BAgBrB,CAAA;AAGF,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;kCAI5B,CAAA"}
@@ -18,6 +18,7 @@ import { sql } from '../../data/db/sql.js';
18
18
  import { index, unique } from '../../data/db/idx/index.js';
19
19
  export const AUTH_TABLE_NAMES = new Set([
20
20
  'pipework_refresh_tokens', 'pipework_auth_versions', 'pipework_user_orgs', 'pipework_signin_attempts',
21
+ 'pipework_email_links', 'pipework_email_link_requests',
21
22
  ]);
22
23
  export const refreshTokens = define('pipework_refresh_tokens', {
23
24
  id: field.uuid().defaultRandom().primaryKey(),
@@ -63,4 +64,30 @@ export const signinAttempts = define('pipework_signin_attempts', {
63
64
  lastFailureAt: field.timestamp().nullable(),
64
65
  lockedUntil: field.timestamp().nullable(),
65
66
  });
67
+ // Behind `auth.emailLinks`. Not tenant-scoped: a reset is asked for before any
68
+ // tenant is known. The link's token is never stored: `token_hash` is its sha256,
69
+ // and the token itself is an HMAC (keyed by the app's secret) of `id` and `nonce`.
70
+ export const emailLinks = define('pipework_email_links', {
71
+ id: field.uuid().primaryKey(),
72
+ purpose: field.text(),
73
+ userId: field.text(),
74
+ address: field.text(),
75
+ tokenHash: field.text(),
76
+ nonce: field.text(),
77
+ createdAt: field.timestamp().default('now'),
78
+ expiresAt: field.timestamp(),
79
+ usedAt: field.timestamp().nullable(),
80
+ endedAt: field.timestamp().nullable(),
81
+ }, {
82
+ indexes: (t) => ({
83
+ byHash: unique('pipework_email_links_token_hash_key').on(t['tokenHash']),
84
+ byUser: index('idx_pipework_email_links_user').on(t['userId'], t['purpose']),
85
+ }),
86
+ });
87
+ // Request counts behind `auth.emailLinks`; `key` is 'address:<sha256 of the address>' or 'client:<address>'.
88
+ export const emailLinkRequests = define('pipework_email_link_requests', {
89
+ key: field.text().primaryKey(),
90
+ count: field.integer().default(0),
91
+ windowStart: field.timestamp().default('now'),
92
+ });
66
93
  //# sourceMappingURL=schema.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"schema.js","sourceRoot":"","sources":["../../../src/auth/auth/schema.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"schema.js","sourceRoot":"","sources":["../../../src/auth/auth/schema.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"sign-in.d.ts","sourceRoot":"","sources":["../../../src/auth/auth/sign-in.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,wBAAwB,CAAA;AAIhD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAE/C,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,SAAS,EAAE,SAAS,CAAA;IAC7B,6EAA6E;IAC7E,QAAQ,CAAC,gBAAgB,CAAC,EAAE,MAAM,CAAA;IAClC,qFAAqF;IACrF,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,CAAA;IACjC,0FAA0F;IAC1F,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAA;IAC/B,gDAAgD;IAChD,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAA;CACjC;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IACxB,kEAAkE;IAClE,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;IACxB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;IACzB,iGAAiG;IACjG,QAAQ,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC,CAAA;CACvG;AAED,MAAM,MAAM,YAAY,GACpB;IAAE,QAAQ,CAAC,EAAE,EAAE,IAAI,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,WAAW,EAAE,OAAO,CAAA;CAAE,GAC7E;IAAE,QAAQ,CAAC,EAAE,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,SAAS,GAAG,QAAQ,CAAC;IAAC,QAAQ,CAAC,iBAAiB,CAAC,EAAE,MAAM,CAAA;CAAE,CAAA;AAEtG,MAAM,WAAW,MAAM;IACrB,OAAO,CAAC,KAAK,EAAE,aAAa,GAAG,OAAO,CAAC,YAAY,CAAC,CAAA;CACrD;AAID;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,YAAY,GAAG,MAAM,CA0GzD"}
1
+ {"version":3,"file":"sign-in.d.ts","sourceRoot":"","sources":["../../../src/auth/auth/sign-in.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,wBAAwB,CAAA;AAIhD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAE/C,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,SAAS,EAAE,SAAS,CAAA;IAC7B,6EAA6E;IAC7E,QAAQ,CAAC,gBAAgB,CAAC,EAAE,MAAM,CAAA;IAClC,qFAAqF;IACrF,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,CAAA;IACjC,0FAA0F;IAC1F,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAA;IAC/B,gDAAgD;IAChD,QAAQ,CAAC,cAAc,CAAC,EAAE,MAAM,CAAA;CACjC;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAA;IACxB,kEAAkE;IAClE,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;IACxB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;IACzB,iGAAiG;IACjG,QAAQ,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,OAAO,EAAE,MAAM,KAAK,OAAO,CAAC;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC,CAAA;CACvG;AAED,MAAM,MAAM,YAAY,GACpB;IAAE,QAAQ,CAAC,EAAE,EAAE,IAAI,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,WAAW,EAAE,OAAO,CAAA;CAAE,GAC7E;IAAE,QAAQ,CAAC,EAAE,EAAE,KAAK,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,SAAS,GAAG,QAAQ,CAAC;IAAC,QAAQ,CAAC,iBAAiB,CAAC,EAAE,MAAM,CAAA;CAAE,CAAA;AAEtG,MAAM,WAAW,MAAM;IACrB,OAAO,CAAC,KAAK,EAAE,aAAa,GAAG,OAAO,CAAC,YAAY,CAAC,CAAA;CACrD;AAID;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,YAAY,GAAG,MAAM,CA0FzD"}
@@ -1,7 +1,7 @@
1
1
  import { createHash } from 'node:crypto';
2
2
  import { sql } from '../../data/db/sql.js';
3
3
  import { pipeSystem } from '../../data/db/db.js';
4
- import { getContext } from '../../request/context/store.js';
4
+ import { auditUnauthenticated } from './audit.js';
5
5
  import { getBaseLogger } from '../../core/logging/index.js';
6
6
  /**
7
7
  * Creates a guarded password sign-in. `attempt` needs an active Flow (a request,
@@ -73,26 +73,7 @@ export function createSignIn(config) {
73
73
  FROM pipework_signin_attempts WHERE key = ${key}`);
74
74
  return { locked: true, failures: Number(held[0]?.['failures'] ?? 0), retryAfterSeconds: Number(held[0]?.['remaining'] ?? 1) };
75
75
  }
76
- async function audit(db, verb, userId, details) {
77
- const flow = getContext();
78
- const trace = flow?.trace;
79
- const stepId = trace?.buffer.openStepId ?? null;
80
- if (trace === undefined || trace === null || stepId === null)
81
- return;
82
- try {
83
- await db.transaction(async (sp) => {
84
- await sp.execute(sql `
85
- INSERT INTO audit_record
86
- (trace_day, trace_id, trace_step_id, tenant_id, actor_id, entity, verb, entity_id, after, occurred_at)
87
- VALUES (${trace.openedDay}, ${trace.id}, ${stepId}, NULL, NULL,
88
- 'SignIn', ${verb}, ${userId}, ${JSON.stringify(details)}::jsonb, now())
89
- `);
90
- });
91
- }
92
- catch (err) {
93
- getBaseLogger().error({ err, traceId: trace.id }, `Failed to write the sign-in ${verb} audit record`);
94
- }
95
- }
76
+ const audit = (db, verb, userId, details) => auditUnauthenticated(db, 'SignIn', verb, userId, details);
96
77
  async function attempt(input) {
97
78
  const db = pipeSystem();
98
79
  const { accountKey, all } = keysFor(input.account, input.client);
@@ -1 +1 @@
1
- {"version":3,"file":"sign-in.js","sourceRoot":"","sources":["../../../src/auth/auth/sign-in.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"sign-in.js","sourceRoot":"","sources":["../../../src/auth/auth/sign-in.ts"],"names":[],"mappings":"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"}
@@ -218,6 +218,7 @@ export declare const config: {
218
218
  sessions: import("zod/v4").ZodOptional<import("zod/v4").ZodObject<{}, import("zod/v4/core").$strip>>;
219
219
  orgs: import("zod/v4").ZodOptional<import("zod/v4").ZodObject<{}, import("zod/v4/core").$strip>>;
220
220
  passwords: import("zod/v4").ZodOptional<import("zod/v4").ZodObject<{}, import("zod/v4/core").$strip>>;
221
+ emailLinks: import("zod/v4").ZodOptional<import("zod/v4").ZodObject<{}, import("zod/v4/core").$strip>>;
221
222
  email: import("zod/v4").ZodOptional<import("zod/v4").ZodObject<{}, import("zod/v4/core").$strip>>;
222
223
  fastPath: import("zod/v4").ZodOptional<import("zod/v4").ZodObject<{
223
224
  default: import("zod/v4").ZodDefault<import("zod/v4").ZodEnum<{