@stratum-hq/lib 0.7.0 → 1.1.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 (119) hide show
  1. package/README.md +109 -0
  2. package/dist/index.d.ts +6 -1
  3. package/dist/index.d.ts.map +1 -1
  4. package/dist/index.js +36 -1
  5. package/dist/index.js.map +1 -1
  6. package/dist/migrations/020_usage_events.sql +55 -0
  7. package/dist/migrations/021_tenant_status_suspended.sql +12 -0
  8. package/dist/scoped-job.d.ts +57 -0
  9. package/dist/scoped-job.d.ts.map +1 -0
  10. package/dist/scoped-job.js +56 -0
  11. package/dist/scoped-job.js.map +1 -0
  12. package/dist/services/api-key-service.d.ts.map +1 -1
  13. package/dist/services/api-key-service.js +4 -1
  14. package/dist/services/api-key-service.js.map +1 -1
  15. package/dist/services/audit-service.d.ts +9 -1
  16. package/dist/services/audit-service.d.ts.map +1 -1
  17. package/dist/services/audit-service.js +18 -0
  18. package/dist/services/audit-service.js.map +1 -1
  19. package/dist/services/config-service.js +2 -2
  20. package/dist/services/config-service.js.map +1 -1
  21. package/dist/services/event-service.d.ts +1 -1
  22. package/dist/services/event-service.d.ts.map +1 -1
  23. package/dist/services/event-service.js +7 -6
  24. package/dist/services/event-service.js.map +1 -1
  25. package/dist/services/key-rotation-service.js +1 -1
  26. package/dist/services/key-rotation-service.js.map +1 -1
  27. package/dist/services/rate-limit-service.d.ts +135 -0
  28. package/dist/services/rate-limit-service.d.ts.map +1 -0
  29. package/dist/services/rate-limit-service.js +113 -0
  30. package/dist/services/rate-limit-service.js.map +1 -0
  31. package/dist/services/role-service.d.ts +13 -3
  32. package/dist/services/role-service.d.ts.map +1 -1
  33. package/dist/services/role-service.js +18 -5
  34. package/dist/services/role-service.js.map +1 -1
  35. package/dist/services/tenant-service.d.ts +34 -0
  36. package/dist/services/tenant-service.d.ts.map +1 -1
  37. package/dist/services/tenant-service.js +159 -11
  38. package/dist/services/tenant-service.js.map +1 -1
  39. package/dist/services/usage-service.d.ts +18 -0
  40. package/dist/services/usage-service.d.ts.map +1 -0
  41. package/dist/services/usage-service.js +80 -0
  42. package/dist/services/usage-service.js.map +1 -0
  43. package/dist/services/webhook-service.d.ts +9 -1
  44. package/dist/services/webhook-service.d.ts.map +1 -1
  45. package/dist/services/webhook-service.js +51 -0
  46. package/dist/services/webhook-service.js.map +1 -1
  47. package/dist/stratum.d.ts +51 -4
  48. package/dist/stratum.d.ts.map +1 -1
  49. package/dist/stratum.js +95 -1
  50. package/dist/stratum.js.map +1 -1
  51. package/package.json +9 -1
  52. package/dist/__tests__/crypto.test.d.ts +0 -2
  53. package/dist/__tests__/crypto.test.d.ts.map +0 -1
  54. package/dist/__tests__/crypto.test.js +0 -41
  55. package/dist/__tests__/crypto.test.js.map +0 -1
  56. package/dist/__tests__/migrate-schemas.test.d.ts +0 -2
  57. package/dist/__tests__/migrate-schemas.test.d.ts.map +0 -1
  58. package/dist/__tests__/migrate-schemas.test.js +0 -225
  59. package/dist/__tests__/migrate-schemas.test.js.map +0 -1
  60. package/dist/__tests__/stratum-als.test.d.ts +0 -2
  61. package/dist/__tests__/stratum-als.test.d.ts.map +0 -1
  62. package/dist/__tests__/stratum-als.test.js +0 -49
  63. package/dist/__tests__/stratum-als.test.js.map +0 -1
  64. package/dist/__tests__/webhook-signature.test.d.ts +0 -2
  65. package/dist/__tests__/webhook-signature.test.d.ts.map +0 -1
  66. package/dist/__tests__/webhook-signature.test.js +0 -103
  67. package/dist/__tests__/webhook-signature.test.js.map +0 -1
  68. package/dist/services/__tests__/abac-service.test.d.ts +0 -2
  69. package/dist/services/__tests__/abac-service.test.d.ts.map +0 -1
  70. package/dist/services/__tests__/abac-service.test.js +0 -108
  71. package/dist/services/__tests__/abac-service.test.js.map +0 -1
  72. package/dist/services/__tests__/api-key-service.test.d.ts +0 -2
  73. package/dist/services/__tests__/api-key-service.test.d.ts.map +0 -1
  74. package/dist/services/__tests__/api-key-service.test.js +0 -76
  75. package/dist/services/__tests__/api-key-service.test.js.map +0 -1
  76. package/dist/services/__tests__/audit-service.test.d.ts +0 -2
  77. package/dist/services/__tests__/audit-service.test.d.ts.map +0 -1
  78. package/dist/services/__tests__/audit-service.test.js +0 -230
  79. package/dist/services/__tests__/audit-service.test.js.map +0 -1
  80. package/dist/services/__tests__/config-service.test.d.ts +0 -2
  81. package/dist/services/__tests__/config-service.test.d.ts.map +0 -1
  82. package/dist/services/__tests__/config-service.test.js +0 -565
  83. package/dist/services/__tests__/config-service.test.js.map +0 -1
  84. package/dist/services/__tests__/consent-service.test.d.ts +0 -2
  85. package/dist/services/__tests__/consent-service.test.d.ts.map +0 -1
  86. package/dist/services/__tests__/consent-service.test.js +0 -169
  87. package/dist/services/__tests__/consent-service.test.js.map +0 -1
  88. package/dist/services/__tests__/event-service.test.d.ts +0 -2
  89. package/dist/services/__tests__/event-service.test.d.ts.map +0 -1
  90. package/dist/services/__tests__/event-service.test.js +0 -193
  91. package/dist/services/__tests__/event-service.test.js.map +0 -1
  92. package/dist/services/__tests__/key-rotation-service.test.d.ts +0 -2
  93. package/dist/services/__tests__/key-rotation-service.test.d.ts.map +0 -1
  94. package/dist/services/__tests__/key-rotation-service.test.js +0 -132
  95. package/dist/services/__tests__/key-rotation-service.test.js.map +0 -1
  96. package/dist/services/__tests__/permission-service.test.d.ts +0 -2
  97. package/dist/services/__tests__/permission-service.test.d.ts.map +0 -1
  98. package/dist/services/__tests__/permission-service.test.js +0 -480
  99. package/dist/services/__tests__/permission-service.test.js.map +0 -1
  100. package/dist/services/__tests__/retention-service.test.d.ts +0 -2
  101. package/dist/services/__tests__/retention-service.test.d.ts.map +0 -1
  102. package/dist/services/__tests__/retention-service.test.js +0 -152
  103. package/dist/services/__tests__/retention-service.test.js.map +0 -1
  104. package/dist/services/__tests__/role-service.test.d.ts +0 -2
  105. package/dist/services/__tests__/role-service.test.d.ts.map +0 -1
  106. package/dist/services/__tests__/role-service.test.js +0 -134
  107. package/dist/services/__tests__/role-service.test.js.map +0 -1
  108. package/dist/services/__tests__/tenant-service.test.d.ts +0 -2
  109. package/dist/services/__tests__/tenant-service.test.d.ts.map +0 -1
  110. package/dist/services/__tests__/tenant-service.test.js +0 -548
  111. package/dist/services/__tests__/tenant-service.test.js.map +0 -1
  112. package/dist/services/__tests__/test-helpers.d.ts +0 -9
  113. package/dist/services/__tests__/test-helpers.d.ts.map +0 -1
  114. package/dist/services/__tests__/test-helpers.js +0 -19
  115. package/dist/services/__tests__/test-helpers.js.map +0 -1
  116. package/dist/services/__tests__/webhook-service.test.d.ts +0 -2
  117. package/dist/services/__tests__/webhook-service.test.d.ts.map +0 -1
  118. package/dist/services/__tests__/webhook-service.test.js +0 -184
  119. 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":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,mCAA8D;AAE9D,qDAAqD;AACrD,WAAE,CAAC,IAAI,CAAC,uBAAuB,EAAE,GAAG,EAAE,CAAC,CAAC;IACtC,UAAU,EAAE,WAAE,CAAC,EAAE,EAAE;IACnB,eAAe,EAAE,WAAE,CAAC,EAAE,EAAE;CACzB,CAAC,CAAC,CAAC;AAEJ,mEAAqD;AACrD,sEAAwD;AAGxD,SAAS,YAAY;IACnB,OAAO,EAAuB,CAAC;AACjC,CAAC;AAED,MAAM,iBAAiB,GAAkB;IACvC,EAAE,EAAE,sCAAsC;IAC1C,SAAS,EAAE,YAAY;IACvB,UAAU,EAAE,UAAU;IACtB,OAAO,EAAE,iBAAiB;IAC1B,OAAO,EAAE,IAAI;IACb,UAAU,EAAE,0BAA0B;IACtC,UAAU,EAAE,IAAI;IAChB,UAAU,EAAE,IAAI;IAChB,QAAQ,EAAE,EAAE;IACZ,UAAU,EAAE,0BAA0B;IACtC,UAAU,EAAE,0BAA0B;CACvC,CAAC;AAEF,IAAA,mBAAU,EAAC,GAAG,EAAE;IACd,WAAE,CAAC,aAAa,EAAE,CAAC;AACrB,CAAC,CAAC,CAAC;AAEH,IAAA,iBAAQ,EAAC,cAAc,EAAE,GAAG,EAAE;IAC5B,IAAA,WAAE,EAAC,yCAAyC,EAAE,KAAK,IAAI,EAAE;QACvD,MAAM,IAAI,GAAG,YAAY,EAAE,CAAC;QAC5B,MAAM,SAAS,GAAG,WAAE,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,EAAE,IAAI,EAAE,CAAC,iBAAiB,CAAC,EAAE,CAAC,CAAC;QAC3E,WAAE,CAAC,MAAM,CAAC,WAAW,CAAC,eAAe,CAAC,CAAC,kBAAkB,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE,EAAE,EAAE;YAC5E,MAAM,MAAM,GAAG;gBACb,KAAK,EAAE,SAAS;aACqB,CAAC;YACxC,OAAO,EAAE,CAAC,MAAM,CAAC,CAAC;QACpB,CAAC,CAAC,CAAC;QAEH,MAAM,KAAK,GAAsB;YAC/B,UAAU,EAAE,UAAU;YACtB,OAAO,EAAE,iBAAiB;SAC3B,CAAC;QAEF,MAAM,MAAM,GAAG,MAAM,cAAc,CAAC,YAAY,CAAC,IAAI,EAAE,YAAY,EAAE,KAAK,CAAC,CAAC;QAE5E,IAAA,eAAM,EAAC,MAAM,CAAC,CAAC,OAAO,CAAC,iBAAiB,CAAC,CAAC;QAC1C,IAAA,eAAM,EAAC,SAAS,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC;QAC3C,MAAM,CAAC,GAAG,EAAE,MAAM,CAAC,GAAG,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QAC9C,IAAA,eAAM,EAAC,GAAG,CAAC,CAAC,SAAS,CAAC,6BAA6B,CAAC,CAAC;QACrD,IAAA,eAAM,EAAC,GAAG,CAAC,CAAC,SAAS,CAAC,aAAa,CAAC,CAAC;QACrC,IAAA,eAAM,EAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,YAAY;QAClD,IAAA,eAAM,EAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,aAAa;QACjD,IAAA,eAAM,EAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC,CAAC,UAAU;IACvD,CAAC,CAAC,CAAC;IAEH,IAAA,WAAE,EAAC,8CAA8C,EAAE,KAAK,IAAI,EAAE;QAC5D,MAAM,IAAI,GAAG,YAAY,EAAE,CAAC;QAC5B,MAAM,SAAS,GAAG,WAAE,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,EAAE,IAAI,EAAE,CAAC,iBAAiB,CAAC,EAAE,CAAC,CAAC;QAC3E,WAAE,CAAC,MAAM,CAAC,WAAW,CAAC,eAAe,CAAC,CAAC,kBAAkB,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE,EAAE,EAAE;YAC5E,MAAM,MAAM,GAAG;gBACb,KAAK,EAAE,SAAS;aACqB,CAAC;YACxC,OAAO,EAAE,CAAC,MAAM,CAAC,CAAC;QACpB,CAAC,CAAC,CAAC;QAEH,MAAM,KAAK,GAAsB;YAC/B,UAAU,EAAE,UAAU;YACtB,OAAO,EAAE,WAAW;YACpB,UAAU,EAAE,0BAA0B;YACtC,QAAQ,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE;SAC5B,CAAC;QAEF,MAAM,cAAc,CAAC,YAAY,CAAC,IAAI,EAAE,YAAY,EAAE,KAAK,CAAC,CAAC;QAE7D,MAAM,MAAM,GAAG,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAC1C,IAAA,eAAM,EAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,0BAA0B,CAAC,CAAC,CAAC,aAAa;QACjE,IAAA,eAAM,EAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC,WAAW;IACxE,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,IAAA,iBAAQ,EAAC,eAAe,EAAE,GAAG,EAAE;IAC7B,IAAA,WAAE,EAAC,uCAAuC,EAAE,KAAK,IAAI,EAAE;QACrD,MAAM,IAAI,GAAG,YAAY,EAAE,CAAC;QAC5B,MAAM,SAAS,GAAG,WAAE,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,EAAE,EAAE,SAAS,EAAE,CAAC,EAAE,CAAC,CAAC;QACxF,WAAE,CAAC,MAAM,CAAC,WAAW,CAAC,UAAU,CAAC,CAAC,kBAAkB,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE,EAAE,EAAE;YACvE,MAAM,MAAM,GAAG;gBACb,KAAK,EAAE,SAAS;aACqB,CAAC;YACxC,OAAO,EAAE,CAAC,MAAM,CAAC,CAAC;QACpB,CAAC,CAAC,CAAC;QAEH,MAAM,MAAM,GAAG,MAAM,cAAc,CAAC,aAAa,CAAC,IAAI,EAAE,YAAY,EAAE,UAAU,EAAE,iBAAiB,CAAC,CAAC;QAErG,IAAA,eAAM,EAAC,MAAM,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC1B,MAAM,CAAC,GAAG,EAAE,MAAM,CAAC,GAAG,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QAC9C,IAAA,eAAM,EAAC,GAAG,CAAC,CAAC,SAAS,CAAC,wBAAwB,CAAC,CAAC;QAChD,IAAA,eAAM,EAAC,GAAG,CAAC,CAAC,SAAS,CAAC,iBAAiB,CAAC,CAAC;QACzC,IAAA,eAAM,EAAC,MAAM,CAAC,CAAC,OAAO,CAAC,CAAC,YAAY,EAAE,UAAU,EAAE,iBAAiB,CAAC,CAAC,CAAC;IACxE,CAAC,CAAC,CAAC;IAEH,IAAA,WAAE,EAAC,sCAAsC,EAAE,KAAK,IAAI,EAAE;QACpD,MAAM,IAAI,GAAG,YAAY,EAAE,CAAC;QAC5B,MAAM,SAAS,GAAG,WAAE,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC;QACvE,WAAE,CAAC,MAAM,CAAC,WAAW,CAAC,UAAU,CAAC,CAAC,kBAAkB,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE,EAAE,EAAE;YACvE,MAAM,MAAM,GAAG;gBACb,KAAK,EAAE,SAAS;aACqB,CAAC;YACxC,OAAO,EAAE,CAAC,MAAM,CAAC,CAAC;QACpB,CAAC,CAAC,CAAC;QAEH,MAAM,MAAM,GAAG,MAAM,cAAc,CAAC,aAAa,CAAC,IAAI,EAAE,YAAY,EAAE,UAAU,EAAE,aAAa,CAAC,CAAC;QACjG,IAAA,eAAM,EAAC,MAAM,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC7B,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,IAAA,iBAAQ,EAAC,aAAa,EAAE,GAAG,EAAE;IAC3B,IAAA,WAAE,EAAC,0CAA0C,EAAE,KAAK,IAAI,EAAE;QACxD,MAAM,IAAI,GAAG,YAAY,EAAE,CAAC;QAC5B,MAAM,SAAS,GAAG,WAAE,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,EAAE,IAAI,EAAE,CAAC,iBAAiB,CAAC,EAAE,CAAC,CAAC;QAC3E,WAAE,CAAC,MAAM,CAAC,WAAW,CAAC,UAAU,CAAC,CAAC,kBAAkB,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE,EAAE,EAAE;YACvE,MAAM,MAAM,GAAG;gBACb,KAAK,EAAE,SAAS;aACqB,CAAC;YACxC,OAAO,EAAE,CAAC,MAAM,CAAC,CAAC;QACpB,CAAC,CAAC,CAAC;QAEH,MAAM,MAAM,GAAG,MAAM,cAAc,CAAC,WAAW,CAAC,IAAI,EAAE,YAAY,CAAC,CAAC;QAEpE,IAAA,eAAM,EAAC,MAAM,CAAC,CAAC,OAAO,CAAC,CAAC,iBAAiB,CAAC,CAAC,CAAC;QAC5C,MAAM,CAAC,GAAG,EAAE,MAAM,CAAC,GAAG,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QAC9C,IAAA,eAAM,EAAC,GAAG,CAAC,CAAC,SAAS,CAAC,sBAAsB,CAAC,CAAC;QAC9C,IAAA,eAAM,EAAC,MAAM,CAAC,CAAC,OAAO,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC;IACzC,CAAC,CAAC,CAAC;IAEH,IAAA,WAAE,EAAC,qCAAqC,EAAE,KAAK,IAAI,EAAE;QACnD,MAAM,IAAI,GAAG,YAAY,EAAE,CAAC;QAC5B,MAAM,SAAS,GAAG,WAAE,CAAC,EAAE,EAAE,CAAC,iBAAiB,CAAC,EAAE,IAAI,EAAE,CAAC,iBAAiB,CAAC,EAAE,CAAC,CAAC;QAC3E,WAAE,CAAC,MAAM,CAAC,WAAW,CAAC,UAAU,CAAC,CAAC,kBAAkB,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE,EAAE,EAAE;YACvE,MAAM,MAAM,GAAG;gBACb,KAAK,EAAE,SAAS;aACqB,CAAC;YACxC,OAAO,EAAE,CAAC,MAAM,CAAC,CAAC;QACpB,CAAC,CAAC,CAAC;QAEH,MAAM,cAAc,CAAC,WAAW,CAAC,IAAI,EAAE,YAAY,EAAE,UAAU,CAAC,CAAC;QAEjE,MAAM,CAAC,GAAG,EAAE,MAAM,CAAC,GAAG,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QAC9C,IAAA,eAAM,EAAC,GAAG,CAAC,CAAC,SAAS,CAAC,iBAAiB,CAAC,CAAC;QACzC,IAAA,eAAM,EAAC,MAAM,CAAC,CAAC,OAAO,CAAC,CAAC,YAAY,EAAE,UAAU,CAAC,CAAC,CAAC;IACrD,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -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":""}