@stratum-hq/lib 1.2.1 → 1.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/crypto.d.ts +6 -2
- package/dist/crypto.d.ts.map +1 -1
- package/dist/crypto.js +23 -6
- package/dist/crypto.js.map +1 -1
- package/dist/index.d.ts +3 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +8 -1
- package/dist/index.js.map +1 -1
- package/dist/migrate-schemas.d.ts.map +1 -1
- package/dist/migrate-schemas.js +19 -8
- package/dist/migrate-schemas.js.map +1 -1
- package/dist/migrations/022_roles_name_per_tenant.sql +10 -0
- package/dist/migrations/024_propagate_ancestry_ltree.sql +42 -0
- package/dist/migrations/025_redact_sensitive_config_audit.sql +19 -0
- package/dist/migrations/026_redact_webhook_secret_audit.sql +28 -0
- package/dist/migrations/027_tenant_status_pending.sql +8 -0
- package/dist/migrations/028_ancestry_path_prefix_index.sql +12 -0
- package/dist/pool-helpers.d.ts.map +1 -1
- package/dist/pool-helpers.js +20 -4
- package/dist/pool-helpers.js.map +1 -1
- package/dist/services/abac-service.d.ts +1 -1
- package/dist/services/abac-service.d.ts.map +1 -1
- package/dist/services/abac-service.js +64 -43
- package/dist/services/abac-service.js.map +1 -1
- package/dist/services/api-key-service.d.ts +6 -0
- package/dist/services/api-key-service.d.ts.map +1 -1
- package/dist/services/api-key-service.js +84 -33
- package/dist/services/api-key-service.js.map +1 -1
- package/dist/services/audit-service.d.ts.map +1 -1
- package/dist/services/audit-service.js +2 -1
- package/dist/services/audit-service.js.map +1 -1
- package/dist/services/config-service.d.ts.map +1 -1
- package/dist/services/config-service.js +14 -6
- package/dist/services/config-service.js.map +1 -1
- package/dist/services/consent-service.d.ts +2 -2
- package/dist/services/consent-service.d.ts.map +1 -1
- package/dist/services/consent-service.js +4 -1
- package/dist/services/consent-service.js.map +1 -1
- package/dist/services/event-service.d.ts +12 -0
- package/dist/services/event-service.d.ts.map +1 -1
- package/dist/services/event-service.js +240 -79
- package/dist/services/event-service.js.map +1 -1
- package/dist/services/key-rotation-service.d.ts +18 -1
- package/dist/services/key-rotation-service.d.ts.map +1 -1
- package/dist/services/key-rotation-service.js +57 -9
- package/dist/services/key-rotation-service.js.map +1 -1
- package/dist/services/permission-service.d.ts.map +1 -1
- package/dist/services/permission-service.js +42 -18
- package/dist/services/permission-service.js.map +1 -1
- package/dist/services/region-service.d.ts.map +1 -1
- package/dist/services/region-service.js +8 -7
- package/dist/services/region-service.js.map +1 -1
- package/dist/services/retention-service.d.ts +7 -1
- package/dist/services/retention-service.d.ts.map +1 -1
- package/dist/services/retention-service.js +47 -7
- package/dist/services/retention-service.js.map +1 -1
- package/dist/services/role-service.d.ts +7 -0
- package/dist/services/role-service.d.ts.map +1 -1
- package/dist/services/role-service.js +25 -11
- package/dist/services/role-service.js.map +1 -1
- package/dist/services/tenant-service.d.ts +24 -3
- package/dist/services/tenant-service.d.ts.map +1 -1
- package/dist/services/tenant-service.js +132 -61
- package/dist/services/tenant-service.js.map +1 -1
- package/dist/services/webhook-service.d.ts +5 -0
- package/dist/services/webhook-service.d.ts.map +1 -1
- package/dist/services/webhook-service.js +14 -0
- package/dist/services/webhook-service.js.map +1 -1
- package/dist/stratum-tables.d.ts +12 -0
- package/dist/stratum-tables.d.ts.map +1 -0
- package/dist/stratum-tables.js +31 -0
- package/dist/stratum-tables.js.map +1 -0
- package/dist/stratum.d.ts +30 -12
- package/dist/stratum.d.ts.map +1 -1
- package/dist/stratum.js +138 -43
- package/dist/stratum.js.map +1 -1
- package/dist/validation.d.ts +25 -0
- package/dist/validation.d.ts.map +1 -0
- package/dist/validation.js +23 -0
- package/dist/validation.js.map +1 -0
- package/package.json +5 -5
|
@@ -7,6 +7,13 @@ export declare function validateWebhookUrl(url: string): void;
|
|
|
7
7
|
* against blocked ranges. Call this at delivery time, not just registration.
|
|
8
8
|
*/
|
|
9
9
|
export declare function validateWebhookUrlWithDns(url: string): Promise<void>;
|
|
10
|
+
/**
|
|
11
|
+
* POST a webhook payload and return the HTTP status. The host is resolved once,
|
|
12
|
+
* every address is validated, and the socket connects only to those addresses
|
|
13
|
+
* (the client never resolves the name again), so a DNS answer that changes
|
|
14
|
+
* after validation cannot redirect the request. Redirects are not followed.
|
|
15
|
+
*/
|
|
16
|
+
export declare function postWebhook(url: string, headers: Record<string, string>, body: string): Promise<number>;
|
|
10
17
|
interface WebhookEventRow {
|
|
11
18
|
id: string;
|
|
12
19
|
type: string;
|
|
@@ -31,6 +38,11 @@ export declare function deliverWebhook(webhook: WebhookRow, event: WebhookEventR
|
|
|
31
38
|
responseCode: number | null;
|
|
32
39
|
error: string | null;
|
|
33
40
|
}>;
|
|
41
|
+
/**
|
|
42
|
+
* Deliver every due pending delivery. At most one run is active per pool in
|
|
43
|
+
* this process; a trigger that arrives during a run joins it and makes it
|
|
44
|
+
* check for due deliveries once more before finishing.
|
|
45
|
+
*/
|
|
34
46
|
export declare function processDeliveries(pool: pg.Pool): Promise<void>;
|
|
35
47
|
export declare function retryFailedDeliveries(pool: pg.Pool, tenantId?: string): Promise<number>;
|
|
36
48
|
export declare function retryDelivery(pool: pg.Pool, deliveryId: string): Promise<boolean>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"event-service.d.ts","sourceRoot":"","sources":["../../src/services/event-service.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"event-service.d.ts","sourceRoot":"","sources":["../../src/services/event-service.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,MAAM,IAAI,CAAC;AAEpB,OAAO,EAA6B,KAAK,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAgF/E,8EAA8E;AAC9E,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAwBpD;AAED;;;GAGG;AACH,wBAAsB,yBAAyB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAsC1E;AAgCD;;;;;GAKG;AACH,wBAAsB,WAAW,CAC/B,GAAG,EAAE,MAAM,EACX,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAC/B,IAAI,EAAE,MAAM,GACX,OAAO,CAAC,MAAM,CAAC,CAyCjB;AAoBD,UAAU,eAAe;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC9B,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,UAAU,UAAU;IAClB,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,GAAG,EAAE,MAAM,CAAC;IACZ,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,MAAM,EAAE,OAAO,CAAC;IAChB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,wBAAsB,SAAS,CAC7B,IAAI,EAAE,EAAE,CAAC,IAAI,EACb,IAAI,EAAE,WAAW,EACjB,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC5B,OAAO,CAAC,IAAI,CAAC,CAkCf;AAED,wBAAsB,cAAc,CAClC,OAAO,EAAE,UAAU,EACnB,KAAK,EAAE,eAAe,EACtB,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,CAAC,CA0ClF;AAMD;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAoB9D;AAkID,wBAAsB,qBAAqB,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CA4B7F;AAED,wBAAsB,aAAa,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAgBvF;AAED,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,wBAAsB,gBAAgB,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC,CA0B/F;AAED,wBAAsB,oBAAoB,CACxC,IAAI,EAAE,EAAE,CAAC,IAAI,EACb,KAAK,SAAM,EACX,QAAQ,CAAC,EAAE,MAAM,GAChB,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC,CA0BpC"}
|
|
@@ -5,6 +5,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.validateWebhookUrl = validateWebhookUrl;
|
|
7
7
|
exports.validateWebhookUrlWithDns = validateWebhookUrlWithDns;
|
|
8
|
+
exports.postWebhook = postWebhook;
|
|
8
9
|
exports.emitEvent = emitEvent;
|
|
9
10
|
exports.deliverWebhook = deliverWebhook;
|
|
10
11
|
exports.processDeliveries = processDeliveries;
|
|
@@ -13,15 +14,25 @@ exports.retryDelivery = retryDelivery;
|
|
|
13
14
|
exports.getDeliveryStats = getDeliveryStats;
|
|
14
15
|
exports.listFailedDeliveries = listFailedDeliveries;
|
|
15
16
|
const promises_1 = __importDefault(require("node:dns/promises"));
|
|
17
|
+
const node_http_1 = __importDefault(require("node:http"));
|
|
18
|
+
const node_https_1 = __importDefault(require("node:https"));
|
|
16
19
|
const node_net_1 = __importDefault(require("node:net"));
|
|
17
20
|
const pool_helpers_js_1 = require("../pool-helpers.js");
|
|
18
21
|
const core_1 = require("@stratum-hq/core");
|
|
19
22
|
const webhook_service_js_1 = require("./webhook-service.js");
|
|
20
23
|
const webhook_signature_js_1 = require("../webhook-signature.js");
|
|
21
24
|
const MAX_ATTEMPTS = 5;
|
|
25
|
+
const DELIVERY_TIMEOUT_MS = 10_000;
|
|
26
|
+
/** Deliveries claimed and sent concurrently per pass. */
|
|
27
|
+
const DELIVERY_BATCH_SIZE = 10;
|
|
22
28
|
/**
|
|
23
|
-
*
|
|
24
|
-
*
|
|
29
|
+
* How long a claimed delivery stays invisible to other workers. Longer than a
|
|
30
|
+
* delivery can take, so a row is only reclaimed if its worker died mid-flight.
|
|
31
|
+
*/
|
|
32
|
+
const DELIVERY_LEASE_MS = 60_000;
|
|
33
|
+
/**
|
|
34
|
+
* Reserved, private, loopback, link-local, and cloud-metadata ranges, plus the
|
|
35
|
+
* IANA special-purpose ranges, that a webhook must never target (SSRF protection). BlockList compares parsed address bytes,
|
|
25
36
|
* so it matches every textual notation of an address, and it also checks an
|
|
26
37
|
* IPv4-mapped IPv6 literal against the IPv4 rules.
|
|
27
38
|
*/
|
|
@@ -29,15 +40,38 @@ const BLOCKED_IP_RANGES = new node_net_1.default.BlockList();
|
|
|
29
40
|
// IPv4
|
|
30
41
|
BLOCKED_IP_RANGES.addSubnet("0.0.0.0", 8, "ipv4"); // "this" network / unspecified
|
|
31
42
|
BLOCKED_IP_RANGES.addSubnet("10.0.0.0", 8, "ipv4"); // RFC 1918
|
|
43
|
+
BLOCKED_IP_RANGES.addSubnet("100.64.0.0", 10, "ipv4"); // shared address space (CGNAT), incl. some cloud metadata
|
|
32
44
|
BLOCKED_IP_RANGES.addSubnet("127.0.0.0", 8, "ipv4"); // loopback
|
|
33
45
|
BLOCKED_IP_RANGES.addSubnet("169.254.0.0", 16, "ipv4"); // link-local, incl. cloud metadata
|
|
34
46
|
BLOCKED_IP_RANGES.addSubnet("172.16.0.0", 12, "ipv4"); // RFC 1918
|
|
47
|
+
BLOCKED_IP_RANGES.addSubnet("192.0.0.0", 24, "ipv4"); // IETF protocol assignments
|
|
48
|
+
BLOCKED_IP_RANGES.addSubnet("192.0.2.0", 24, "ipv4"); // documentation (TEST-NET-1)
|
|
49
|
+
BLOCKED_IP_RANGES.addSubnet("192.31.196.0", 24, "ipv4"); // AS112-v4
|
|
50
|
+
BLOCKED_IP_RANGES.addSubnet("192.52.193.0", 24, "ipv4"); // AMT
|
|
51
|
+
BLOCKED_IP_RANGES.addSubnet("192.88.99.0", 24, "ipv4"); // deprecated 6to4 relay anycast
|
|
35
52
|
BLOCKED_IP_RANGES.addSubnet("192.168.0.0", 16, "ipv4"); // RFC 1918
|
|
53
|
+
BLOCKED_IP_RANGES.addSubnet("192.175.48.0", 24, "ipv4"); // direct delegation AS112
|
|
54
|
+
BLOCKED_IP_RANGES.addSubnet("198.18.0.0", 15, "ipv4"); // benchmarking
|
|
55
|
+
BLOCKED_IP_RANGES.addSubnet("198.51.100.0", 24, "ipv4"); // documentation (TEST-NET-2)
|
|
56
|
+
BLOCKED_IP_RANGES.addSubnet("203.0.113.0", 24, "ipv4"); // documentation (TEST-NET-3)
|
|
57
|
+
BLOCKED_IP_RANGES.addSubnet("224.0.0.0", 4, "ipv4"); // multicast
|
|
58
|
+
BLOCKED_IP_RANGES.addSubnet("240.0.0.0", 4, "ipv4"); // reserved, incl. limited broadcast
|
|
36
59
|
// IPv6
|
|
37
|
-
BLOCKED_IP_RANGES.
|
|
38
|
-
BLOCKED_IP_RANGES.
|
|
60
|
+
BLOCKED_IP_RANGES.addSubnet("::", 96, "ipv6"); // unspecified, loopback, deprecated IPv4-compatible
|
|
61
|
+
BLOCKED_IP_RANGES.addSubnet("64:ff9b::", 96, "ipv6"); // NAT64 well-known prefix (maps to IPv4)
|
|
62
|
+
BLOCKED_IP_RANGES.addSubnet("64:ff9b:1::", 48, "ipv6"); // local-use NAT64 (maps to IPv4)
|
|
63
|
+
BLOCKED_IP_RANGES.addSubnet("100::", 64, "ipv6"); // discard-only
|
|
64
|
+
BLOCKED_IP_RANGES.addSubnet("100:0:0:1::", 64, "ipv6"); // dummy prefix
|
|
65
|
+
BLOCKED_IP_RANGES.addSubnet("2001::", 23, "ipv6"); // IETF protocol assignments, incl. Teredo (maps to IPv4)
|
|
66
|
+
BLOCKED_IP_RANGES.addSubnet("2001:db8::", 32, "ipv6"); // documentation
|
|
67
|
+
BLOCKED_IP_RANGES.addSubnet("2002::", 16, "ipv6"); // 6to4 (maps to IPv4)
|
|
68
|
+
BLOCKED_IP_RANGES.addSubnet("2620:4f:8000::", 48, "ipv6"); // direct delegation AS112
|
|
69
|
+
BLOCKED_IP_RANGES.addSubnet("3fff::", 20, "ipv6"); // documentation
|
|
70
|
+
BLOCKED_IP_RANGES.addSubnet("5f00::", 16, "ipv6"); // SRv6 SIDs
|
|
39
71
|
BLOCKED_IP_RANGES.addSubnet("fc00::", 7, "ipv6"); // unique-local (covers fc00::/8 and fd00::/8)
|
|
40
72
|
BLOCKED_IP_RANGES.addSubnet("fe80::", 10, "ipv6"); // link-local
|
|
73
|
+
BLOCKED_IP_RANGES.addSubnet("fec0::", 10, "ipv6"); // deprecated site-local
|
|
74
|
+
BLOCKED_IP_RANGES.addSubnet("ff00::", 8, "ipv6"); // multicast
|
|
41
75
|
const BLOCKED_HOSTNAMES = new Set([
|
|
42
76
|
"localhost",
|
|
43
77
|
"localhost.localdomain",
|
|
@@ -119,6 +153,75 @@ async function validateWebhookUrlWithDns(url) {
|
|
|
119
153
|
}
|
|
120
154
|
}
|
|
121
155
|
}
|
|
156
|
+
/**
|
|
157
|
+
* Resolve a webhook host once and validate every address it resolves to.
|
|
158
|
+
* The caller connects only to the returned addresses.
|
|
159
|
+
*/
|
|
160
|
+
async function resolveWebhookHost(hostname) {
|
|
161
|
+
const literal = unwrapHostLiteral(hostname);
|
|
162
|
+
const family = node_net_1.default.isIP(literal);
|
|
163
|
+
if (family !== 0) {
|
|
164
|
+
return [{ address: literal, family }]; // IP literal, already checked by validateWebhookUrl
|
|
165
|
+
}
|
|
166
|
+
let addresses;
|
|
167
|
+
try {
|
|
168
|
+
addresses = await promises_1.default.lookup(hostname, { all: true });
|
|
169
|
+
}
|
|
170
|
+
catch {
|
|
171
|
+
addresses = [];
|
|
172
|
+
}
|
|
173
|
+
if (addresses.length === 0) {
|
|
174
|
+
throw new core_1.WebhookUrlValidationError(`DNS resolution failed for webhook host: ${hostname}`);
|
|
175
|
+
}
|
|
176
|
+
for (const { address } of addresses) {
|
|
177
|
+
if (isBlockedIp(address)) {
|
|
178
|
+
throw new core_1.WebhookUrlValidationError(`Webhook URL hostname ${hostname} resolves to blocked IP ${address}`);
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
return addresses;
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* POST a webhook payload and return the HTTP status. The host is resolved once,
|
|
185
|
+
* every address is validated, and the socket connects only to those addresses
|
|
186
|
+
* (the client never resolves the name again), so a DNS answer that changes
|
|
187
|
+
* after validation cannot redirect the request. Redirects are not followed.
|
|
188
|
+
*/
|
|
189
|
+
async function postWebhook(url, headers, body) {
|
|
190
|
+
validateWebhookUrl(url);
|
|
191
|
+
const target = new URL(url);
|
|
192
|
+
const signal = AbortSignal.timeout(DELIVERY_TIMEOUT_MS);
|
|
193
|
+
const addresses = await Promise.race([
|
|
194
|
+
resolveWebhookHost(target.hostname.toLowerCase()),
|
|
195
|
+
new Promise((_, reject) => {
|
|
196
|
+
signal.addEventListener("abort", () => reject(signal.reason), { once: true });
|
|
197
|
+
}),
|
|
198
|
+
]);
|
|
199
|
+
const pinnedLookup = (_hostname, options, callback) => {
|
|
200
|
+
if (options.all) {
|
|
201
|
+
callback(null, addresses);
|
|
202
|
+
}
|
|
203
|
+
else {
|
|
204
|
+
callback(null, addresses[0].address, addresses[0].family);
|
|
205
|
+
}
|
|
206
|
+
};
|
|
207
|
+
const send = target.protocol === "https:" ? node_https_1.default.request : node_http_1.default.request;
|
|
208
|
+
return new Promise((resolve, reject) => {
|
|
209
|
+
const req = send(target, {
|
|
210
|
+
method: "POST",
|
|
211
|
+
headers: { ...headers, "Content-Length": String(Buffer.byteLength(body)) },
|
|
212
|
+
lookup: pinnedLookup,
|
|
213
|
+
signal,
|
|
214
|
+
}, (res) => {
|
|
215
|
+
// Only the status is used; drain the body. A timeout that fires while
|
|
216
|
+
// the body is still arriving must not surface as an unhandled error.
|
|
217
|
+
res.on("error", () => { });
|
|
218
|
+
res.resume();
|
|
219
|
+
resolve(res.statusCode ?? 0);
|
|
220
|
+
});
|
|
221
|
+
req.on("error", reject);
|
|
222
|
+
req.end(body);
|
|
223
|
+
});
|
|
224
|
+
}
|
|
122
225
|
function retryDelayMs(attempts) {
|
|
123
226
|
// attempts^2 * 5000ms: 5s, 20s, 45s, 80s, 125s
|
|
124
227
|
return Math.pow(attempts, 2) * 5000;
|
|
@@ -156,32 +259,27 @@ async function deliverWebhook(webhook, event, deliveryId) {
|
|
|
156
259
|
data: event.data,
|
|
157
260
|
created_at: event.created_at,
|
|
158
261
|
});
|
|
159
|
-
//
|
|
160
|
-
|
|
161
|
-
const rawSecret = (0, webhook_service_js_1.decryptSecret)(webhook.secret_hash);
|
|
162
|
-
const timestamp = new Date().toISOString();
|
|
163
|
-
const signature = (0, webhook_signature_js_1.signWebhookPayload)(rawSecret, timestamp, payload);
|
|
262
|
+
// Any failure, including URL validation and secret decryption, is reported
|
|
263
|
+
// as a failed attempt so it gets backoff and eventually reaches the DLQ.
|
|
164
264
|
try {
|
|
165
|
-
const
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
if (response.ok) {
|
|
179
|
-
return { success: true, responseCode: response.status, error: null };
|
|
265
|
+
const rawSecret = (0, webhook_service_js_1.decryptSecret)(webhook.secret_hash);
|
|
266
|
+
const timestamp = new Date().toISOString();
|
|
267
|
+
const signature = (0, webhook_signature_js_1.signWebhookPayload)(rawSecret, timestamp, payload);
|
|
268
|
+
// SSRF protection: resolves, validates and pins the address it connects to.
|
|
269
|
+
const status = await postWebhook(webhook.url, {
|
|
270
|
+
"Content-Type": "application/json",
|
|
271
|
+
"X-Stratum-Event": event.type,
|
|
272
|
+
"X-Stratum-Signature": signature,
|
|
273
|
+
"X-Stratum-Delivery-ID": deliveryId,
|
|
274
|
+
"X-Stratum-Timestamp": timestamp,
|
|
275
|
+
}, payload);
|
|
276
|
+
if (status >= 200 && status < 300) {
|
|
277
|
+
return { success: true, responseCode: status, error: null };
|
|
180
278
|
}
|
|
181
279
|
return {
|
|
182
280
|
success: false,
|
|
183
|
-
responseCode:
|
|
184
|
-
error: `HTTP ${
|
|
281
|
+
responseCode: status,
|
|
282
|
+
error: `HTTP ${status}`,
|
|
185
283
|
};
|
|
186
284
|
}
|
|
187
285
|
catch (err) {
|
|
@@ -189,61 +287,124 @@ async function deliverWebhook(webhook, event, deliveryId) {
|
|
|
189
287
|
return { success: false, responseCode: null, error: message };
|
|
190
288
|
}
|
|
191
289
|
}
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
290
|
+
/** In-flight delivery run per pool, so concurrent triggers share one worker loop. */
|
|
291
|
+
const activeRuns = new WeakMap();
|
|
292
|
+
const rerunRequested = new WeakSet();
|
|
293
|
+
/**
|
|
294
|
+
* Deliver every due pending delivery. At most one run is active per pool in
|
|
295
|
+
* this process; a trigger that arrives during a run joins it and makes it
|
|
296
|
+
* check for due deliveries once more before finishing.
|
|
297
|
+
*/
|
|
298
|
+
function processDeliveries(pool) {
|
|
299
|
+
const active = activeRuns.get(pool);
|
|
300
|
+
if (active) {
|
|
301
|
+
rerunRequested.add(pool);
|
|
302
|
+
return active;
|
|
303
|
+
}
|
|
304
|
+
const run = (async () => {
|
|
305
|
+
try {
|
|
306
|
+
do {
|
|
307
|
+
rerunRequested.delete(pool);
|
|
308
|
+
while ((await deliverDueBatch(pool)) > 0) {
|
|
309
|
+
// keep going until nothing is due
|
|
310
|
+
}
|
|
311
|
+
} while (rerunRequested.has(pool));
|
|
312
|
+
}
|
|
313
|
+
finally {
|
|
314
|
+
activeRuns.delete(pool);
|
|
315
|
+
}
|
|
316
|
+
})();
|
|
317
|
+
activeRuns.set(pool, run);
|
|
318
|
+
return run;
|
|
319
|
+
}
|
|
320
|
+
/**
|
|
321
|
+
* Claim, deliver and record one batch. No database connection or transaction
|
|
322
|
+
* is held while a delivery is on the network: the claim and each result are
|
|
323
|
+
* separate short transactions. Returns the number of deliveries claimed.
|
|
324
|
+
*/
|
|
325
|
+
async function deliverDueBatch(pool) {
|
|
326
|
+
const claimed = await claimDueDeliveries(pool);
|
|
327
|
+
await Promise.all(claimed.map((c) => deliverClaimed(pool, c).catch(() => {
|
|
328
|
+
// Non-fatal: the lease expires and the delivery is picked up again.
|
|
329
|
+
})));
|
|
330
|
+
return claimed.length;
|
|
331
|
+
}
|
|
332
|
+
/**
|
|
333
|
+
* Lease a batch of due deliveries: count the attempt and move next_retry_at
|
|
334
|
+
* past the lease so no other worker takes them. Deliveries are taken in turns
|
|
335
|
+
* across tenants (oldest first within a tenant), so one tenant's backlog does
|
|
336
|
+
* not crowd out everyone else's.
|
|
337
|
+
*/
|
|
338
|
+
async function claimDueDeliveries(pool) {
|
|
339
|
+
return (0, pool_helpers_js_1.withTransaction)(pool, async (client) => {
|
|
340
|
+
const res = await client.query(`WITH due AS (
|
|
341
|
+
SELECT d.id, d.created_at,
|
|
342
|
+
row_number() OVER (PARTITION BY e.tenant_id ORDER BY d.created_at) AS turn
|
|
343
|
+
FROM webhook_deliveries d
|
|
344
|
+
JOIN webhook_events e ON e.id = d.event_id
|
|
345
|
+
WHERE d.status = 'pending'
|
|
346
|
+
AND (d.next_retry_at IS NULL OR d.next_retry_at <= now())
|
|
347
|
+
), picked AS (
|
|
348
|
+
SELECT id FROM due ORDER BY turn, created_at LIMIT $2
|
|
349
|
+
)
|
|
350
|
+
UPDATE webhook_deliveries d
|
|
351
|
+
SET attempts = d.attempts + 1,
|
|
352
|
+
next_retry_at = now() + ($1 || ' milliseconds')::interval
|
|
353
|
+
WHERE d.id IN (
|
|
354
|
+
SELECT id FROM webhook_deliveries
|
|
355
|
+
WHERE id IN (SELECT id FROM picked)
|
|
356
|
+
AND status = 'pending'
|
|
357
|
+
AND (next_retry_at IS NULL OR next_retry_at <= now())
|
|
358
|
+
FOR UPDATE SKIP LOCKED
|
|
359
|
+
)
|
|
360
|
+
RETURNING d.*`, [DELIVERY_LEASE_MS, DELIVERY_BATCH_SIZE]);
|
|
361
|
+
if (res.rows.length === 0) {
|
|
362
|
+
return [];
|
|
363
|
+
}
|
|
364
|
+
const webhookRes = await client.query(`SELECT * FROM webhooks WHERE id = ANY($1)`, [res.rows.map((d) => d.webhook_id)]);
|
|
365
|
+
const eventRes = await client.query(`SELECT * FROM webhook_events WHERE id = ANY($1)`, [res.rows.map((d) => d.event_id)]);
|
|
366
|
+
const webhooks = new Map(webhookRes.rows.map((w) => [w.id, w]));
|
|
367
|
+
const events = new Map(eventRes.rows.map((e) => [e.id, e]));
|
|
368
|
+
return res.rows.map((delivery) => ({
|
|
369
|
+
delivery,
|
|
370
|
+
webhook: webhooks.get(delivery.webhook_id),
|
|
371
|
+
event: events.get(delivery.event_id),
|
|
372
|
+
}));
|
|
201
373
|
});
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
const webhookRes = await client.query(`SELECT * FROM webhooks WHERE id = $1`, [locked.webhook_id]);
|
|
212
|
-
const eventRes = await client.query(`SELECT * FROM webhook_events WHERE id = $1`, [locked.event_id]);
|
|
213
|
-
if (webhookRes.rows.length === 0 || eventRes.rows.length === 0) {
|
|
214
|
-
// Webhook or event was deleted; mark failed
|
|
215
|
-
await client.query(`UPDATE webhook_deliveries
|
|
216
|
-
SET status = 'failed', last_error = 'Webhook or event not found', completed_at = now()
|
|
217
|
-
WHERE id = $1`, [locked.id]);
|
|
218
|
-
return;
|
|
219
|
-
}
|
|
220
|
-
const webhook = webhookRes.rows[0];
|
|
221
|
-
const event = eventRes.rows[0];
|
|
222
|
-
const attempts = locked.attempts + 1;
|
|
223
|
-
const result = await deliverWebhook(webhook, event, locked.id);
|
|
224
|
-
if (result.success) {
|
|
225
|
-
await client.query(`UPDATE webhook_deliveries
|
|
226
|
-
SET status = 'success', attempts = $1, response_code = $2,
|
|
227
|
-
last_error = NULL, completed_at = now()
|
|
228
|
-
WHERE id = $3`, [attempts, result.responseCode, locked.id]);
|
|
229
|
-
}
|
|
230
|
-
else if (attempts >= MAX_ATTEMPTS) {
|
|
231
|
-
await client.query(`UPDATE webhook_deliveries
|
|
232
|
-
SET status = 'failed', attempts = $1, response_code = $2,
|
|
233
|
-
last_error = $3, completed_at = now()
|
|
234
|
-
WHERE id = $4`, [attempts, result.responseCode, result.error, locked.id]);
|
|
235
|
-
}
|
|
236
|
-
else {
|
|
237
|
-
const nextRetryMs = retryDelayMs(attempts);
|
|
238
|
-
await client.query(`UPDATE webhook_deliveries
|
|
239
|
-
SET attempts = $1, response_code = $2, last_error = $3,
|
|
240
|
-
next_retry_at = now() + ($4 || ' milliseconds')::interval
|
|
241
|
-
WHERE id = $5`, [attempts, result.responseCode, result.error, nextRetryMs, locked.id]);
|
|
242
|
-
}
|
|
243
|
-
}).catch(() => {
|
|
244
|
-
// Per-delivery failures are non-fatal; continue processing others
|
|
245
|
-
});
|
|
374
|
+
}
|
|
375
|
+
async function deliverClaimed(pool, claimed) {
|
|
376
|
+
const { delivery, webhook, event } = claimed;
|
|
377
|
+
if (!webhook || !event) {
|
|
378
|
+
// Webhook or event was deleted; mark failed
|
|
379
|
+
await (0, pool_helpers_js_1.withClient)(pool, (client) => client.query(`UPDATE webhook_deliveries
|
|
380
|
+
SET status = 'failed', last_error = 'Webhook or event not found', completed_at = now()
|
|
381
|
+
WHERE id = $1 AND status = 'pending'`, [delivery.id]));
|
|
382
|
+
return;
|
|
246
383
|
}
|
|
384
|
+
// The attempt was already counted when the delivery was claimed.
|
|
385
|
+
const attempts = delivery.attempts;
|
|
386
|
+
const result = await deliverWebhook(webhook, event, delivery.id);
|
|
387
|
+
await (0, pool_helpers_js_1.withClient)(pool, async (client) => {
|
|
388
|
+
if (result.success) {
|
|
389
|
+
await client.query(`UPDATE webhook_deliveries
|
|
390
|
+
SET status = 'success', response_code = $1,
|
|
391
|
+
last_error = NULL, completed_at = now()
|
|
392
|
+
WHERE id = $2 AND status = 'pending'`, [result.responseCode, delivery.id]);
|
|
393
|
+
}
|
|
394
|
+
else if (attempts >= MAX_ATTEMPTS) {
|
|
395
|
+
await client.query(`UPDATE webhook_deliveries
|
|
396
|
+
SET status = 'failed', response_code = $1,
|
|
397
|
+
last_error = $2, completed_at = now()
|
|
398
|
+
WHERE id = $3 AND status = 'pending'`, [result.responseCode, result.error, delivery.id]);
|
|
399
|
+
}
|
|
400
|
+
else {
|
|
401
|
+
const nextRetryMs = retryDelayMs(attempts);
|
|
402
|
+
await client.query(`UPDATE webhook_deliveries
|
|
403
|
+
SET response_code = $1, last_error = $2,
|
|
404
|
+
next_retry_at = now() + ($3 || ' milliseconds')::interval
|
|
405
|
+
WHERE id = $4 AND status = 'pending'`, [result.responseCode, result.error, nextRetryMs, delivery.id]);
|
|
406
|
+
}
|
|
407
|
+
});
|
|
247
408
|
}
|
|
248
409
|
async function retryFailedDeliveries(pool, tenantId) {
|
|
249
410
|
const result = await (0, pool_helpers_js_1.withClient)(pool, async (client) => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"event-service.js","sourceRoot":"","sources":["../../src/services/event-service.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"event-service.js","sourceRoot":"","sources":["../../src/services/event-service.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,14 +1,31 @@
|
|
|
1
1
|
import pg from "pg";
|
|
2
|
+
/** A row that decrypts with neither the old key nor the new key. Rotation leaves it unchanged. */
|
|
3
|
+
export interface KeyRotationUnreadableRow {
|
|
4
|
+
table: "config_entries" | "webhooks";
|
|
5
|
+
id: string;
|
|
6
|
+
}
|
|
2
7
|
export interface KeyRotationResult {
|
|
3
8
|
config_entries_rotated: number;
|
|
4
9
|
webhooks_rotated: number;
|
|
10
|
+
/** Rows that already decrypt with the new key, for example after an interrupted run. */
|
|
11
|
+
already_rotated: number;
|
|
12
|
+
/** Rows that decrypt with neither key. */
|
|
13
|
+
unreadable: KeyRotationUnreadableRow[];
|
|
5
14
|
}
|
|
6
15
|
/**
|
|
7
16
|
* Re-encrypts all sensitive data (config entries and webhook secrets)
|
|
8
17
|
* from oldKey to newKey in batches, walking the primary key with a keyset
|
|
9
|
-
* cursor (id > lastId, ordered by id) so every row is
|
|
18
|
+
* cursor (id > lastId, ordered by id) so every row is visited exactly once.
|
|
10
19
|
* Each batch is its own transaction so locks are held briefly.
|
|
11
20
|
*
|
|
21
|
+
* The run is safe to repeat with the same keys. A value that already decrypts
|
|
22
|
+
* with the new key stays as it is and counts in `already_rotated`. A value that
|
|
23
|
+
* decrypts with neither key stays as it is and appears in `unreadable`.
|
|
24
|
+
*
|
|
25
|
+
* Throws a ValidationError when encrypted values exist and none of them
|
|
26
|
+
* decrypts with either key. That result almost always means `oldKeyMaterial`
|
|
27
|
+
* is wrong, and the run has changed no row.
|
|
28
|
+
*
|
|
12
29
|
* After rotation, update the STRATUM_ENCRYPTION_KEY environment variable to
|
|
13
30
|
* the new key.
|
|
14
31
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"key-rotation-service.d.ts","sourceRoot":"","sources":["../../src/services/key-rotation-service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,IAAI,CAAC;
|
|
1
|
+
{"version":3,"file":"key-rotation-service.d.ts","sourceRoot":"","sources":["../../src/services/key-rotation-service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,IAAI,CAAC;AAKpB,kGAAkG;AAClG,MAAM,WAAW,wBAAwB;IACvC,KAAK,EAAE,gBAAgB,GAAG,UAAU,CAAC;IACrC,EAAE,EAAE,MAAM,CAAC;CACZ;AAED,MAAM,WAAW,iBAAiB;IAChC,sBAAsB,EAAE,MAAM,CAAC;IAC/B,gBAAgB,EAAE,MAAM,CAAC;IACzB,wFAAwF;IACxF,eAAe,EAAE,MAAM,CAAC;IACxB,0CAA0C;IAC1C,UAAU,EAAE,wBAAwB,EAAE,CAAC;CACxC;AAmBD;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAsB,mBAAmB,CACvC,IAAI,EAAE,EAAE,CAAC,IAAI,EACb,cAAc,EAAE,MAAM,EACtB,cAAc,EAAE,MAAM,EACtB,SAAS,GAAE,MAAY,GACtB,OAAO,CAAC,iBAAiB,CAAC,CAmF5B"}
|
|
@@ -2,21 +2,44 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.rotateEncryptionKey = rotateEncryptionKey;
|
|
4
4
|
const pool_helpers_js_1 = require("../pool-helpers.js");
|
|
5
|
+
const core_1 = require("@stratum-hq/core");
|
|
5
6
|
const crypto_js_1 = require("../crypto.js");
|
|
6
7
|
// Lowest possible UUID; a keyset cursor starting here precedes every real row.
|
|
7
8
|
const ZERO_UUID = "00000000-0000-0000-0000-000000000000";
|
|
9
|
+
// A run that fails partway leaves earlier batches committed under the new key.
|
|
10
|
+
// Accepting those values, instead of failing on them, is what lets a re-run
|
|
11
|
+
// with the same keys finish the rotation.
|
|
12
|
+
function rotateValue(encrypted, oldKeyMaterial, newKeyMaterial) {
|
|
13
|
+
const plaintext = (0, crypto_js_1.decryptWithKeyMaterial)(encrypted, oldKeyMaterial);
|
|
14
|
+
if (plaintext !== null) {
|
|
15
|
+
return { kind: "rotated", value: (0, crypto_js_1.encryptWithKeyMaterial)(plaintext, newKeyMaterial) };
|
|
16
|
+
}
|
|
17
|
+
if ((0, crypto_js_1.decryptWithKeyMaterial)(encrypted, newKeyMaterial) !== null)
|
|
18
|
+
return { kind: "already_rotated" };
|
|
19
|
+
return { kind: "unreadable" };
|
|
20
|
+
}
|
|
8
21
|
/**
|
|
9
22
|
* Re-encrypts all sensitive data (config entries and webhook secrets)
|
|
10
23
|
* from oldKey to newKey in batches, walking the primary key with a keyset
|
|
11
|
-
* cursor (id > lastId, ordered by id) so every row is
|
|
24
|
+
* cursor (id > lastId, ordered by id) so every row is visited exactly once.
|
|
12
25
|
* Each batch is its own transaction so locks are held briefly.
|
|
13
26
|
*
|
|
27
|
+
* The run is safe to repeat with the same keys. A value that already decrypts
|
|
28
|
+
* with the new key stays as it is and counts in `already_rotated`. A value that
|
|
29
|
+
* decrypts with neither key stays as it is and appears in `unreadable`.
|
|
30
|
+
*
|
|
31
|
+
* Throws a ValidationError when encrypted values exist and none of them
|
|
32
|
+
* decrypts with either key. That result almost always means `oldKeyMaterial`
|
|
33
|
+
* is wrong, and the run has changed no row.
|
|
34
|
+
*
|
|
14
35
|
* After rotation, update the STRATUM_ENCRYPTION_KEY environment variable to
|
|
15
36
|
* the new key.
|
|
16
37
|
*/
|
|
17
38
|
async function rotateEncryptionKey(pool, oldKeyMaterial, newKeyMaterial, batchSize = 100) {
|
|
18
39
|
let configCount = 0;
|
|
19
40
|
let webhookCount = 0;
|
|
41
|
+
let alreadyRotated = 0;
|
|
42
|
+
const unreadable = [];
|
|
20
43
|
// Process config entries in batches, advancing a keyset cursor by id.
|
|
21
44
|
let lastConfigId = ZERO_UUID;
|
|
22
45
|
while (true) {
|
|
@@ -27,14 +50,21 @@ async function rotateEncryptionKey(pool, oldKeyMaterial, newKeyMaterial, batchSi
|
|
|
27
50
|
if (batch.rows.length === 0)
|
|
28
51
|
return 0;
|
|
29
52
|
for (const row of batch.rows) {
|
|
30
|
-
const
|
|
31
|
-
|
|
32
|
-
|
|
53
|
+
const outcome = rotateValue(row.value, oldKeyMaterial, newKeyMaterial);
|
|
54
|
+
if (outcome.kind === "already_rotated") {
|
|
55
|
+
alreadyRotated++;
|
|
56
|
+
}
|
|
57
|
+
else if (outcome.kind === "unreadable") {
|
|
58
|
+
unreadable.push({ table: "config_entries", id: row.id });
|
|
59
|
+
}
|
|
60
|
+
else {
|
|
61
|
+
await client.query(`UPDATE config_entries SET value = $1, updated_at = now() WHERE id = $2`, [JSON.stringify(outcome.value), row.id]);
|
|
62
|
+
configCount++;
|
|
63
|
+
}
|
|
33
64
|
}
|
|
34
65
|
lastConfigId = batch.rows[batch.rows.length - 1].id;
|
|
35
66
|
return batch.rows.length;
|
|
36
67
|
});
|
|
37
|
-
configCount += count;
|
|
38
68
|
if (count < batchSize)
|
|
39
69
|
break;
|
|
40
70
|
}
|
|
@@ -48,16 +78,34 @@ async function rotateEncryptionKey(pool, oldKeyMaterial, newKeyMaterial, batchSi
|
|
|
48
78
|
if (batch.rows.length === 0)
|
|
49
79
|
return 0;
|
|
50
80
|
for (const row of batch.rows) {
|
|
51
|
-
const
|
|
52
|
-
|
|
81
|
+
const outcome = rotateValue(row.secret_hash, oldKeyMaterial, newKeyMaterial);
|
|
82
|
+
if (outcome.kind === "already_rotated") {
|
|
83
|
+
alreadyRotated++;
|
|
84
|
+
}
|
|
85
|
+
else if (outcome.kind === "unreadable") {
|
|
86
|
+
unreadable.push({ table: "webhooks", id: row.id });
|
|
87
|
+
}
|
|
88
|
+
else {
|
|
89
|
+
await client.query(`UPDATE webhooks SET secret_hash = $1 WHERE id = $2`, [outcome.value, row.id]);
|
|
90
|
+
webhookCount++;
|
|
91
|
+
}
|
|
53
92
|
}
|
|
54
93
|
lastWebhookId = batch.rows[batch.rows.length - 1].id;
|
|
55
94
|
return batch.rows.length;
|
|
56
95
|
});
|
|
57
|
-
webhookCount += count;
|
|
58
96
|
if (count < batchSize)
|
|
59
97
|
break;
|
|
60
98
|
}
|
|
61
|
-
|
|
99
|
+
// A run that changed nothing and matched no value on either key must not look
|
|
100
|
+
// like a success, because the operator would then retire a key that is still in use.
|
|
101
|
+
if (unreadable.length > 0 && configCount + webhookCount + alreadyRotated === 0) {
|
|
102
|
+
throw new core_1.ValidationError("Key rotation found no encrypted value that decrypts with the old key or the new key. Check the old key. No row was changed.", { unreadable: unreadable.length });
|
|
103
|
+
}
|
|
104
|
+
return {
|
|
105
|
+
config_entries_rotated: configCount,
|
|
106
|
+
webhooks_rotated: webhookCount,
|
|
107
|
+
already_rotated: alreadyRotated,
|
|
108
|
+
unreadable,
|
|
109
|
+
};
|
|
62
110
|
}
|
|
63
111
|
//# sourceMappingURL=key-rotation-service.js.map
|