@stratum-hq/lib 0.6.0 → 1.0.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.
Files changed (95) hide show
  1. package/dist/index.d.ts +1 -0
  2. package/dist/index.d.ts.map +1 -1
  3. package/dist/index.js +28 -1
  4. package/dist/index.js.map +1 -1
  5. package/dist/migrations/019_rls_policies.sql +236 -0
  6. package/dist/pool-helpers.d.ts.map +1 -1
  7. package/dist/pool-helpers.js +31 -1
  8. package/dist/pool-helpers.js.map +1 -1
  9. package/dist/services/api-key-service.d.ts.map +1 -1
  10. package/dist/services/api-key-service.js +4 -1
  11. package/dist/services/api-key-service.js.map +1 -1
  12. package/dist/services/config-service.js +2 -2
  13. package/dist/services/config-service.js.map +1 -1
  14. package/dist/services/key-rotation-service.js +1 -1
  15. package/dist/services/key-rotation-service.js.map +1 -1
  16. package/dist/services/role-service.d.ts +13 -3
  17. package/dist/services/role-service.d.ts.map +1 -1
  18. package/dist/services/role-service.js +18 -5
  19. package/dist/services/role-service.js.map +1 -1
  20. package/dist/services/tenant-service.d.ts.map +1 -1
  21. package/dist/services/tenant-service.js +12 -2
  22. package/dist/services/tenant-service.js.map +1 -1
  23. package/dist/stratum.d.ts +4 -4
  24. package/dist/stratum.d.ts.map +1 -1
  25. package/dist/stratum.js +1 -1
  26. package/dist/stratum.js.map +1 -1
  27. package/package.json +8 -1
  28. package/dist/__tests__/crypto.test.d.ts +0 -2
  29. package/dist/__tests__/crypto.test.d.ts.map +0 -1
  30. package/dist/__tests__/crypto.test.js +0 -41
  31. package/dist/__tests__/crypto.test.js.map +0 -1
  32. package/dist/__tests__/migrate-schemas.test.d.ts +0 -2
  33. package/dist/__tests__/migrate-schemas.test.d.ts.map +0 -1
  34. package/dist/__tests__/migrate-schemas.test.js +0 -225
  35. package/dist/__tests__/migrate-schemas.test.js.map +0 -1
  36. package/dist/__tests__/stratum-als.test.d.ts +0 -2
  37. package/dist/__tests__/stratum-als.test.d.ts.map +0 -1
  38. package/dist/__tests__/stratum-als.test.js +0 -49
  39. package/dist/__tests__/stratum-als.test.js.map +0 -1
  40. package/dist/__tests__/webhook-signature.test.d.ts +0 -2
  41. package/dist/__tests__/webhook-signature.test.d.ts.map +0 -1
  42. package/dist/__tests__/webhook-signature.test.js +0 -103
  43. package/dist/__tests__/webhook-signature.test.js.map +0 -1
  44. package/dist/services/__tests__/abac-service.test.d.ts +0 -2
  45. package/dist/services/__tests__/abac-service.test.d.ts.map +0 -1
  46. package/dist/services/__tests__/abac-service.test.js +0 -108
  47. package/dist/services/__tests__/abac-service.test.js.map +0 -1
  48. package/dist/services/__tests__/api-key-service.test.d.ts +0 -2
  49. package/dist/services/__tests__/api-key-service.test.d.ts.map +0 -1
  50. package/dist/services/__tests__/api-key-service.test.js +0 -76
  51. package/dist/services/__tests__/api-key-service.test.js.map +0 -1
  52. package/dist/services/__tests__/audit-service.test.d.ts +0 -2
  53. package/dist/services/__tests__/audit-service.test.d.ts.map +0 -1
  54. package/dist/services/__tests__/audit-service.test.js +0 -230
  55. package/dist/services/__tests__/audit-service.test.js.map +0 -1
  56. package/dist/services/__tests__/config-service.test.d.ts +0 -2
  57. package/dist/services/__tests__/config-service.test.d.ts.map +0 -1
  58. package/dist/services/__tests__/config-service.test.js +0 -565
  59. package/dist/services/__tests__/config-service.test.js.map +0 -1
  60. package/dist/services/__tests__/consent-service.test.d.ts +0 -2
  61. package/dist/services/__tests__/consent-service.test.d.ts.map +0 -1
  62. package/dist/services/__tests__/consent-service.test.js +0 -169
  63. package/dist/services/__tests__/consent-service.test.js.map +0 -1
  64. package/dist/services/__tests__/event-service.test.d.ts +0 -2
  65. package/dist/services/__tests__/event-service.test.d.ts.map +0 -1
  66. package/dist/services/__tests__/event-service.test.js +0 -193
  67. package/dist/services/__tests__/event-service.test.js.map +0 -1
  68. package/dist/services/__tests__/key-rotation-service.test.d.ts +0 -2
  69. package/dist/services/__tests__/key-rotation-service.test.d.ts.map +0 -1
  70. package/dist/services/__tests__/key-rotation-service.test.js +0 -132
  71. package/dist/services/__tests__/key-rotation-service.test.js.map +0 -1
  72. package/dist/services/__tests__/permission-service.test.d.ts +0 -2
  73. package/dist/services/__tests__/permission-service.test.d.ts.map +0 -1
  74. package/dist/services/__tests__/permission-service.test.js +0 -480
  75. package/dist/services/__tests__/permission-service.test.js.map +0 -1
  76. package/dist/services/__tests__/retention-service.test.d.ts +0 -2
  77. package/dist/services/__tests__/retention-service.test.d.ts.map +0 -1
  78. package/dist/services/__tests__/retention-service.test.js +0 -152
  79. package/dist/services/__tests__/retention-service.test.js.map +0 -1
  80. package/dist/services/__tests__/role-service.test.d.ts +0 -2
  81. package/dist/services/__tests__/role-service.test.d.ts.map +0 -1
  82. package/dist/services/__tests__/role-service.test.js +0 -134
  83. package/dist/services/__tests__/role-service.test.js.map +0 -1
  84. package/dist/services/__tests__/tenant-service.test.d.ts +0 -2
  85. package/dist/services/__tests__/tenant-service.test.d.ts.map +0 -1
  86. package/dist/services/__tests__/tenant-service.test.js +0 -548
  87. package/dist/services/__tests__/tenant-service.test.js.map +0 -1
  88. package/dist/services/__tests__/test-helpers.d.ts +0 -9
  89. package/dist/services/__tests__/test-helpers.d.ts.map +0 -1
  90. package/dist/services/__tests__/test-helpers.js +0 -19
  91. package/dist/services/__tests__/test-helpers.js.map +0 -1
  92. package/dist/services/__tests__/webhook-service.test.d.ts +0 -2
  93. package/dist/services/__tests__/webhook-service.test.d.ts.map +0 -1
  94. package/dist/services/__tests__/webhook-service.test.js +0 -184
  95. package/dist/services/__tests__/webhook-service.test.js.map +0 -1
