@stratum-hq/lib 0.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.
- package/dist/__tests__/crypto.test.d.ts +2 -0
- package/dist/__tests__/crypto.test.d.ts.map +1 -0
- package/dist/__tests__/crypto.test.js +41 -0
- package/dist/__tests__/crypto.test.js.map +1 -0
- package/dist/crypto.d.ts +7 -0
- package/dist/crypto.d.ts.map +1 -0
- package/dist/crypto.js +74 -0
- package/dist/crypto.js.map +1 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +13 -0
- package/dist/index.js.map +1 -0
- package/dist/pool-helpers.d.ts +4 -0
- package/dist/pool-helpers.d.ts.map +1 -0
- package/dist/pool-helpers.js +31 -0
- package/dist/pool-helpers.js.map +1 -0
- package/dist/services/__tests__/audit-service.test.d.ts +2 -0
- package/dist/services/__tests__/audit-service.test.d.ts.map +1 -0
- package/dist/services/__tests__/audit-service.test.js +220 -0
- package/dist/services/__tests__/audit-service.test.js.map +1 -0
- package/dist/services/__tests__/config-service.test.d.ts +2 -0
- package/dist/services/__tests__/config-service.test.d.ts.map +1 -0
- package/dist/services/__tests__/config-service.test.js +555 -0
- package/dist/services/__tests__/config-service.test.js.map +1 -0
- package/dist/services/__tests__/consent-service.test.d.ts +2 -0
- package/dist/services/__tests__/consent-service.test.d.ts.map +1 -0
- package/dist/services/__tests__/consent-service.test.js +159 -0
- package/dist/services/__tests__/consent-service.test.js.map +1 -0
- package/dist/services/__tests__/event-service.test.d.ts +2 -0
- package/dist/services/__tests__/event-service.test.d.ts.map +1 -0
- package/dist/services/__tests__/event-service.test.js +151 -0
- package/dist/services/__tests__/event-service.test.js.map +1 -0
- package/dist/services/__tests__/permission-service.test.d.ts +2 -0
- package/dist/services/__tests__/permission-service.test.d.ts.map +1 -0
- package/dist/services/__tests__/permission-service.test.js +470 -0
- package/dist/services/__tests__/permission-service.test.js.map +1 -0
- package/dist/services/__tests__/retention-service.test.d.ts +2 -0
- package/dist/services/__tests__/retention-service.test.d.ts.map +1 -0
- package/dist/services/__tests__/retention-service.test.js +126 -0
- package/dist/services/__tests__/retention-service.test.js.map +1 -0
- package/dist/services/__tests__/tenant-service.test.d.ts +2 -0
- package/dist/services/__tests__/tenant-service.test.d.ts.map +1 -0
- package/dist/services/__tests__/tenant-service.test.js +451 -0
- package/dist/services/__tests__/tenant-service.test.js.map +1 -0
- package/dist/services/__tests__/test-helpers.d.ts +9 -0
- package/dist/services/__tests__/test-helpers.d.ts.map +1 -0
- package/dist/services/__tests__/test-helpers.js +20 -0
- package/dist/services/__tests__/test-helpers.js.map +1 -0
- package/dist/services/__tests__/webhook-service.test.d.ts +2 -0
- package/dist/services/__tests__/webhook-service.test.d.ts.map +1 -0
- package/dist/services/__tests__/webhook-service.test.js +174 -0
- package/dist/services/__tests__/webhook-service.test.js.map +1 -0
- package/dist/services/api-key-service.d.ts +61 -0
- package/dist/services/api-key-service.d.ts.map +1 -0
- package/dist/services/api-key-service.js +164 -0
- package/dist/services/api-key-service.js.map +1 -0
- package/dist/services/audit-service.d.ts +6 -0
- package/dist/services/audit-service.d.ts.map +1 -0
- package/dist/services/audit-service.js +85 -0
- package/dist/services/audit-service.js.map +1 -0
- package/dist/services/config-service.d.ts +33 -0
- package/dist/services/config-service.d.ts.map +1 -0
- package/dist/services/config-service.js +271 -0
- package/dist/services/config-service.js.map +1 -0
- package/dist/services/consent-service.d.ts +7 -0
- package/dist/services/consent-service.d.ts.map +1 -0
- package/dist/services/consent-service.js +71 -0
- package/dist/services/consent-service.js.map +1 -0
- package/dist/services/event-service.d.ts +39 -0
- package/dist/services/event-service.d.ts.map +1 -0
- package/dist/services/event-service.js +331 -0
- package/dist/services/event-service.js.map +1 -0
- package/dist/services/key-rotation-service.d.ts +15 -0
- package/dist/services/key-rotation-service.d.ts.map +1 -0
- package/dist/services/key-rotation-service.js +41 -0
- package/dist/services/key-rotation-service.js.map +1 -0
- package/dist/services/permission-service.d.ts +21 -0
- package/dist/services/permission-service.d.ts.map +1 -0
- package/dist/services/permission-service.js +213 -0
- package/dist/services/permission-service.js.map +1 -0
- package/dist/services/region-service.d.ts +9 -0
- package/dist/services/region-service.d.ts.map +1 -0
- package/dist/services/region-service.js +105 -0
- package/dist/services/region-service.js.map +1 -0
- package/dist/services/retention-service.d.ts +19 -0
- package/dist/services/retention-service.d.ts.map +1 -0
- package/dist/services/retention-service.js +88 -0
- package/dist/services/retention-service.js.map +1 -0
- package/dist/services/role-service.d.ts +35 -0
- package/dist/services/role-service.d.ts.map +1 -0
- package/dist/services/role-service.js +101 -0
- package/dist/services/role-service.js.map +1 -0
- package/dist/services/tenant-service.d.ts +25 -0
- package/dist/services/tenant-service.d.ts.map +1 -0
- package/dist/services/tenant-service.js +335 -0
- package/dist/services/tenant-service.js.map +1 -0
- package/dist/services/webhook-service.d.ts +12 -0
- package/dist/services/webhook-service.d.ts.map +1 -0
- package/dist/services/webhook-service.js +129 -0
- package/dist/services/webhook-service.js.map +1 -0
- package/dist/stratum.d.ts +107 -0
- package/dist/stratum.d.ts.map +1 -0
- package/dist/stratum.js +531 -0
- package/dist/stratum.js.map +1 -0
- package/dist/telemetry.d.ts +27 -0
- package/dist/telemetry.d.ts.map +1 -0
- package/dist/telemetry.js +94 -0
- package/dist/telemetry.js.map +1 -0
- package/package.json +46 -0
|
@@ -0,0 +1,335 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getChildren = exports.getDescendants = exports.getAncestors = exports.batchCreateTenants = exports.moveTenant = exports.deleteTenant = exports.updateTenant = exports.listTenants = exports.getTenant = exports.createTenant = void 0;
|
|
4
|
+
const pool_helpers_js_1 = require("../pool-helpers.js");
|
|
5
|
+
const core_1 = require("@stratum-hq/core");
|
|
6
|
+
async function createTenant(pool, input) {
|
|
7
|
+
return (0, pool_helpers_js_1.withTransaction)(pool, async (client) => {
|
|
8
|
+
// Advisory lock on parent to serialize sibling inserts
|
|
9
|
+
if (input.parent_id) {
|
|
10
|
+
await client.query(`SELECT pg_advisory_xact_lock(('x' || substr(md5($1::text), 1, 16))::bit(64)::bigint)`, [input.parent_id]);
|
|
11
|
+
// Verify parent exists and is active
|
|
12
|
+
const parentRes = await client.query(`SELECT * FROM tenants WHERE id = $1`, [input.parent_id]);
|
|
13
|
+
if (parentRes.rows.length === 0) {
|
|
14
|
+
throw new core_1.TenantNotFoundError(input.parent_id);
|
|
15
|
+
}
|
|
16
|
+
if (parentRes.rows[0].status === "archived") {
|
|
17
|
+
throw new core_1.TenantArchivedError(input.parent_id);
|
|
18
|
+
}
|
|
19
|
+
const parent = parentRes.rows[0];
|
|
20
|
+
const ancestry_path = (0, core_1.appendToPath)(parent.ancestry_path, parent.id);
|
|
21
|
+
// Inherit region_id from parent if not explicitly provided
|
|
22
|
+
const regionId = input.region_id ?? parent.region_id ?? null;
|
|
23
|
+
const res = await client.query(`INSERT INTO tenants (parent_id, ancestry_path, depth, name, slug, config, metadata, isolation_strategy, status, region_id)
|
|
24
|
+
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, 'active', $9)
|
|
25
|
+
RETURNING *`, [
|
|
26
|
+
input.parent_id,
|
|
27
|
+
ancestry_path,
|
|
28
|
+
(0, core_1.parseAncestryPath)(ancestry_path).length,
|
|
29
|
+
input.name,
|
|
30
|
+
input.slug,
|
|
31
|
+
JSON.stringify(input.config ?? {}),
|
|
32
|
+
JSON.stringify(input.metadata ?? {}),
|
|
33
|
+
input.isolation_strategy ?? "SHARED_RLS",
|
|
34
|
+
regionId,
|
|
35
|
+
]);
|
|
36
|
+
return res.rows[0];
|
|
37
|
+
}
|
|
38
|
+
else {
|
|
39
|
+
// Root tenant — no parent lock needed
|
|
40
|
+
const rootRegionId = input.region_id ?? null;
|
|
41
|
+
const res = await client.query(`INSERT INTO tenants (parent_id, ancestry_path, depth, name, slug, config, metadata, isolation_strategy, status, region_id)
|
|
42
|
+
VALUES (NULL, '/', 0, $1, $2, $3, $4, $5, 'active', $6)
|
|
43
|
+
RETURNING *`, [
|
|
44
|
+
input.name,
|
|
45
|
+
input.slug,
|
|
46
|
+
JSON.stringify(input.config ?? {}),
|
|
47
|
+
JSON.stringify(input.metadata ?? {}),
|
|
48
|
+
input.isolation_strategy ?? "SHARED_RLS",
|
|
49
|
+
rootRegionId,
|
|
50
|
+
]);
|
|
51
|
+
return res.rows[0];
|
|
52
|
+
}
|
|
53
|
+
}).catch((err) => {
|
|
54
|
+
if (err instanceof Error &&
|
|
55
|
+
"code" in err &&
|
|
56
|
+
err.code === "23505") {
|
|
57
|
+
throw new core_1.TenantAlreadyExistsError(input.slug);
|
|
58
|
+
}
|
|
59
|
+
throw err;
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
exports.createTenant = createTenant;
|
|
63
|
+
async function getTenant(pool, id, includeArchived = false) {
|
|
64
|
+
return (0, pool_helpers_js_1.withClient)(pool, async (client) => {
|
|
65
|
+
// Always fetch the row; check archived status in application logic (single query)
|
|
66
|
+
const res = await client.query(`SELECT * FROM tenants WHERE id = $1`, [id]);
|
|
67
|
+
if (res.rows.length === 0) {
|
|
68
|
+
throw new core_1.TenantNotFoundError(id);
|
|
69
|
+
}
|
|
70
|
+
const tenant = res.rows[0];
|
|
71
|
+
if (!includeArchived && tenant.status === "archived") {
|
|
72
|
+
throw new core_1.TenantArchivedError(id);
|
|
73
|
+
}
|
|
74
|
+
return tenant;
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
exports.getTenant = getTenant;
|
|
78
|
+
async function listTenants(pool, pagination) {
|
|
79
|
+
return (0, pool_helpers_js_1.withClient)(pool, async (client) => {
|
|
80
|
+
const limit = pagination.limit ?? 50;
|
|
81
|
+
let res;
|
|
82
|
+
if (pagination.cursor) {
|
|
83
|
+
res = await client.query(`SELECT * FROM tenants
|
|
84
|
+
WHERE status = 'active' AND id > $1
|
|
85
|
+
ORDER BY id ASC
|
|
86
|
+
LIMIT $2`, [pagination.cursor, limit + 1]);
|
|
87
|
+
}
|
|
88
|
+
else {
|
|
89
|
+
res = await client.query(`SELECT * FROM tenants
|
|
90
|
+
WHERE status = 'active'
|
|
91
|
+
ORDER BY id ASC
|
|
92
|
+
LIMIT $1`, [limit + 1]);
|
|
93
|
+
}
|
|
94
|
+
const rows = res.rows;
|
|
95
|
+
const has_more = rows.length > limit;
|
|
96
|
+
const data = has_more ? rows.slice(0, limit) : rows;
|
|
97
|
+
const next_cursor = has_more ? data[data.length - 1].id : null;
|
|
98
|
+
return { data, next_cursor, has_more };
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
exports.listTenants = listTenants;
|
|
102
|
+
async function updateTenant(pool, id, patch) {
|
|
103
|
+
return (0, pool_helpers_js_1.withTransaction)(pool, async (client) => {
|
|
104
|
+
const existing = await client.query(`SELECT * FROM tenants WHERE id = $1 AND status != 'archived'`, [id]);
|
|
105
|
+
if (existing.rows.length === 0) {
|
|
106
|
+
throw new core_1.TenantNotFoundError(id);
|
|
107
|
+
}
|
|
108
|
+
const sets = [];
|
|
109
|
+
const values = [];
|
|
110
|
+
let idx = 1;
|
|
111
|
+
if (patch.name !== undefined) {
|
|
112
|
+
sets.push(`name = $${idx++}`);
|
|
113
|
+
values.push(patch.name);
|
|
114
|
+
}
|
|
115
|
+
if (patch.slug !== undefined) {
|
|
116
|
+
sets.push(`slug = $${idx++}`);
|
|
117
|
+
values.push(patch.slug);
|
|
118
|
+
}
|
|
119
|
+
if (patch.config !== undefined) {
|
|
120
|
+
sets.push(`config = $${idx++}`);
|
|
121
|
+
values.push(JSON.stringify(patch.config));
|
|
122
|
+
}
|
|
123
|
+
if (patch.metadata !== undefined) {
|
|
124
|
+
sets.push(`metadata = $${idx++}`);
|
|
125
|
+
values.push(JSON.stringify(patch.metadata));
|
|
126
|
+
}
|
|
127
|
+
if (sets.length === 0) {
|
|
128
|
+
return existing.rows[0];
|
|
129
|
+
}
|
|
130
|
+
sets.push(`updated_at = now()`);
|
|
131
|
+
values.push(id);
|
|
132
|
+
const res = await client.query(`UPDATE tenants SET ${sets.join(", ")} WHERE id = $${idx} RETURNING *`, values);
|
|
133
|
+
return res.rows[0];
|
|
134
|
+
}).catch((err) => {
|
|
135
|
+
if (err instanceof Error &&
|
|
136
|
+
"code" in err &&
|
|
137
|
+
err.code === "23505") {
|
|
138
|
+
throw new core_1.TenantAlreadyExistsError(patch.slug ?? "");
|
|
139
|
+
}
|
|
140
|
+
throw err;
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
exports.updateTenant = updateTenant;
|
|
144
|
+
async function deleteTenant(pool, id) {
|
|
145
|
+
return (0, pool_helpers_js_1.withTransaction)(pool, async (client) => {
|
|
146
|
+
const existing = await client.query(`SELECT * FROM tenants WHERE id = $1 AND status != 'archived'`, [id]);
|
|
147
|
+
if (existing.rows.length === 0) {
|
|
148
|
+
throw new core_1.TenantNotFoundError(id);
|
|
149
|
+
}
|
|
150
|
+
// Check for active children
|
|
151
|
+
const childrenRes = await client.query(`SELECT COUNT(*) as count FROM tenants WHERE parent_id = $1 AND status = 'active'`, [id]);
|
|
152
|
+
if (parseInt(childrenRes.rows[0].count, 10) > 0) {
|
|
153
|
+
throw new core_1.TenantHasChildrenError(id);
|
|
154
|
+
}
|
|
155
|
+
await client.query(`UPDATE tenants SET status = 'archived', deleted_at = now(), updated_at = now() WHERE id = $1`, [id]);
|
|
156
|
+
});
|
|
157
|
+
}
|
|
158
|
+
exports.deleteTenant = deleteTenant;
|
|
159
|
+
async function moveTenant(pool, id, newParentId) {
|
|
160
|
+
return (0, pool_helpers_js_1.withTransaction)(pool, async (client) => {
|
|
161
|
+
// Lock both old and new parents to prevent concurrent moves
|
|
162
|
+
await client.query(`SELECT pg_advisory_xact_lock(('x' || substr(md5($1::text), 1, 16))::bit(64)::bigint)`, [id]);
|
|
163
|
+
await client.query(`SELECT pg_advisory_xact_lock(('x' || substr(md5($1::text), 1, 16))::bit(64)::bigint)`, [newParentId]);
|
|
164
|
+
// Load tenant being moved
|
|
165
|
+
const tenantRes = await client.query(`SELECT * FROM tenants WHERE id = $1 AND status != 'archived'`, [id]);
|
|
166
|
+
if (tenantRes.rows.length === 0) {
|
|
167
|
+
throw new core_1.TenantNotFoundError(id);
|
|
168
|
+
}
|
|
169
|
+
const tenant = tenantRes.rows[0];
|
|
170
|
+
// Load new parent
|
|
171
|
+
const newParentRes = await client.query(`SELECT * FROM tenants WHERE id = $1 AND status != 'archived'`, [newParentId]);
|
|
172
|
+
if (newParentRes.rows.length === 0) {
|
|
173
|
+
throw new core_1.TenantNotFoundError(newParentId);
|
|
174
|
+
}
|
|
175
|
+
const newParent = newParentRes.rows[0];
|
|
176
|
+
// Cycle detection: newParent must not be a descendant of tenant
|
|
177
|
+
if (newParent.id === tenant.id ||
|
|
178
|
+
(0, core_1.isDescendantOf)(newParent.ancestry_path, tenant.ancestry_path) ||
|
|
179
|
+
(newParent.ancestry_path !== "/" &&
|
|
180
|
+
newParent.ancestry_path.includes(tenant.id))) {
|
|
181
|
+
throw new core_1.TenantCycleDetectedError(id, newParentId);
|
|
182
|
+
}
|
|
183
|
+
const oldAncestryPath = tenant.ancestry_path;
|
|
184
|
+
const newAncestryPath = (0, core_1.appendToPath)(newParent.ancestry_path, newParent.id);
|
|
185
|
+
const newDepth = (0, core_1.parseAncestryPath)(newAncestryPath).length;
|
|
186
|
+
// Update the moved tenant
|
|
187
|
+
const updatedRes = await client.query(`UPDATE tenants
|
|
188
|
+
SET parent_id = $1,
|
|
189
|
+
ancestry_path = $2,
|
|
190
|
+
depth = $3,
|
|
191
|
+
updated_at = now()
|
|
192
|
+
WHERE id = $4
|
|
193
|
+
RETURNING *`, [newParentId, newAncestryPath, newDepth, id]);
|
|
194
|
+
// Recompute ancestry_path for all descendants.
|
|
195
|
+
// The moved tenant's old ancestry_path is oldAncestryPath.
|
|
196
|
+
// Descendants have ancestry_path starting with oldAncestryPath + "/" + id.
|
|
197
|
+
const oldPrefix = oldAncestryPath === "/"
|
|
198
|
+
? `/${id}`
|
|
199
|
+
: `${oldAncestryPath}/${id}`;
|
|
200
|
+
const newPrefix = newAncestryPath === "/"
|
|
201
|
+
? `/${id}`
|
|
202
|
+
: `${newAncestryPath}/${id}`;
|
|
203
|
+
const descendantsRes = await client.query(`SELECT * FROM tenants
|
|
204
|
+
WHERE ancestry_path LIKE $1
|
|
205
|
+
ORDER BY depth ASC`, [`${oldPrefix}/%`]);
|
|
206
|
+
for (const desc of descendantsRes.rows) {
|
|
207
|
+
const updatedDescPath = newPrefix + desc.ancestry_path.slice(oldPrefix.length);
|
|
208
|
+
const updatedDescDepth = (0, core_1.parseAncestryPath)(updatedDescPath).length;
|
|
209
|
+
await client.query(`UPDATE tenants
|
|
210
|
+
SET ancestry_path = $1,
|
|
211
|
+
depth = $2,
|
|
212
|
+
slug = slug,
|
|
213
|
+
updated_at = now()
|
|
214
|
+
WHERE id = $3`, [updatedDescPath, updatedDescDepth, desc.id]);
|
|
215
|
+
}
|
|
216
|
+
return updatedRes.rows[0];
|
|
217
|
+
});
|
|
218
|
+
}
|
|
219
|
+
exports.moveTenant = moveTenant;
|
|
220
|
+
/**
|
|
221
|
+
* Create multiple tenants in a single transaction.
|
|
222
|
+
* Stops on first error and rolls back all changes.
|
|
223
|
+
*/
|
|
224
|
+
async function batchCreateTenants(pool, inputs) {
|
|
225
|
+
const created = [];
|
|
226
|
+
const errors = [];
|
|
227
|
+
try {
|
|
228
|
+
await (0, pool_helpers_js_1.withTransaction)(pool, async (client) => {
|
|
229
|
+
// Map of slug → created tenant for intra-batch parent references
|
|
230
|
+
const slugMap = new Map();
|
|
231
|
+
for (let i = 0; i < inputs.length; i++) {
|
|
232
|
+
const input = inputs[i];
|
|
233
|
+
let parentId = input.parent_id ?? null;
|
|
234
|
+
let parentNode = null;
|
|
235
|
+
if (parentId) {
|
|
236
|
+
// Check if parent was created earlier in this batch (by ID)
|
|
237
|
+
const batchParent = created.find((t) => t.id === parentId);
|
|
238
|
+
if (batchParent) {
|
|
239
|
+
parentNode = batchParent;
|
|
240
|
+
}
|
|
241
|
+
else {
|
|
242
|
+
// Look up in DB
|
|
243
|
+
const parentRes = await client.query(`SELECT * FROM tenants WHERE id = $1 AND status != 'archived'`, [parentId]);
|
|
244
|
+
if (parentRes.rows.length === 0) {
|
|
245
|
+
throw new core_1.TenantNotFoundError(parentId);
|
|
246
|
+
}
|
|
247
|
+
parentNode = parentRes.rows[0];
|
|
248
|
+
}
|
|
249
|
+
// Advisory lock on parent
|
|
250
|
+
await client.query(`SELECT pg_advisory_xact_lock(('x' || substr(md5($1::text), 1, 16))::bit(64)::bigint)`, [parentId]);
|
|
251
|
+
const ancestry_path = (0, core_1.appendToPath)(parentNode.ancestry_path, parentNode.id);
|
|
252
|
+
const regionId = input.region_id ?? parentNode.region_id ?? null;
|
|
253
|
+
const res = await client.query(`INSERT INTO tenants (parent_id, ancestry_path, depth, name, slug, config, metadata, isolation_strategy, status, region_id)
|
|
254
|
+
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, 'active', $9)
|
|
255
|
+
RETURNING *`, [
|
|
256
|
+
parentId,
|
|
257
|
+
ancestry_path,
|
|
258
|
+
(0, core_1.parseAncestryPath)(ancestry_path).length,
|
|
259
|
+
input.name,
|
|
260
|
+
input.slug,
|
|
261
|
+
JSON.stringify(input.config ?? {}),
|
|
262
|
+
JSON.stringify(input.metadata ?? {}),
|
|
263
|
+
input.isolation_strategy ?? "SHARED_RLS",
|
|
264
|
+
regionId,
|
|
265
|
+
]);
|
|
266
|
+
const tenant = res.rows[0];
|
|
267
|
+
created.push(tenant);
|
|
268
|
+
slugMap.set(tenant.slug, tenant);
|
|
269
|
+
}
|
|
270
|
+
else {
|
|
271
|
+
// Root tenant
|
|
272
|
+
const rootRegionId = input.region_id ?? null;
|
|
273
|
+
const res = await client.query(`INSERT INTO tenants (parent_id, ancestry_path, depth, name, slug, config, metadata, isolation_strategy, status, region_id)
|
|
274
|
+
VALUES (NULL, '/', 0, $1, $2, $3, $4, $5, 'active', $6)
|
|
275
|
+
RETURNING *`, [
|
|
276
|
+
input.name,
|
|
277
|
+
input.slug,
|
|
278
|
+
JSON.stringify(input.config ?? {}),
|
|
279
|
+
JSON.stringify(input.metadata ?? {}),
|
|
280
|
+
input.isolation_strategy ?? "SHARED_RLS",
|
|
281
|
+
rootRegionId,
|
|
282
|
+
]);
|
|
283
|
+
const tenant = res.rows[0];
|
|
284
|
+
created.push(tenant);
|
|
285
|
+
slugMap.set(tenant.slug, tenant);
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
});
|
|
289
|
+
}
|
|
290
|
+
catch (err) {
|
|
291
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
292
|
+
errors.push({ index: created.length, slug: inputs[created.length]?.slug ?? "unknown", error: message });
|
|
293
|
+
}
|
|
294
|
+
return { created, errors };
|
|
295
|
+
}
|
|
296
|
+
exports.batchCreateTenants = batchCreateTenants;
|
|
297
|
+
async function getAncestors(pool, id) {
|
|
298
|
+
return (0, pool_helpers_js_1.withClient)(pool, async (client) => {
|
|
299
|
+
const tenantRes = await client.query(`SELECT * FROM tenants WHERE id = $1`, [id]);
|
|
300
|
+
if (tenantRes.rows.length === 0) {
|
|
301
|
+
throw new core_1.TenantNotFoundError(id);
|
|
302
|
+
}
|
|
303
|
+
const tenant = tenantRes.rows[0];
|
|
304
|
+
const ancestorIds = (0, core_1.getAncestorIds)(tenant.ancestry_path);
|
|
305
|
+
if (ancestorIds.length === 0) {
|
|
306
|
+
return [];
|
|
307
|
+
}
|
|
308
|
+
const res = await client.query(`SELECT * FROM tenants WHERE id = ANY($1) ORDER BY depth ASC`, [ancestorIds]);
|
|
309
|
+
return res.rows;
|
|
310
|
+
});
|
|
311
|
+
}
|
|
312
|
+
exports.getAncestors = getAncestors;
|
|
313
|
+
async function getDescendants(pool, id) {
|
|
314
|
+
return (0, pool_helpers_js_1.withClient)(pool, async (client) => {
|
|
315
|
+
const existsRes = await client.query(`SELECT id FROM tenants WHERE id = $1`, [id]);
|
|
316
|
+
if (existsRes.rows.length === 0) {
|
|
317
|
+
throw new core_1.TenantNotFoundError(id);
|
|
318
|
+
}
|
|
319
|
+
// Use ltree <@ operator for efficient subtree query
|
|
320
|
+
const res = await client.query(`SELECT * FROM tenants
|
|
321
|
+
WHERE ancestry_ltree <@ (SELECT ancestry_ltree FROM tenants WHERE id = $1)
|
|
322
|
+
AND id != $1
|
|
323
|
+
ORDER BY depth ASC`, [id]);
|
|
324
|
+
return res.rows;
|
|
325
|
+
});
|
|
326
|
+
}
|
|
327
|
+
exports.getDescendants = getDescendants;
|
|
328
|
+
async function getChildren(pool, id) {
|
|
329
|
+
return (0, pool_helpers_js_1.withClient)(pool, async (client) => {
|
|
330
|
+
const res = await client.query(`SELECT * FROM tenants WHERE parent_id = $1 AND status = 'active' ORDER BY created_at ASC`, [id]);
|
|
331
|
+
return res.rows;
|
|
332
|
+
});
|
|
333
|
+
}
|
|
334
|
+
exports.getChildren = getChildren;
|
|
335
|
+
//# sourceMappingURL=tenant-service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tenant-service.js","sourceRoot":"","sources":["../../src/services/tenant-service.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import pg from "pg";
|
|
2
|
+
import type { Webhook, CreateWebhookInput, UpdateWebhookInput } from "@stratum-hq/core";
|
|
3
|
+
/** Decrypts a stored webhook secret. */
|
|
4
|
+
export declare function decryptSecret(encrypted: string): string;
|
|
5
|
+
export declare function createWebhook(pool: pg.Pool, input: CreateWebhookInput): Promise<Webhook>;
|
|
6
|
+
export declare function getWebhook(pool: pg.Pool, id: string): Promise<Webhook>;
|
|
7
|
+
export declare function listWebhooks(pool: pg.Pool, tenantId?: string | null): Promise<Webhook[]>;
|
|
8
|
+
export declare function updateWebhook(pool: pg.Pool, id: string, input: UpdateWebhookInput): Promise<Webhook>;
|
|
9
|
+
export declare function deleteWebhook(pool: pg.Pool, id: string): Promise<void>;
|
|
10
|
+
export declare function listWebhookDeliveries(pool: pg.Pool, webhookId: string): Promise<Record<string, unknown>[]>;
|
|
11
|
+
export declare function getWebhooksForEvent(pool: pg.Pool, eventType: string, tenantId: string): Promise<Webhook[]>;
|
|
12
|
+
//# sourceMappingURL=webhook-service.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"webhook-service.d.ts","sourceRoot":"","sources":["../../src/services/webhook-service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,IAAI,CAAC;AAEpB,OAAO,KAAK,EACV,OAAO,EACP,kBAAkB,EAClB,kBAAkB,EACnB,MAAM,kBAAkB,CAAC;AAY1B,wCAAwC;AACxC,wBAAgB,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAEvD;AAED,wBAAsB,aAAa,CACjC,IAAI,EAAE,EAAE,CAAC,IAAI,EACb,KAAK,EAAE,kBAAkB,GACxB,OAAO,CAAC,OAAO,CAAC,CAiBlB;AAED,wBAAsB,UAAU,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAW5E;AAED,wBAAsB,YAAY,CAChC,IAAI,EAAE,EAAE,CAAC,IAAI,EACb,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,GACvB,OAAO,CAAC,OAAO,EAAE,CAAC,CAepB;AAED,wBAAsB,aAAa,CACjC,IAAI,EAAE,EAAE,CAAC,IAAI,EACb,EAAE,EAAE,MAAM,EACV,KAAK,EAAE,kBAAkB,GACxB,OAAO,CAAC,OAAO,CAAC,CAoDlB;AAED,wBAAsB,aAAa,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,EAAE,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAU5E;AAED,wBAAsB,qBAAqB,CACzC,IAAI,EAAE,EAAE,CAAC,IAAI,EACb,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,CAAC,CAiBpC;AAED,wBAAsB,mBAAmB,CACvC,IAAI,EAAE,EAAE,CAAC,IAAI,EACb,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,OAAO,EAAE,CAAC,CAWpB"}
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getWebhooksForEvent = exports.listWebhookDeliveries = exports.deleteWebhook = exports.updateWebhook = exports.listWebhooks = exports.getWebhook = exports.createWebhook = exports.decryptSecret = void 0;
|
|
4
|
+
const pool_helpers_js_1 = require("../pool-helpers.js");
|
|
5
|
+
const core_1 = require("@stratum-hq/core");
|
|
6
|
+
const crypto_js_1 = require("../crypto.js");
|
|
7
|
+
/** Columns safe to return in API responses (excludes secret_hash). */
|
|
8
|
+
const WEBHOOK_PUBLIC_COLS = "id, tenant_id, url, events, active, description, created_at, updated_at";
|
|
9
|
+
/** Encrypts a webhook secret for storage. */
|
|
10
|
+
function encryptSecret(secret) {
|
|
11
|
+
return (0, crypto_js_1.encrypt)(secret);
|
|
12
|
+
}
|
|
13
|
+
/** Decrypts a stored webhook secret. */
|
|
14
|
+
function decryptSecret(encrypted) {
|
|
15
|
+
return (0, crypto_js_1.decrypt)(encrypted);
|
|
16
|
+
}
|
|
17
|
+
exports.decryptSecret = decryptSecret;
|
|
18
|
+
async function createWebhook(pool, input) {
|
|
19
|
+
return (0, pool_helpers_js_1.withClient)(pool, async (client) => {
|
|
20
|
+
const encryptedSecret = encryptSecret(input.secret);
|
|
21
|
+
const res = await client.query(`INSERT INTO webhooks (tenant_id, url, secret_hash, events, active, description)
|
|
22
|
+
VALUES ($1, $2, $3, $4, true, $5)
|
|
23
|
+
RETURNING ${WEBHOOK_PUBLIC_COLS}`, [
|
|
24
|
+
input.tenant_id ?? null,
|
|
25
|
+
input.url,
|
|
26
|
+
encryptedSecret,
|
|
27
|
+
input.events,
|
|
28
|
+
input.description ?? null,
|
|
29
|
+
]);
|
|
30
|
+
return res.rows[0];
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
exports.createWebhook = createWebhook;
|
|
34
|
+
async function getWebhook(pool, id) {
|
|
35
|
+
return (0, pool_helpers_js_1.withClient)(pool, async (client) => {
|
|
36
|
+
const res = await client.query(`SELECT ${WEBHOOK_PUBLIC_COLS} FROM webhooks WHERE id = $1`, [id]);
|
|
37
|
+
if (res.rows.length === 0) {
|
|
38
|
+
throw new core_1.WebhookNotFoundError(id);
|
|
39
|
+
}
|
|
40
|
+
return res.rows[0];
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
exports.getWebhook = getWebhook;
|
|
44
|
+
async function listWebhooks(pool, tenantId) {
|
|
45
|
+
return (0, pool_helpers_js_1.withClient)(pool, async (client) => {
|
|
46
|
+
let res;
|
|
47
|
+
if (tenantId !== undefined && tenantId !== null) {
|
|
48
|
+
res = await client.query(`SELECT ${WEBHOOK_PUBLIC_COLS} FROM webhooks WHERE tenant_id = $1 ORDER BY created_at ASC`, [tenantId]);
|
|
49
|
+
}
|
|
50
|
+
else {
|
|
51
|
+
res = await client.query(`SELECT ${WEBHOOK_PUBLIC_COLS} FROM webhooks ORDER BY created_at ASC`);
|
|
52
|
+
}
|
|
53
|
+
return res.rows;
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
exports.listWebhooks = listWebhooks;
|
|
57
|
+
async function updateWebhook(pool, id, input) {
|
|
58
|
+
return (0, pool_helpers_js_1.withTransaction)(pool, async (client) => {
|
|
59
|
+
const existing = await client.query(`SELECT id FROM webhooks WHERE id = $1`, [id]);
|
|
60
|
+
if (existing.rows.length === 0) {
|
|
61
|
+
throw new core_1.WebhookNotFoundError(id);
|
|
62
|
+
}
|
|
63
|
+
const sets = [];
|
|
64
|
+
const values = [];
|
|
65
|
+
let idx = 1;
|
|
66
|
+
if (input.url !== undefined) {
|
|
67
|
+
sets.push(`url = $${idx++}`);
|
|
68
|
+
values.push(input.url);
|
|
69
|
+
}
|
|
70
|
+
if (input.secret !== undefined) {
|
|
71
|
+
sets.push(`secret_hash = $${idx++}`);
|
|
72
|
+
values.push(encryptSecret(input.secret));
|
|
73
|
+
}
|
|
74
|
+
if (input.events !== undefined) {
|
|
75
|
+
sets.push(`events = $${idx++}`);
|
|
76
|
+
values.push(input.events);
|
|
77
|
+
}
|
|
78
|
+
if (input.active !== undefined) {
|
|
79
|
+
sets.push(`active = $${idx++}`);
|
|
80
|
+
values.push(input.active);
|
|
81
|
+
}
|
|
82
|
+
if (input.description !== undefined) {
|
|
83
|
+
sets.push(`description = $${idx++}`);
|
|
84
|
+
values.push(input.description);
|
|
85
|
+
}
|
|
86
|
+
if (sets.length === 0) {
|
|
87
|
+
const current = await client.query(`SELECT ${WEBHOOK_PUBLIC_COLS} FROM webhooks WHERE id = $1`, [id]);
|
|
88
|
+
return current.rows[0];
|
|
89
|
+
}
|
|
90
|
+
sets.push(`updated_at = now()`);
|
|
91
|
+
values.push(id);
|
|
92
|
+
const res = await client.query(`UPDATE webhooks SET ${sets.join(", ")} WHERE id = $${idx} RETURNING ${WEBHOOK_PUBLIC_COLS}`, values);
|
|
93
|
+
return res.rows[0];
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
exports.updateWebhook = updateWebhook;
|
|
97
|
+
async function deleteWebhook(pool, id) {
|
|
98
|
+
return (0, pool_helpers_js_1.withTransaction)(pool, async (client) => {
|
|
99
|
+
const res = await client.query(`DELETE FROM webhooks WHERE id = $1 RETURNING id`, [id]);
|
|
100
|
+
if (res.rows.length === 0) {
|
|
101
|
+
throw new core_1.WebhookNotFoundError(id);
|
|
102
|
+
}
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
exports.deleteWebhook = deleteWebhook;
|
|
106
|
+
async function listWebhookDeliveries(pool, webhookId) {
|
|
107
|
+
return (0, pool_helpers_js_1.withClient)(pool, async (client) => {
|
|
108
|
+
// Verify webhook exists
|
|
109
|
+
const existing = await client.query(`SELECT id FROM webhooks WHERE id = $1`, [webhookId]);
|
|
110
|
+
if (existing.rows.length === 0) {
|
|
111
|
+
throw new core_1.WebhookNotFoundError(webhookId);
|
|
112
|
+
}
|
|
113
|
+
const res = await client.query(`SELECT id, webhook_id, event_id, status, attempts, next_retry_at, last_error, response_code, created_at, completed_at
|
|
114
|
+
FROM webhook_deliveries WHERE webhook_id = $1 ORDER BY created_at DESC LIMIT 100`, [webhookId]);
|
|
115
|
+
return res.rows;
|
|
116
|
+
});
|
|
117
|
+
}
|
|
118
|
+
exports.listWebhookDeliveries = listWebhookDeliveries;
|
|
119
|
+
async function getWebhooksForEvent(pool, eventType, tenantId) {
|
|
120
|
+
return (0, pool_helpers_js_1.withClient)(pool, async (client) => {
|
|
121
|
+
const res = await client.query(`SELECT ${WEBHOOK_PUBLIC_COLS}, secret_encrypted FROM webhooks
|
|
122
|
+
WHERE active = true
|
|
123
|
+
AND $1 = ANY(events)
|
|
124
|
+
AND (tenant_id IS NULL OR tenant_id = $2)`, [eventType, tenantId]);
|
|
125
|
+
return res.rows;
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
exports.getWebhooksForEvent = getWebhooksForEvent;
|
|
129
|
+
//# sourceMappingURL=webhook-service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"webhook-service.js","sourceRoot":"","sources":["../../src/services/webhook-service.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import pg from "pg";
|
|
2
|
+
import * as tenantService from "./services/tenant-service.js";
|
|
3
|
+
import * as apiKeyService from "./services/api-key-service.js";
|
|
4
|
+
import * as eventService from "./services/event-service.js";
|
|
5
|
+
import * as keyRotationService from "./services/key-rotation-service.js";
|
|
6
|
+
import * as roleService from "./services/role-service.js";
|
|
7
|
+
import type { TenantNode, CreateTenantInput, UpdateTenantInput, PaginationInput, PaginatedResult, ConfigEntry, SetConfigInput, ResolvedConfig, BatchSetConfigResult, PermissionPolicy, CreatePermissionInput, UpdatePermissionInput, ResolvedPermission, Webhook, CreateWebhookInput, UpdateWebhookInput, AuditContext, AuditEntry, AuditLogQuery, ConsentRecord, GrantConsentInput, Region, CreateRegionInput, UpdateRegionInput, TenantContext, ConfigDiff } from "@stratum-hq/core";
|
|
8
|
+
export interface StratumOptions {
|
|
9
|
+
pool: pg.Pool;
|
|
10
|
+
keyPrefix?: string;
|
|
11
|
+
}
|
|
12
|
+
export declare class Stratum {
|
|
13
|
+
private readonly pool;
|
|
14
|
+
private readonly keyPrefix;
|
|
15
|
+
constructor(options: StratumOptions);
|
|
16
|
+
private emitEvent;
|
|
17
|
+
createTenant(input: CreateTenantInput, audit?: AuditContext): Promise<TenantNode>;
|
|
18
|
+
getTenant(id: string, includeArchived?: boolean): Promise<TenantNode>;
|
|
19
|
+
listTenants(pagination: PaginationInput): Promise<PaginatedResult<TenantNode>>;
|
|
20
|
+
updateTenant(id: string, patch: UpdateTenantInput, audit?: AuditContext): Promise<TenantNode>;
|
|
21
|
+
deleteTenant(id: string, audit?: AuditContext): Promise<void>;
|
|
22
|
+
moveTenant(id: string, newParentId: string, audit?: AuditContext): Promise<TenantNode>;
|
|
23
|
+
getAncestors(id: string): Promise<TenantNode[]>;
|
|
24
|
+
getDescendants(id: string): Promise<TenantNode[]>;
|
|
25
|
+
getChildren(id: string): Promise<TenantNode[]>;
|
|
26
|
+
getTenantContext(tenantId: string): Promise<TenantContext>;
|
|
27
|
+
resolveConfig(tenantId: string): Promise<ResolvedConfig>;
|
|
28
|
+
setConfig(tenantId: string, key: string, input: SetConfigInput, audit?: AuditContext): Promise<ConfigEntry>;
|
|
29
|
+
deleteConfig(tenantId: string, key: string, audit?: AuditContext): Promise<void>;
|
|
30
|
+
getConfigWithInheritance(tenantId: string): Promise<ResolvedConfig>;
|
|
31
|
+
diffConfig(tenantIdA: string, tenantIdB: string): Promise<ConfigDiff>;
|
|
32
|
+
resolvePermissions(tenantId: string): Promise<Record<string, ResolvedPermission>>;
|
|
33
|
+
createPermission(tenantId: string, input: CreatePermissionInput, audit?: AuditContext): Promise<PermissionPolicy>;
|
|
34
|
+
updatePermission(tenantId: string, policyId: string, input: UpdatePermissionInput, audit?: AuditContext): Promise<PermissionPolicy>;
|
|
35
|
+
deletePermission(tenantId: string, policyId: string, audit?: AuditContext): Promise<void>;
|
|
36
|
+
createApiKey(tenantId: string, nameOrOptions?: string | apiKeyService.CreateApiKeyOptions, expiresAt?: Date): Promise<apiKeyService.CreatedApiKey>;
|
|
37
|
+
validateApiKey(key: string): Promise<apiKeyService.ValidatedApiKey | null>;
|
|
38
|
+
revokeApiKey(keyId: string): Promise<boolean>;
|
|
39
|
+
rotateApiKey(keyId: string, newName?: string): Promise<apiKeyService.CreatedApiKey>;
|
|
40
|
+
listApiKeys(tenantId?: string): Promise<Array<{
|
|
41
|
+
id: string;
|
|
42
|
+
tenant_id: string | null;
|
|
43
|
+
name: string | null;
|
|
44
|
+
created_at: Date;
|
|
45
|
+
last_used_at: Date | null;
|
|
46
|
+
revoked_at: Date | null;
|
|
47
|
+
expires_at: Date | null;
|
|
48
|
+
}>>;
|
|
49
|
+
listDormantKeys(dormantDays?: number): Promise<Array<{
|
|
50
|
+
id: string;
|
|
51
|
+
tenant_id: string | null;
|
|
52
|
+
name: string | null;
|
|
53
|
+
last_used_at: Date | null;
|
|
54
|
+
created_at: Date;
|
|
55
|
+
}>>;
|
|
56
|
+
createWebhook(input: CreateWebhookInput, audit?: AuditContext): Promise<Webhook>;
|
|
57
|
+
getWebhook(id: string): Promise<Webhook>;
|
|
58
|
+
listWebhooks(tenantId?: string): Promise<Webhook[]>;
|
|
59
|
+
updateWebhook(id: string, input: UpdateWebhookInput, audit?: AuditContext): Promise<Webhook>;
|
|
60
|
+
deleteWebhook(id: string, audit?: AuditContext): Promise<void>;
|
|
61
|
+
listWebhookDeliveries(webhookId: string): Promise<Record<string, unknown>[]>;
|
|
62
|
+
testWebhook(id: string): Promise<{
|
|
63
|
+
success: boolean;
|
|
64
|
+
response_code: number | null;
|
|
65
|
+
error?: string;
|
|
66
|
+
}>;
|
|
67
|
+
listFailedDeliveries(limit?: number, tenantId?: string): Promise<Record<string, unknown>[]>;
|
|
68
|
+
retryDelivery(deliveryId: string): Promise<boolean>;
|
|
69
|
+
retryFailedDeliveries(tenantId?: string): Promise<number>;
|
|
70
|
+
getDeliveryStats(tenantId?: string): Promise<eventService.DeliveryStats>;
|
|
71
|
+
queryAuditLogs(query: AuditLogQuery): Promise<AuditEntry[]>;
|
|
72
|
+
getAuditEntry(id: string): Promise<AuditEntry | null>;
|
|
73
|
+
grantConsent(tenantId: string, input: GrantConsentInput, audit?: AuditContext): Promise<ConsentRecord>;
|
|
74
|
+
revokeConsent(tenantId: string, subjectId: string, purpose: string, audit?: AuditContext): Promise<boolean>;
|
|
75
|
+
listConsent(tenantId: string, subjectId?: string): Promise<ConsentRecord[]>;
|
|
76
|
+
getActiveConsent(tenantId: string, subjectId: string, purpose: string): Promise<ConsentRecord | null>;
|
|
77
|
+
purgeExpiredData(retentionDays?: number): Promise<{
|
|
78
|
+
deleted_count: number;
|
|
79
|
+
}>;
|
|
80
|
+
purgeTenant(tenantId: string, audit?: AuditContext): Promise<void>;
|
|
81
|
+
exportTenantData(tenantId: string): Promise<Record<string, unknown>>;
|
|
82
|
+
createRegion(input: CreateRegionInput, audit?: AuditContext): Promise<Region>;
|
|
83
|
+
getRegion(id: string): Promise<Region>;
|
|
84
|
+
listRegions(): Promise<Region[]>;
|
|
85
|
+
updateRegion(id: string, input: UpdateRegionInput, audit?: AuditContext): Promise<Region>;
|
|
86
|
+
deleteRegion(id: string, audit?: AuditContext): Promise<void>;
|
|
87
|
+
migrateRegion(tenantId: string, newRegionId: string, audit?: AuditContext): Promise<void>;
|
|
88
|
+
createRole(input: roleService.CreateRoleInput, audit?: AuditContext): Promise<roleService.Role>;
|
|
89
|
+
getRole(id: string): Promise<roleService.Role | null>;
|
|
90
|
+
listRoles(tenantId?: string): Promise<roleService.Role[]>;
|
|
91
|
+
updateRole(id: string, input: roleService.UpdateRoleInput, audit?: AuditContext): Promise<roleService.Role | null>;
|
|
92
|
+
deleteRole(id: string, audit?: AuditContext): Promise<boolean>;
|
|
93
|
+
assignRoleToKey(keyId: string, roleId: string): Promise<boolean>;
|
|
94
|
+
removeRoleFromKey(keyId: string): Promise<boolean>;
|
|
95
|
+
resolveKeyScopes(keyId: string): Promise<string[]>;
|
|
96
|
+
batchCreateTenants(inputs: CreateTenantInput[], audit?: AuditContext): Promise<tenantService.BatchCreateResult>;
|
|
97
|
+
batchSetConfig(tenantId: string, entries: Array<{
|
|
98
|
+
key: string;
|
|
99
|
+
value: unknown;
|
|
100
|
+
locked?: boolean;
|
|
101
|
+
sensitive?: boolean;
|
|
102
|
+
}>, audit?: AuditContext): Promise<BatchSetConfigResult>;
|
|
103
|
+
rotateEncryptionKey(oldKeyMaterial: string, newKeyMaterial: string, audit?: AuditContext): Promise<keyRotationService.KeyRotationResult>;
|
|
104
|
+
/** Validates that a webhook URL does not target internal/private networks. */
|
|
105
|
+
private validateWebhookUrl;
|
|
106
|
+
}
|
|
107
|
+
//# sourceMappingURL=stratum.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stratum.d.ts","sourceRoot":"","sources":["../src/stratum.ts"],"names":[],"mappings":"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"}
|