@@ -1,169 +0,0 @@
1
- "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
7
- }
8
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
- Object.defineProperty(o, "default", { enumerable: true, value: v });
15
- }) : function(o, v) {
16
- o["default"] = v;
17
- });
18
- var __importStar = (this && this.__importStar) || (function () {
19
- var ownKeys = function(o) {
20
- ownKeys = Object.getOwnPropertyNames || function (o) {
21
- var ar = [];
22
- for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
- return ar;
24
- };
25
- return ownKeys(o);
26
- };
27
- return function (mod) {
28
- if (mod && mod.__esModule) return mod;
29
- var result = {};
30
- if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
- __setModuleDefault(result, mod);
32
- return result;
33
- };
34
- })();
35
- Object.defineProperty(exports, "__esModule", { value: true });
36
- const vitest_1 = require("vitest");
37
- // Mock pool-helpers before importing consent-service
38
- vitest_1.vi.mock("../../pool-helpers.js", () => ({
39
- withClient: vitest_1.vi.fn(),
40
- withTransaction: vitest_1.vi.fn(),
41
- }));
42
- const poolHelpers = __importStar(require("../../pool-helpers.js"));
43
- const consentService = __importStar(require("../consent-service.js"));
44
- function makeMockPool() {
45
- return {};
46
- }
47
- const mockConsentRecord = {
48
- id: "550e8400-e29b-41d4-a716-446655440000",
49
- tenant_id: "tenant-456",
50
- subject_id: "user-789",
51
- purpose: "data_processing",
52
- granted: true,
53
- granted_at: "2024-01-01T00:00:00.000Z",
54
- revoked_at: null,
55
- expires_at: null,
56
- metadata: {},
57
- created_at: "2024-01-01T00:00:00.000Z",
58
- updated_at: "2024-01-01T00:00:00.000Z",
59
- };
60
- (0, vitest_1.beforeEach)(() => {
61
- vitest_1.vi.clearAllMocks();
62
- });
63
- (0, vitest_1.describe)("grantConsent", () => {
64
- (0, vitest_1.it)("inserts a consent record and returns it", async () => {
65
- const pool = makeMockPool();
66
- const mockQuery = vitest_1.vi.fn().mockResolvedValue({ rows: [mockConsentRecord] });
67
- vitest_1.vi.mocked(poolHelpers.withTransaction).mockImplementation(async (_pool, fn) => {
68
- const client = {
69
- query: mockQuery,
70
- };
71
- return fn(client);
72
- });
73
- const input = {
74
- subject_id: "user-789",
75
- purpose: "data_processing",
76
- };
77
- const result = await consentService.grantConsent(pool, "tenant-456", input);
78
- (0, vitest_1.expect)(result).toEqual(mockConsentRecord);
79
- (0, vitest_1.expect)(mockQuery).toHaveBeenCalledTimes(1);
80
- const [sql, params] = mockQuery.mock.calls[0];
81
- (0, vitest_1.expect)(sql).toContain("INSERT INTO consent_records");
82
- (0, vitest_1.expect)(sql).toContain("ON CONFLICT");
83
- (0, vitest_1.expect)(params[0]).toBe("tenant-456"); // tenant_id
84
- (0, vitest_1.expect)(params[1]).toBe("user-789"); // subject_id
85
- (0, vitest_1.expect)(params[2]).toBe("data_processing"); // purpose
86
- });
87
- (0, vitest_1.it)("passes expires_at and metadata when provided", async () => {
88
- const pool = makeMockPool();
89
- const mockQuery = vitest_1.vi.fn().mockResolvedValue({ rows: [mockConsentRecord] });
90
- vitest_1.vi.mocked(poolHelpers.withTransaction).mockImplementation(async (_pool, fn) => {
91
- const client = {
92
- query: mockQuery,
93
- };
94
- return fn(client);
95
- });
96
- const input = {
97
- subject_id: "user-789",
98
- purpose: "analytics",
99
- expires_at: "2025-12-31T23:59:59.000Z",
100
- metadata: { source: "web" },
101
- };
102
- await consentService.grantConsent(pool, "tenant-456", input);
103
- const params = mockQuery.mock.calls[0][1];
104
- (0, vitest_1.expect)(params[3]).toBe("2025-12-31T23:59:59.000Z"); // expires_at
105
- (0, vitest_1.expect)(params[4]).toBe(JSON.stringify({ source: "web" })); // metadata
106
- });
107
- });
108
- (0, vitest_1.describe)("revokeConsent", () => {
109
- (0, vitest_1.it)("returns true when a record is revoked", async () => {
110
- const pool = makeMockPool();
111
- const mockQuery = vitest_1.vi.fn().mockResolvedValue({ rowCount: 1, rows: [{ id: "some-id" }] });
112
- vitest_1.vi.mocked(poolHelpers.withClient).mockImplementation(async (_pool, fn) => {
113
- const client = {
114
- query: mockQuery,
115
- };
116
- return fn(client);
117
- });
118
- const result = await consentService.revokeConsent(pool, "tenant-456", "user-789", "data_processing");
119
- (0, vitest_1.expect)(result).toBe(true);
120
- const [sql, params] = mockQuery.mock.calls[0];
121
- (0, vitest_1.expect)(sql).toContain("UPDATE consent_records");
122
- (0, vitest_1.expect)(sql).toContain("granted = false");
123
- (0, vitest_1.expect)(params).toEqual(["tenant-456", "user-789", "data_processing"]);
124
- });
125
- (0, vitest_1.it)("returns false when no record matches", async () => {
126
- const pool = makeMockPool();
127
- const mockQuery = vitest_1.vi.fn().mockResolvedValue({ rowCount: 0, rows: [] });
128
- vitest_1.vi.mocked(poolHelpers.withClient).mockImplementation(async (_pool, fn) => {
129
- const client = {
130
- query: mockQuery,
131
- };
132
- return fn(client);
133
- });
134
- const result = await consentService.revokeConsent(pool, "tenant-456", "user-789", "nonexistent");
135
- (0, vitest_1.expect)(result).toBe(false);
136
- });
137
- });
138
- (0, vitest_1.describe)("listConsent", () => {
139
- (0, vitest_1.it)("returns all consent records for a tenant", async () => {
140
- const pool = makeMockPool();
141
- const mockQuery = vitest_1.vi.fn().mockResolvedValue({ rows: [mockConsentRecord] });
142
- vitest_1.vi.mocked(poolHelpers.withClient).mockImplementation(async (_pool, fn) => {
143
- const client = {
144
- query: mockQuery,
145
- };
146
- return fn(client);
147
- });
148
- const result = await consentService.listConsent(pool, "tenant-456");
149
- (0, vitest_1.expect)(result).toEqual([mockConsentRecord]);
150
- const [sql, params] = mockQuery.mock.calls[0];
151
- (0, vitest_1.expect)(sql).toContain("FROM consent_records");
152
- (0, vitest_1.expect)(params).toEqual(["tenant-456"]);
153
- });
154
- (0, vitest_1.it)("filters by subject_id when provided", async () => {
155
- const pool = makeMockPool();
156
- const mockQuery = vitest_1.vi.fn().mockResolvedValue({ rows: [mockConsentRecord] });
157
- vitest_1.vi.mocked(poolHelpers.withClient).mockImplementation(async (_pool, fn) => {
158
- const client = {
159
- query: mockQuery,
160
- };
161
- return fn(client);
162
- });
163
- await consentService.listConsent(pool, "tenant-456", "user-789");
164
- const [sql, params] = mockQuery.mock.calls[0];
165
- (0, vitest_1.expect)(sql).toContain("subject_id = $2");
166
- (0, vitest_1.expect)(params).toEqual(["tenant-456", "user-789"]);
167
- });
168
- });
169
- //# sourceMappingURL=consent-service.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"consent-service.test.js","sourceRoot":"","sources":["../../../src/services/__tests__/consent-service.test.ts"],"names":[],"mappings":"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"}
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=event-service.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"event-service.test.d.ts","sourceRoot":"","sources":["../../../src/services/__tests__/event-service.test.ts"],"names":[],"mappings":""}
@@ -1,193 +0,0 @@
1
- "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
7
- }
8
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
- Object.defineProperty(o, "default", { enumerable: true, value: v });
15
- }) : function(o, v) {
16
- o["default"] = v;
17
- });
18
- var __importStar = (this && this.__importStar) || (function () {
19
- var ownKeys = function(o) {
20
- ownKeys = Object.getOwnPropertyNames || function (o) {
21
- var ar = [];
22
- for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
- return ar;
24
- };
25
- return ownKeys(o);
26
- };
27
- return function (mod) {
28
- if (mod && mod.__esModule) return mod;
29
- var result = {};
30
- if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
- __setModuleDefault(result, mod);
32
- return result;
33
- };
34
- })();
35
- var __importDefault = (this && this.__importDefault) || function (mod) {
36
- return (mod && mod.__esModule) ? mod : { "default": mod };
37
- };
38
- Object.defineProperty(exports, "__esModule", { value: true });
39
- const vitest_1 = require("vitest");
40
- const node_crypto_1 = __importDefault(require("node:crypto"));
41
- // Mock pool-helpers before importing event-service
42
- vitest_1.vi.mock("../../pool-helpers.js", () => ({
43
- withClient: vitest_1.vi.fn(),
44
- withTransaction: vitest_1.vi.fn(),
45
- }));
46
- // Mock webhook-service
47
- vitest_1.vi.mock("../webhook-service.js", () => ({
48
- getWebhooksForEvent: vitest_1.vi.fn(),
49
- decryptSecret: vitest_1.vi.fn().mockReturnValue("decrypted-test-secret"),
50
- }));
51
- const poolHelpers = __importStar(require("../../pool-helpers.js"));
52
- const webhookServiceMock = __importStar(require("../webhook-service.js"));
53
- const eventService = __importStar(require("../event-service.js"));
54
- const core_1 = require("@stratum-hq/core");
55
- function makeMockPool() {
56
- return {};
57
- }
58
- function signPayload(secret, payload) {
59
- return "sha256=" + node_crypto_1.default.createHmac("sha256", secret).update(payload).digest("hex");
60
- }
61
- (0, vitest_1.beforeEach)(() => {
62
- vitest_1.vi.clearAllMocks();
63
- });
64
- (0, vitest_1.describe)("HMAC signature generation", () => {
65
- (0, vitest_1.it)("produces sha256= prefixed signature", () => {
66
- const sig = signPayload("mysecretkey", "payload-body");
67
- (0, vitest_1.expect)(sig).toMatch(/^sha256=[0-9a-f]{64}$/);
68
- });
69
- (0, vitest_1.it)("same secret and payload produce same signature", () => {
70
- const sig1 = signPayload("mysecretkey", "payload-body");
71
- const sig2 = signPayload("mysecretkey", "payload-body");
72
- (0, vitest_1.expect)(sig1).toBe(sig2);
73
- });
74
- (0, vitest_1.it)("different secrets produce different signatures", () => {
75
- const sig1 = signPayload("secret-one-key", "payload-body");
76
- const sig2 = signPayload("secret-two-key", "payload-body");
77
- (0, vitest_1.expect)(sig1).not.toBe(sig2);
78
- });
79
- (0, vitest_1.it)("different payloads produce different signatures", () => {
80
- const sig1 = signPayload("mysecretkey", "payload-one");
81
- const sig2 = signPayload("mysecretkey", "payload-two");
82
- (0, vitest_1.expect)(sig1).not.toBe(sig2);
83
- });
84
- });
85
- (0, vitest_1.describe)("webhook egress filter (SSRF protection)", () => {
86
- // Regression: bracketed IPv6 literals must be rejected in every notation.
87
- // The URL parser exposes IPv6 hosts wrapped in brackets, so a filter that
88
- // only matches the unbracketed textual form lets internal targets through.
89
- const mustReject = [
90
- ["bracketed IPv6 loopback", "http://[::1]/hook"],
91
- ["expanded IPv6 loopback", "http://[0:0:0:0:0:0:0:1]/hook"],
92
- ["IPv6 link-local", "http://[fe80::1]/hook"],
93
- ["IPv6 unique-local", "http://[fd00:ec2::254]/hook"],
94
- ["IPv4-mapped loopback", "http://[::ffff:127.0.0.1]/hook"],
95
- ["IPv4-mapped metadata address", "http://[::ffff:169.254.169.254]/hook"],
96
- ["unspecified IPv6 address", "http://[::]/hook"],
97
- ["integer-coerced loopback", "http://2130706433/hook"],
98
- ];
99
- for (const [label, url] of mustReject) {
100
- (0, vitest_1.it)(`rejects ${label}`, () => {
101
- (0, vitest_1.expect)(() => eventService.validateWebhookUrl(url)).toThrow();
102
- });
103
- }
104
- // Unbracketed forms that already worked must keep working.
105
- (0, vitest_1.it)("still rejects IPv4 loopback and metadata", () => {
106
- (0, vitest_1.expect)(() => eventService.validateWebhookUrl("http://127.0.0.1/hook")).toThrow();
107
- (0, vitest_1.expect)(() => eventService.validateWebhookUrl("http://169.254.169.254/hook")).toThrow();
108
- (0, vitest_1.expect)(() => eventService.validateWebhookUrl("http://localhost/hook")).toThrow();
109
- });
110
- (0, vitest_1.it)("allows a public https target", () => {
111
- (0, vitest_1.expect)(() => eventService.validateWebhookUrl("https://example.com/hook")).not.toThrow();
112
- });
113
- (0, vitest_1.it)("fails closed on an unparseable URL", () => {
114
- (0, vitest_1.expect)(() => eventService.validateWebhookUrl("http://[not-an-ip/hook")).toThrow();
115
- });
116
- });
117
- (0, vitest_1.describe)("retry backoff calculation", () => {
118
- // attempts^2 * 5000ms
119
- const cases = [
120
- [1, 5000],
121
- [2, 20000],
122
- [3, 45000],
123
- [4, 80000],
124
- [5, 125000],
125
- ];
126
- for (const [attempts, expectedMs] of cases) {
127
- (0, vitest_1.it)(`attempt ${attempts} => ${expectedMs}ms delay`, () => {
128
- const delayMs = Math.pow(attempts, 2) * 5000;
129
- (0, vitest_1.expect)(delayMs).toBe(expectedMs);
130
- });
131
- }
132
- });
133
- (0, vitest_1.describe)("emitEvent", () => {
134
- (0, vitest_1.it)("inserts event record and creates delivery records for matching webhooks", async () => {
135
- const pool = makeMockPool();
136
- const mockEvent = {
137
- id: "event-id-1",
138
- type: "tenant.created",
139
- tenant_id: "tenant-id-1",
140
- data: {},
141
- created_at: "2024-01-01T00:00:00.000Z",
142
- };
143
- const mockWebhook = {
144
- id: "webhook-id-1",
145
- tenant_id: null,
146
- url: "https://example.com/hook",
147
- secret_hash: "abc123",
148
- events: ["tenant.created"],
149
- active: true,
150
- created_at: "2024-01-01T00:00:00.000Z",
151
- updated_at: "2024-01-01T00:00:00.000Z",
152
- };
153
- const insertEventQuery = vitest_1.vi.fn().mockResolvedValue({ rows: [mockEvent] });
154
- const insertDeliveryQuery = vitest_1.vi.fn().mockResolvedValue({ rows: [] });
155
- // First withClient call: insert event
156
- // Second withClient call: insert deliveries
157
- vitest_1.vi.mocked(poolHelpers.withClient)
158
- .mockImplementationOnce(async (_pool, fn) => {
159
- const client = { query: insertEventQuery };
160
- return fn(client);
161
- })
162
- .mockImplementationOnce(async (_pool, fn) => {
163
- const client = { query: insertDeliveryQuery };
164
- return fn(client);
165
- });
166
- vitest_1.vi.mocked(webhookServiceMock.getWebhooksForEvent).mockResolvedValue([mockWebhook]);
167
- await eventService.emitEvent(pool, core_1.TenantEvent.TENANT_CREATED, "tenant-id-1", { tenant: {} });
168
- (0, vitest_1.expect)(insertEventQuery).toHaveBeenCalledOnce();
169
- (0, vitest_1.expect)(webhookServiceMock.getWebhooksForEvent).toHaveBeenCalledWith(pool, core_1.TenantEvent.TENANT_CREATED, "tenant-id-1");
170
- (0, vitest_1.expect)(insertDeliveryQuery).toHaveBeenCalledWith(vitest_1.expect.stringContaining("INSERT INTO webhook_deliveries"), ["webhook-id-1", "event-id-1"]);
171
- });
172
- (0, vitest_1.it)("does not create deliveries when no matching webhooks", async () => {
173
- const pool = makeMockPool();
174
- const mockEvent = {
175
- id: "event-id-2",
176
- type: "tenant.created",
177
- tenant_id: "tenant-id-2",
178
- data: {},
179
- created_at: "2024-01-01T00:00:00.000Z",
180
- };
181
- vitest_1.vi.mocked(poolHelpers.withClient).mockImplementationOnce(async (_pool, fn) => {
182
- const client = {
183
- query: vitest_1.vi.fn().mockResolvedValue({ rows: [mockEvent] }),
184
- };
185
- return fn(client);
186
- });
187
- vitest_1.vi.mocked(webhookServiceMock.getWebhooksForEvent).mockResolvedValue([]);
188
- await eventService.emitEvent(pool, core_1.TenantEvent.TENANT_CREATED, "tenant-id-2", {});
189
- // withClient should only have been called once (event insert), not again for deliveries
190
- (0, vitest_1.expect)(poolHelpers.withClient).toHaveBeenCalledOnce();
191
- });
192
- });
193
- //# sourceMappingURL=event-service.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"event-service.test.js","sourceRoot":"","sources":["../../../src/services/__tests__/event-service.test.ts"],"names":[],"mappings":"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"}
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=key-rotation-service.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"key-rotation-service.test.d.ts","sourceRoot":"","sources":["../../../src/services/__tests__/key-rotation-service.test.ts"],"names":[],"mappings":""}
@@ -1,132 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- const vitest_1 = require("vitest");
4
- const key_rotation_service_js_1 = require("../key-rotation-service.js");
5
- const crypto_js_1 = require("../../crypto.js");
6
- function paramFor(sql, re, params) {
7
- const m = sql.match(re);
8
- return m ? params[Number(m[1]) - 1] : undefined;
9
- }
10
- function makeFakePool(store) {
11
- const client = {
12
- query: async (sql, params = []) => {
13
- const s = sql.trim();
14
- if (/^(BEGIN|COMMIT|ROLLBACK|RESET|SET)\b/.test(s)) {
15
- return { rows: [], rowCount: 0 };
16
- }
17
- const limit = Number(paramFor(s, /LIMIT \$(\d+)/, params));
18
- const gtId = paramFor(s, /id > \$(\d+)/, params);
19
- const ordered = /ORDER BY id/.test(s);
20
- // The previous query tried to exclude already-rotated rows with a
21
- // `value NOT LIKE 'rotated:%'` predicate. Emulate that literally.
22
- const excludeRotatedPrefix = /NOT LIKE 'rotated:%'/.test(s);
23
- const byId = (rows) => ordered
24
- ? [...rows].sort((a, b) => (a.id < b.id ? -1 : a.id > b.id ? 1 : 0))
25
- : rows;
26
- if (/SELECT id, value FROM config_entries/.test(s)) {
27
- let rows = store.config.filter((r) => r.sensitive === true);
28
- if (excludeRotatedPrefix)
29
- rows = rows.filter((r) => !r.value.startsWith("rotated:"));
30
- if (gtId !== undefined)
31
- rows = rows.filter((r) => r.id > gtId);
32
- rows = byId(rows).slice(0, limit);
33
- return {
34
- rows: rows.map((r) => ({ id: r.id, value: r.value })),
35
- rowCount: rows.length,
36
- };
37
- }
38
- if (/UPDATE config_entries SET value/.test(s)) {
39
- const [value, id] = params;
40
- const row = store.config.find((r) => r.id === id);
41
- if (row)
42
- row.value = value;
43
- return { rows: [], rowCount: row ? 1 : 0 };
44
- }
45
- if (/SELECT id, secret_hash FROM webhooks/.test(s)) {
46
- let rows = store.webhooks.filter((r) => r.secret_hash != null);
47
- if (gtId !== undefined)
48
- rows = rows.filter((r) => r.id > gtId);
49
- rows = byId(rows).slice(0, limit);
50
- return {
51
- rows: rows.map((r) => ({ id: r.id, secret_hash: r.secret_hash })),
52
- rowCount: rows.length,
53
- };
54
- }
55
- if (/UPDATE webhooks SET secret_hash/.test(s)) {
56
- const [secret, id] = params;
57
- const row = store.webhooks.find((r) => r.id === id);
58
- if (row)
59
- row.secret_hash = secret;
60
- return { rows: [], rowCount: row ? 1 : 0 };
61
- }
62
- throw new Error(`unexpected SQL in test double: ${s}`);
63
- },
64
- release: () => { },
65
- };
66
- return { connect: async () => client };
67
- }
68
- // Deterministic ascending ids, all strictly greater than the zero UUID so a
69
- // keyset cursor starting there sees every row.
70
- function seedId(i) {
71
- return `00000000-0000-0000-0000-${String(i + 1).padStart(12, "0")}`;
72
- }
73
- const OLD_KEY = "old-key-material-abc";
74
- const NEW_KEY = "new-key-material-xyz";
75
- (0, vitest_1.describe)("rotateEncryptionKey batching", () => {
76
- const savedEnv = { ...process.env };
77
- (0, vitest_1.beforeEach)(() => {
78
- delete process.env.STRATUM_ENCRYPTION_KEY_PREVIOUS;
79
- });
80
- (0, vitest_1.afterEach)(() => {
81
- process.env = { ...savedEnv };
82
- });
83
- (0, vitest_1.it)("re-encrypts every sensitive config row exactly once past the first batch", async () => {
84
- const batchSize = 100;
85
- const total = 250; // spans three batches
86
- // Seed rows encrypted under the old key.
87
- process.env.STRATUM_ENCRYPTION_KEY = OLD_KEY;
88
- const plaintexts = [];
89
- const config = [];
90
- for (let i = 0; i < total; i++) {
91
- const pt = `config-secret-${i}`;
92
- plaintexts.push(pt);
93
- config.push({
94
- id: seedId(i),
95
- value: JSON.stringify((0, crypto_js_1.encrypt)(pt)),
96
- sensitive: true,
97
- });
98
- }
99
- const store = { config, webhooks: [] };
100
- const pool = makeFakePool(store);
101
- const result = await (0, key_rotation_service_js_1.rotateEncryptionKey)(pool, OLD_KEY, NEW_KEY, batchSize);
102
- (0, vitest_1.expect)(result.config_entries_rotated).toBe(total);
103
- // Every row must now decrypt under the NEW key back to its original
104
- // plaintext — i.e. rotated exactly once, none skipped or double-encrypted.
105
- process.env.STRATUM_ENCRYPTION_KEY = NEW_KEY;
106
- for (let i = 0; i < total; i++) {
107
- const blob = JSON.parse(store.config[i].value);
108
- (0, vitest_1.expect)((0, crypto_js_1.decrypt)(blob)).toBe(plaintexts[i]);
109
- }
110
- });
111
- (0, vitest_1.it)("re-encrypts every webhook secret exactly once past the first batch", async () => {
112
- const batchSize = 100;
113
- const total = 250;
114
- process.env.STRATUM_ENCRYPTION_KEY = OLD_KEY;
115
- const plaintexts = [];
116
- const webhooks = [];
117
- for (let i = 0; i < total; i++) {
118
- const pt = `webhook-secret-${i}`;
119
- plaintexts.push(pt);
120
- webhooks.push({ id: seedId(i), secret_hash: (0, crypto_js_1.encrypt)(pt) });
121
- }
122
- const store = { config: [], webhooks };
123
- const pool = makeFakePool(store);
124
- const result = await (0, key_rotation_service_js_1.rotateEncryptionKey)(pool, OLD_KEY, NEW_KEY, batchSize);
125
- (0, vitest_1.expect)(result.webhooks_rotated).toBe(total);
126
- process.env.STRATUM_ENCRYPTION_KEY = NEW_KEY;
127
- for (let i = 0; i < total; i++) {
128
- (0, vitest_1.expect)((0, crypto_js_1.decrypt)(store.webhooks[i].secret_hash)).toBe(plaintexts[i]);
129
- }
130
- });
131
- });
132
- //# sourceMappingURL=key-rotation-service.test.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"key-rotation-service.test.js","sourceRoot":"","sources":["../../../src/services/__tests__/key-rotation-service.test.ts"],"names":[],"mappings":"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"}
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=permission-service.test.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"permission-service.test.d.ts","sourceRoot":"","sources":["../../../src/services/__tests__/permission-service.test.ts"],"names":[],"mappings":""}