@authhero/multi-tenancy 14.24.0 → 14.25.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/multi-tenancy.cjs +1 -1
- package/dist/multi-tenancy.mjs +281 -224
- package/dist/types/index.d.ts +2 -2
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/rollout/defaults-projection.d.ts +47 -1
- package/dist/types/rollout/defaults-projection.d.ts.map +1 -1
- package/dist/types/rollout/index.d.ts +3 -1
- package/dist/types/rollout/index.d.ts.map +1 -1
- package/dist/types/rollout/payload.d.ts +57 -0
- package/dist/types/rollout/payload.d.ts.map +1 -0
- package/dist/types/routes/tenants.d.ts.map +1 -1
- package/package.json +3 -3
package/dist/multi-tenancy.mjs
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { Hono as e } from "hono";
|
|
2
|
-
import { MANAGEMENT_API_AUDIENCE as t, MANAGEMENT_API_SCOPES as n, auth0QuerySchema as r,
|
|
3
|
-
import { OpenAPIHono as
|
|
2
|
+
import { MANAGEMENT_API_AUDIENCE as t, MANAGEMENT_API_SCOPES as n, auth0QuerySchema as r, brandingSchema as i, connectionInsertSchema as a, connectionOptionsSchema as o, connectionSchema as s, deepMergePatch as c, emailProviderSchema as l, fetchAll as u, hookInsertSchema as d, init as f, listControlPlaneKeys as p, promptSettingSchema as m, resourceServerInsertSchema as h, tenantInsertSchema as g, tenantSchema as _ } from "authhero";
|
|
3
|
+
import { OpenAPIHono as v, createRoute as y, z as b } from "@hono/zod-openapi";
|
|
4
|
+
import { HTTPException as x } from "hono/http-exception";
|
|
4
5
|
//#region src/hooks/access-control.ts
|
|
5
|
-
function
|
|
6
|
+
function S(e) {
|
|
6
7
|
let { controlPlaneTenantId: t, requireOrganizationMatch: n = !0 } = e;
|
|
7
8
|
return { async onTenantAccessValidation(e, r) {
|
|
8
9
|
if (r === t) return !0;
|
|
@@ -13,14 +14,14 @@ function _(e) {
|
|
|
13
14
|
return !0;
|
|
14
15
|
} };
|
|
15
16
|
}
|
|
16
|
-
function
|
|
17
|
+
function C(e, t, n, r) {
|
|
17
18
|
if (t === n) return !0;
|
|
18
19
|
let i = r || e;
|
|
19
20
|
return i ? i.toLowerCase() === t.toLowerCase() : !1;
|
|
20
21
|
}
|
|
21
22
|
//#endregion
|
|
22
23
|
//#region src/hooks/database.ts
|
|
23
|
-
function
|
|
24
|
+
function w(e) {
|
|
24
25
|
return { async resolveDataAdapters(t) {
|
|
25
26
|
try {
|
|
26
27
|
return await e.getAdapters(t);
|
|
@@ -32,20 +33,20 @@ function y(e) {
|
|
|
32
33
|
}
|
|
33
34
|
//#endregion
|
|
34
35
|
//#region src/hooks/provisioning.ts
|
|
35
|
-
function
|
|
36
|
+
function T(e) {
|
|
36
37
|
return `urn:authhero:tenant:${e.toLowerCase()}`;
|
|
37
38
|
}
|
|
38
|
-
function
|
|
39
|
+
function E(e) {
|
|
39
40
|
return {
|
|
40
41
|
async beforeCreate(e, t) {
|
|
41
42
|
return !t.audience && t.id ? {
|
|
42
43
|
...t,
|
|
43
|
-
audience:
|
|
44
|
+
audience: T(t.id)
|
|
44
45
|
} : t;
|
|
45
46
|
},
|
|
46
47
|
async afterCreate(t, n) {
|
|
47
48
|
let { accessControl: r, databaseIsolation: i } = e;
|
|
48
|
-
r && t.ctx && await
|
|
49
|
+
r && t.ctx && await ee(t, n, r), i?.onProvision && await i.onProvision(n.id);
|
|
49
50
|
},
|
|
50
51
|
async beforeDelete(t, n) {
|
|
51
52
|
let { accessControl: r, databaseIsolation: i } = e;
|
|
@@ -63,14 +64,14 @@ function x(e) {
|
|
|
63
64
|
}
|
|
64
65
|
};
|
|
65
66
|
}
|
|
66
|
-
async function
|
|
67
|
+
async function ee(e, t, n) {
|
|
67
68
|
let { controlPlaneTenantId: r, defaultPermissions: i, defaultRoles: a, issuer: o, adminRoleName: s = "Tenant Admin", adminRoleDescription: c = "Full access to all tenant management operations", addCreatorToOrganization: l = !0 } = n, u = await e.adapters.organizations.create(r, {
|
|
68
69
|
name: t.id,
|
|
69
70
|
display_name: t.friendly_name || t.id
|
|
70
71
|
}), d;
|
|
71
|
-
if (o && (d = await
|
|
72
|
+
if (o && (d = await ne(e, r, s, c)), l && e.ctx) {
|
|
72
73
|
let t = e.ctx.var.user;
|
|
73
|
-
if (t?.sub && !await
|
|
74
|
+
if (t?.sub && !await te(e, r, t.sub)) try {
|
|
74
75
|
await e.adapters.userOrganizations.create(r, {
|
|
75
76
|
user_id: t.sub,
|
|
76
77
|
organization_id: u.id
|
|
@@ -81,12 +82,12 @@ async function S(e, t, n) {
|
|
|
81
82
|
}
|
|
82
83
|
a && a.length > 0 && console.log(`Would assign roles ${a.join(", ")} to organization ${u.id}`), i && i.length > 0 && console.log(`Would grant permissions ${i.join(", ")} to organization ${u.id}`);
|
|
83
84
|
}
|
|
84
|
-
async function
|
|
85
|
+
async function te(e, t, n) {
|
|
85
86
|
let r = await e.adapters.userRoles.list(t, n, void 0, "");
|
|
86
87
|
for (let n of r) if ((await e.adapters.rolePermissions.list(t, n.id, { per_page: 1e3 })).some((e) => e.permission_name === "admin:organizations")) return !0;
|
|
87
88
|
return !1;
|
|
88
89
|
}
|
|
89
|
-
async function
|
|
90
|
+
async function ne(e, r, i, a) {
|
|
90
91
|
let o = (await e.adapters.roles.list(r, {})).roles.find((e) => e.name === i);
|
|
91
92
|
if (o) return o.id;
|
|
92
93
|
let s = await e.adapters.roles.create(r, {
|
|
@@ -101,7 +102,7 @@ async function w(e, r, i, a) {
|
|
|
101
102
|
}
|
|
102
103
|
//#endregion
|
|
103
104
|
//#region src/hooks/sync.ts
|
|
104
|
-
function
|
|
105
|
+
function D(e, t, n = () => !0) {
|
|
105
106
|
let { controlPlaneTenantId: r, getChildTenantIds: i, getAdapters: a } = e, o = /* @__PURE__ */ new Map();
|
|
106
107
|
async function s(e, n, r) {
|
|
107
108
|
return (await t(e).list(n, {
|
|
@@ -156,18 +157,18 @@ function T(e, t, n = () => !0) {
|
|
|
156
157
|
}
|
|
157
158
|
};
|
|
158
159
|
}
|
|
159
|
-
function
|
|
160
|
+
function O(e, t, n = () => !0) {
|
|
160
161
|
let { controlPlaneTenantId: r, getControlPlaneAdapters: i, getAdapters: a } = e;
|
|
161
162
|
return { async afterCreate(e, o) {
|
|
162
163
|
if (o.id !== r) try {
|
|
163
|
-
let e = await i(), s = await a(o.id),
|
|
164
|
+
let e = await i(), s = await a(o.id), c = t(e), l = t(s), d = await u((e) => c.listPaginated(r, e), c.listKey, {
|
|
164
165
|
cursorField: "id",
|
|
165
166
|
pageSize: 100
|
|
166
167
|
});
|
|
167
168
|
await Promise.all(d.filter((e) => n(e)).map(async (e) => {
|
|
168
169
|
try {
|
|
169
|
-
let t =
|
|
170
|
-
await
|
|
170
|
+
let t = c.transform(e);
|
|
171
|
+
await l.create(o.id, {
|
|
171
172
|
...t,
|
|
172
173
|
is_system: !0
|
|
173
174
|
});
|
|
@@ -180,7 +181,7 @@ function E(e, t, n = () => !0) {
|
|
|
180
181
|
}
|
|
181
182
|
} };
|
|
182
183
|
}
|
|
183
|
-
var
|
|
184
|
+
var k = (e) => ({
|
|
184
185
|
list: async (t, n) => (await e.resourceServers.list(t, n)).resource_servers,
|
|
185
186
|
listPaginated: (t, n) => e.resourceServers.list(t, n),
|
|
186
187
|
get: (t, n) => e.resourceServers.get(t, n),
|
|
@@ -198,7 +199,7 @@ var D = (e) => ({
|
|
|
198
199
|
token_lifetime: e.token_lifetime,
|
|
199
200
|
token_lifetime_for_web: e.token_lifetime_for_web
|
|
200
201
|
})
|
|
201
|
-
}),
|
|
202
|
+
}), A = (e) => ({
|
|
202
203
|
list: async (t, n) => (await e.roles.list(t, n)).roles,
|
|
203
204
|
listPaginated: (t, n) => e.roles.list(t, n),
|
|
204
205
|
get: (t, n) => e.roles.get(t, n),
|
|
@@ -213,15 +214,15 @@ var D = (e) => ({
|
|
|
213
214
|
description: e.description
|
|
214
215
|
})
|
|
215
216
|
});
|
|
216
|
-
function
|
|
217
|
+
function re(e) {
|
|
217
218
|
return e.metadata?.sync !== !1;
|
|
218
219
|
}
|
|
219
|
-
function
|
|
220
|
-
let { sync: t = {}, filters: n = {} } = e, r = t.resourceServers ?? !0, i = t.roles ?? !0, a = (e) =>
|
|
220
|
+
function ie(e) {
|
|
221
|
+
let { sync: t = {}, filters: n = {} } = e, r = t.resourceServers ?? !0, i = t.roles ?? !0, a = (e) => re(e) ? n.resourceServers ? n.resourceServers(e) : !0 : !1, o = (e) => re(e) ? n.roles ? n.roles(e) : !0 : !1, s = r ? D(e, k, a) : void 0, c = i ? D(e, A, o) : void 0, l = r ? O(e, k, a) : void 0, d = i ? O(e, A, o) : void 0, f = i ? { async afterCreate(t, r) {
|
|
221
222
|
if (r.id !== e.controlPlaneTenantId) {
|
|
222
223
|
await d?.afterCreate?.(t, r);
|
|
223
224
|
try {
|
|
224
|
-
let t = await e.getControlPlaneAdapters(), i = await e.getAdapters(r.id), a = await
|
|
225
|
+
let t = await e.getControlPlaneAdapters(), i = await e.getAdapters(r.id), a = await u((n) => t.roles.list(e.controlPlaneTenantId, n), "roles", {
|
|
225
226
|
cursorField: "id",
|
|
226
227
|
pageSize: 100
|
|
227
228
|
}), o = /* @__PURE__ */ new Map();
|
|
@@ -256,10 +257,10 @@ function A(e) {
|
|
|
256
257
|
return {
|
|
257
258
|
entityHooks: {
|
|
258
259
|
resourceServers: s,
|
|
259
|
-
roles:
|
|
260
|
+
roles: c
|
|
260
261
|
},
|
|
261
262
|
tenantHooks: { async afterCreate(e, t) {
|
|
262
|
-
let n = [
|
|
263
|
+
let n = [l?.afterCreate, f?.afterCreate ?? d?.afterCreate], r = [];
|
|
263
264
|
for (let i of n) if (i) try {
|
|
264
265
|
await i(e, t);
|
|
265
266
|
} catch (e) {
|
|
@@ -271,36 +272,36 @@ function A(e) {
|
|
|
271
272
|
};
|
|
272
273
|
}
|
|
273
274
|
//#endregion
|
|
274
|
-
//#region ../../node_modules/.pnpm/hono@4.12.25/node_modules/hono/dist/http-exception.js
|
|
275
|
-
var j = class extends Error {
|
|
276
|
-
res;
|
|
277
|
-
status;
|
|
278
|
-
constructor(e = 500, t) {
|
|
279
|
-
super(t?.message, { cause: t?.cause }), this.res = t?.res, this.status = e;
|
|
280
|
-
}
|
|
281
|
-
getResponse() {
|
|
282
|
-
return this.res ? new Response(this.res.body, {
|
|
283
|
-
status: this.status,
|
|
284
|
-
headers: this.res.headers
|
|
285
|
-
}) : new Response(this.message, { status: this.status });
|
|
286
|
-
}
|
|
287
|
-
};
|
|
288
|
-
//#endregion
|
|
289
275
|
//#region src/routes/tenants.ts
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
276
|
+
var ae = b.object({
|
|
277
|
+
sub: b.string(),
|
|
278
|
+
tenant_id: b.string().optional(),
|
|
279
|
+
org_id: b.string().optional(),
|
|
280
|
+
scope: b.string().optional(),
|
|
281
|
+
permissions: b.array(b.string()).optional()
|
|
282
|
+
}).passthrough();
|
|
283
|
+
function oe(e) {
|
|
284
|
+
let t = ae.safeParse(e);
|
|
285
|
+
return t.success ? t.data : void 0;
|
|
286
|
+
}
|
|
287
|
+
function se(e) {
|
|
288
|
+
let t = e.permissions ?? [], n = e.scope ? e.scope.split(" ").filter(Boolean) : [], r = new Set([...t, ...n]);
|
|
289
|
+
return r.has("delete:tenants") || r.has("admin:organizations");
|
|
290
|
+
}
|
|
291
|
+
function j(e, t) {
|
|
292
|
+
let n = new v();
|
|
293
|
+
return n.openapi(y({
|
|
293
294
|
tags: ["tenants"],
|
|
294
295
|
method: "get",
|
|
295
296
|
path: "/",
|
|
296
297
|
request: { query: r },
|
|
297
298
|
security: [{ Bearer: [] }],
|
|
298
299
|
responses: { 200: {
|
|
299
|
-
content: { "application/json": { schema:
|
|
300
|
-
tenants:
|
|
301
|
-
start:
|
|
302
|
-
limit:
|
|
303
|
-
length:
|
|
300
|
+
content: { "application/json": { schema: b.object({
|
|
301
|
+
tenants: b.array(_),
|
|
302
|
+
start: b.number().optional(),
|
|
303
|
+
limit: b.number().optional(),
|
|
304
|
+
length: b.number().optional()
|
|
304
305
|
}) } },
|
|
305
306
|
description: "List of tenants"
|
|
306
307
|
} }
|
|
@@ -320,17 +321,17 @@ function M(e, t) {
|
|
|
320
321
|
length: e.tenants.length
|
|
321
322
|
}) : t.json({ tenants: e.tenants });
|
|
322
323
|
}
|
|
323
|
-
let
|
|
324
|
-
if (
|
|
325
|
-
if (
|
|
326
|
-
let e = (await
|
|
324
|
+
let c = e.accessControl?.controlPlaneTenantId ?? t.env.data.multiTenancyConfig?.controlPlaneTenantId;
|
|
325
|
+
if (c && !o?.sub) throw new x(403, { message: "Access denied: token has no subject" });
|
|
326
|
+
if (c && o?.sub) {
|
|
327
|
+
let e = (await u((e) => t.env.data.userOrganizations.listUserOrganizations(c, o.sub, e), "organizations")).map((e) => e.name);
|
|
327
328
|
if (e.length === 0) return i ? t.json({
|
|
328
329
|
tenants: [],
|
|
329
330
|
start: 0,
|
|
330
331
|
limit: r ?? 50,
|
|
331
332
|
length: 0
|
|
332
333
|
}) : t.json({ tenants: [] });
|
|
333
|
-
let s = e.length,
|
|
334
|
+
let s = e.length, l = n ?? 0, d = r ?? 50, f = l * d, p = e.slice(f, f + d);
|
|
334
335
|
if (p.length === 0) return i ? t.json({
|
|
335
336
|
tenants: [],
|
|
336
337
|
start: f,
|
|
@@ -349,34 +350,34 @@ function M(e, t) {
|
|
|
349
350
|
length: s
|
|
350
351
|
}) : t.json({ tenants: g.tenants });
|
|
351
352
|
}
|
|
352
|
-
let
|
|
353
|
+
let l = await t.env.data.tenants.list({
|
|
353
354
|
page: n,
|
|
354
355
|
per_page: r,
|
|
355
356
|
include_totals: i,
|
|
356
357
|
q: a
|
|
357
358
|
});
|
|
358
359
|
return i ? t.json({
|
|
359
|
-
tenants:
|
|
360
|
-
start:
|
|
361
|
-
limit:
|
|
362
|
-
length:
|
|
363
|
-
}) : t.json({ tenants:
|
|
364
|
-
}), n.openapi(
|
|
360
|
+
tenants: l.tenants,
|
|
361
|
+
start: l.totals?.start ?? 0,
|
|
362
|
+
limit: l.totals?.limit ?? r,
|
|
363
|
+
length: l.tenants.length
|
|
364
|
+
}) : t.json({ tenants: l.tenants });
|
|
365
|
+
}), n.openapi(y({
|
|
365
366
|
tags: ["tenants"],
|
|
366
367
|
method: "post",
|
|
367
368
|
path: "/",
|
|
368
|
-
request: { body: { content: { "application/json": { schema:
|
|
369
|
+
request: { body: { content: { "application/json": { schema: g } } } },
|
|
369
370
|
security: [{ Bearer: [] }],
|
|
370
371
|
responses: {
|
|
371
372
|
201: {
|
|
372
|
-
content: { "application/json": { schema:
|
|
373
|
+
content: { "application/json": { schema: _ } },
|
|
373
374
|
description: "Tenant created"
|
|
374
375
|
},
|
|
375
376
|
400: { description: "Validation error" },
|
|
376
377
|
409: { description: "Tenant with this ID already exists" }
|
|
377
378
|
}
|
|
378
379
|
}), async (e) => {
|
|
379
|
-
if (!e.var.user?.sub) throw new
|
|
380
|
+
if (!e.var.user?.sub) throw new x(401, { message: "Authentication required to create tenants" });
|
|
380
381
|
let n = e.req.valid("json"), r = {
|
|
381
382
|
adapters: e.env.data,
|
|
382
383
|
ctx: e
|
|
@@ -384,11 +385,11 @@ function M(e, t) {
|
|
|
384
385
|
t.tenants?.beforeCreate && (n = await t.tenants.beforeCreate(r, n));
|
|
385
386
|
let i = await e.env.data.tenants.create(n);
|
|
386
387
|
return t.tenants?.afterCreate && await t.tenants.afterCreate(r, i), e.json(i, 201);
|
|
387
|
-
}), n.openapi(
|
|
388
|
+
}), n.openapi(y({
|
|
388
389
|
tags: ["tenants"],
|
|
389
390
|
method: "delete",
|
|
390
391
|
path: "/{id}",
|
|
391
|
-
request: { params:
|
|
392
|
+
request: { params: b.object({ id: b.string() }) },
|
|
392
393
|
security: [{ Bearer: ["delete:tenants"] }],
|
|
393
394
|
responses: {
|
|
394
395
|
204: { description: "Tenant deleted" },
|
|
@@ -398,58 +399,62 @@ function M(e, t) {
|
|
|
398
399
|
}), async (n) => {
|
|
399
400
|
let { id: r } = n.req.valid("param"), i = e.accessControl?.controlPlaneTenantId ?? n.env.data.multiTenancyConfig?.controlPlaneTenantId;
|
|
400
401
|
if (i) {
|
|
401
|
-
let e = n.var.user;
|
|
402
|
-
if (!e?.sub) throw new
|
|
403
|
-
if (r === i) throw new
|
|
402
|
+
let e = oe(n.var.user);
|
|
403
|
+
if (!e?.sub) throw new x(401, { message: "Authentication required" });
|
|
404
|
+
if (r === i) throw new x(403, { message: "Cannot delete the control plane" });
|
|
404
405
|
let t = n.var.org_name, a = r.toLowerCase(), o = !!t && t.toLowerCase() === a;
|
|
405
|
-
if (
|
|
406
|
+
if (!o) {
|
|
407
|
+
let r = !!(e.org_id ?? n.var.organization_id ?? t), a = !e.tenant_id || e.tenant_id === i;
|
|
408
|
+
!r && a && se(e) && (o = !0);
|
|
409
|
+
}
|
|
410
|
+
if (o ||= (await u((t) => n.env.data.userOrganizations.listUserOrganizations(i, e.sub, t), "organizations")).some((e) => e.name?.toLowerCase() === a), !o) throw new x(403, { message: "Access denied to this tenant" });
|
|
406
411
|
}
|
|
407
|
-
if (!await n.env.data.tenants.get(r)) throw new
|
|
412
|
+
if (!await n.env.data.tenants.get(r)) throw new x(404, { message: "Tenant not found" });
|
|
408
413
|
let a = {
|
|
409
414
|
adapters: n.env.data,
|
|
410
415
|
ctx: n
|
|
411
416
|
};
|
|
412
417
|
return t.tenants?.beforeDelete && await t.tenants.beforeDelete(a, r), await n.env.data.tenants.remove(r), t.tenants?.afterDelete && await t.tenants.afterDelete(a, r), n.body(null, 204);
|
|
413
|
-
}), n.openapi(
|
|
418
|
+
}), n.openapi(y({
|
|
414
419
|
tags: ["tenants", "settings"],
|
|
415
420
|
method: "get",
|
|
416
421
|
path: "/settings",
|
|
417
|
-
request: { headers:
|
|
422
|
+
request: { headers: b.object({ "tenant-id": b.string().optional() }) },
|
|
418
423
|
security: [{ Bearer: ["read:tenants"] }],
|
|
419
424
|
responses: { 200: {
|
|
420
|
-
content: { "application/json": { schema:
|
|
425
|
+
content: { "application/json": { schema: _ } },
|
|
421
426
|
description: "Current tenant settings"
|
|
422
427
|
} }
|
|
423
428
|
}), async (e) => {
|
|
424
429
|
let t = await e.env.data.tenants.get(e.var.tenant_id);
|
|
425
|
-
if (!t) throw new
|
|
430
|
+
if (!t) throw new x(404, { message: "Tenant not found" });
|
|
426
431
|
return e.json(t);
|
|
427
|
-
}), n.openapi(
|
|
432
|
+
}), n.openapi(y({
|
|
428
433
|
tags: ["tenants", "settings"],
|
|
429
434
|
method: "patch",
|
|
430
435
|
path: "/settings",
|
|
431
436
|
request: {
|
|
432
|
-
headers:
|
|
433
|
-
body: { content: { "application/json": { schema:
|
|
437
|
+
headers: b.object({ "tenant-id": b.string().optional() }),
|
|
438
|
+
body: { content: { "application/json": { schema: b.object(g.shape).partial() } } }
|
|
434
439
|
},
|
|
435
440
|
security: [{ Bearer: ["update:tenants"] }],
|
|
436
441
|
responses: { 200: {
|
|
437
|
-
content: { "application/json": { schema:
|
|
442
|
+
content: { "application/json": { schema: _ } },
|
|
438
443
|
description: "Updated tenant settings"
|
|
439
444
|
} }
|
|
440
445
|
}), async (e) => {
|
|
441
446
|
let { id: t, ...n } = e.req.valid("json"), r = await e.env.data.tenants.get(e.var.tenant_id);
|
|
442
|
-
if (!r) throw new
|
|
443
|
-
let i =
|
|
447
|
+
if (!r) throw new x(404, { message: "Tenant not found" });
|
|
448
|
+
let i = c(r, n);
|
|
444
449
|
await e.env.data.tenants.update(e.var.tenant_id, i);
|
|
445
450
|
let a = await e.env.data.tenants.get(e.var.tenant_id);
|
|
446
|
-
if (!a) throw new
|
|
451
|
+
if (!a) throw new x(500, { message: "Failed to retrieve updated tenant" });
|
|
447
452
|
return e.json(a);
|
|
448
453
|
}), n;
|
|
449
454
|
}
|
|
450
455
|
//#endregion
|
|
451
456
|
//#region src/middleware/protect-synced.ts
|
|
452
|
-
function
|
|
457
|
+
function ce(e) {
|
|
453
458
|
for (let { pattern: t, type: n } of [
|
|
454
459
|
{
|
|
455
460
|
pattern: /\/api\/v2\/resource-servers\/([^/]+)$/,
|
|
@@ -472,7 +477,7 @@ function ee(e) {
|
|
|
472
477
|
}
|
|
473
478
|
return null;
|
|
474
479
|
}
|
|
475
|
-
async function
|
|
480
|
+
async function le(e, t, n) {
|
|
476
481
|
try {
|
|
477
482
|
switch (n.type) {
|
|
478
483
|
case "resource_server": return (await e.resourceServers.get(t, n.id))?.is_system === !0;
|
|
@@ -484,47 +489,47 @@ async function te(e, t, n) {
|
|
|
484
489
|
return !1;
|
|
485
490
|
}
|
|
486
491
|
}
|
|
487
|
-
function
|
|
492
|
+
function ue(e) {
|
|
488
493
|
return {
|
|
489
494
|
resource_server: "resource server",
|
|
490
495
|
role: "role",
|
|
491
496
|
connection: "connection"
|
|
492
497
|
}[e];
|
|
493
498
|
}
|
|
494
|
-
function
|
|
499
|
+
function M() {
|
|
495
500
|
return async (e, t) => {
|
|
496
501
|
if (![
|
|
497
502
|
"PATCH",
|
|
498
503
|
"PUT",
|
|
499
504
|
"DELETE"
|
|
500
505
|
].includes(e.req.method)) return t();
|
|
501
|
-
let n =
|
|
506
|
+
let n = ce(e.req.path);
|
|
502
507
|
if (!n) return t();
|
|
503
508
|
let r = e.var.tenant_id || e.req.header("x-tenant-id") || e.req.header("tenant-id");
|
|
504
509
|
if (!r) return t();
|
|
505
|
-
if (await
|
|
510
|
+
if (await le(e.env.data, r, n)) throw new x(403, { message: `This ${ue(n.type)} is a system resource and cannot be modified. Make changes in the control plane instead.` });
|
|
506
511
|
return t();
|
|
507
512
|
};
|
|
508
513
|
}
|
|
509
514
|
//#endregion
|
|
510
515
|
//#region src/middleware/settings-inheritance.ts
|
|
511
|
-
function
|
|
516
|
+
function N(e, t) {
|
|
512
517
|
let n = t.find((t) => t.strategy === e.strategy);
|
|
513
518
|
if (!n?.options) return e;
|
|
514
|
-
let r =
|
|
519
|
+
let r = s.passthrough().parse({
|
|
515
520
|
...n,
|
|
516
521
|
...e
|
|
517
522
|
});
|
|
518
|
-
return r.options =
|
|
523
|
+
return r.options = o.passthrough().parse({
|
|
519
524
|
...n.options || {},
|
|
520
525
|
...e.options
|
|
521
526
|
}), r;
|
|
522
527
|
}
|
|
523
|
-
function
|
|
528
|
+
function P(e, t) {
|
|
524
529
|
let n = [...t || [], ...e || []];
|
|
525
530
|
return [...new Set(n)];
|
|
526
531
|
}
|
|
527
|
-
function
|
|
532
|
+
function de(e, t) {
|
|
528
533
|
if (!t?.length) return e || [];
|
|
529
534
|
if (!e?.length) return t;
|
|
530
535
|
let n = /* @__PURE__ */ new Map();
|
|
@@ -532,22 +537,22 @@ function I(e, t) {
|
|
|
532
537
|
for (let t of e) n.set(t.value, t);
|
|
533
538
|
return Array.from(n.values());
|
|
534
539
|
}
|
|
535
|
-
function
|
|
540
|
+
function F(e, t) {
|
|
536
541
|
return t ? {
|
|
537
542
|
...e,
|
|
538
|
-
scopes:
|
|
543
|
+
scopes: de(e.scopes, t.scopes)
|
|
539
544
|
} : e;
|
|
540
545
|
}
|
|
541
|
-
function
|
|
546
|
+
function fe(e, t) {
|
|
542
547
|
return t ? {
|
|
543
548
|
...e,
|
|
544
|
-
callbacks:
|
|
545
|
-
web_origins:
|
|
546
|
-
allowed_logout_urls:
|
|
547
|
-
allowed_origins:
|
|
549
|
+
callbacks: P(e.callbacks, t.callbacks),
|
|
550
|
+
web_origins: P(e.web_origins, t.web_origins),
|
|
551
|
+
allowed_logout_urls: P(e.allowed_logout_urls, t.allowed_logout_urls),
|
|
552
|
+
allowed_origins: P(e.allowed_origins, t.allowed_origins)
|
|
548
553
|
} : e;
|
|
549
554
|
}
|
|
550
|
-
function
|
|
555
|
+
function I(e) {
|
|
551
556
|
let { controlPlaneTenantId: t, controlPlaneClientId: n, resolveControlPlane: r } = e;
|
|
552
557
|
if (r) return async (e) => r({ tenant_id: e });
|
|
553
558
|
if (!t) return async () => void 0;
|
|
@@ -557,14 +562,14 @@ function R(e) {
|
|
|
557
562
|
};
|
|
558
563
|
return async () => i;
|
|
559
564
|
}
|
|
560
|
-
function
|
|
565
|
+
function L(e, t) {
|
|
561
566
|
return {
|
|
562
567
|
...e.resourceServers,
|
|
563
568
|
get: async (n, r) => {
|
|
564
569
|
let i = await e.resourceServers.get(n, r);
|
|
565
570
|
if (!i) return i;
|
|
566
571
|
let a = await t(n);
|
|
567
|
-
return !a || n === a.tenantId || !i.is_system ? i :
|
|
572
|
+
return !a || n === a.tenantId || !i.is_system ? i : F(i, await e.resourceServers.get(a.tenantId, r));
|
|
568
573
|
},
|
|
569
574
|
list: async (n, r) => {
|
|
570
575
|
let i = await e.resourceServers.list(n, r), a = await t(n);
|
|
@@ -576,7 +581,7 @@ function z(e, t) {
|
|
|
576
581
|
let n = await e.resourceServers.get(o, t);
|
|
577
582
|
n && c.set(t, n);
|
|
578
583
|
}));
|
|
579
|
-
let l = i.resource_servers.map((e) => e.is_system && e.id ?
|
|
584
|
+
let l = i.resource_servers.map((e) => e.is_system && e.id ? F(e, c.get(e.id) ?? null) : e);
|
|
580
585
|
return {
|
|
581
586
|
...i,
|
|
582
587
|
resource_servers: l
|
|
@@ -584,18 +589,18 @@ function z(e, t) {
|
|
|
584
589
|
}
|
|
585
590
|
};
|
|
586
591
|
}
|
|
587
|
-
function
|
|
588
|
-
let n =
|
|
592
|
+
function R(e, t) {
|
|
593
|
+
let n = I({
|
|
589
594
|
controlPlaneTenantId: t.controlPlaneTenantId,
|
|
590
595
|
resolveControlPlane: t.resolveControlPlane
|
|
591
596
|
});
|
|
592
597
|
return {
|
|
593
598
|
...e,
|
|
594
|
-
resourceServers:
|
|
599
|
+
resourceServers: L(e, n)
|
|
595
600
|
};
|
|
596
601
|
}
|
|
597
|
-
function
|
|
598
|
-
let { controlPlaneTenantId: n, controlPlaneClientId: r, resolveControlPlane: i } = t, a =
|
|
602
|
+
function z(e, t) {
|
|
603
|
+
let { controlPlaneTenantId: n, controlPlaneClientId: r, resolveControlPlane: i } = t, a = I({
|
|
599
604
|
controlPlaneTenantId: n,
|
|
600
605
|
controlPlaneClientId: r,
|
|
601
606
|
resolveControlPlane: i
|
|
@@ -613,12 +618,12 @@ function V(e, t) {
|
|
|
613
618
|
let r = await e.connections.get(t, n);
|
|
614
619
|
if (!r) return r;
|
|
615
620
|
let i = await a(t);
|
|
616
|
-
return !i || t === i.tenantId ? r :
|
|
621
|
+
return !i || t === i.tenantId ? r : N(r, (await e.connections.list(i.tenantId)).connections || []);
|
|
617
622
|
},
|
|
618
623
|
list: async (t, n) => {
|
|
619
624
|
let r = await e.connections.list(t, n), i = await a(t);
|
|
620
625
|
if (!i || t === i.tenantId) return r;
|
|
621
|
-
let o = await e.connections.list(i.tenantId), s = r.connections.map((e) =>
|
|
626
|
+
let o = await e.connections.list(i.tenantId), s = r.connections.map((e) => N(e, o.connections || []));
|
|
622
627
|
return {
|
|
623
628
|
...r,
|
|
624
629
|
connections: s
|
|
@@ -633,7 +638,7 @@ function V(e, t) {
|
|
|
633
638
|
let i = await a(t);
|
|
634
639
|
if (!i || t === i.tenantId) return r;
|
|
635
640
|
let o = await e.connections.list(i.tenantId);
|
|
636
|
-
return r.map((e) =>
|
|
641
|
+
return r.map((e) => N(e, o.connections || []));
|
|
637
642
|
}
|
|
638
643
|
},
|
|
639
644
|
emailProviders: {
|
|
@@ -645,22 +650,22 @@ function V(e, t) {
|
|
|
645
650
|
return !r || t === r.tenantId ? null : e.emailProviders.get(r.tenantId);
|
|
646
651
|
}
|
|
647
652
|
},
|
|
648
|
-
resourceServers:
|
|
649
|
-
hooks:
|
|
653
|
+
resourceServers: L(e, a),
|
|
654
|
+
hooks: pe(e, a)
|
|
650
655
|
};
|
|
651
656
|
}
|
|
652
|
-
function
|
|
657
|
+
function B(e) {
|
|
653
658
|
if (!e || typeof e != "object") return !1;
|
|
654
659
|
let t = e.metadata;
|
|
655
660
|
return !t || typeof t != "object" ? !1 : t.inheritable === !0;
|
|
656
661
|
}
|
|
657
|
-
function
|
|
662
|
+
function pe(e, t) {
|
|
658
663
|
return {
|
|
659
664
|
...e.hooks,
|
|
660
665
|
list: async (n, r) => {
|
|
661
666
|
let i = await e.hooks.list(n, r), a = await t(n);
|
|
662
667
|
if (!a || n === a.tenantId) return i;
|
|
663
|
-
let o = ((await e.hooks.list(a.tenantId, r)).hooks || []).filter(
|
|
668
|
+
let o = ((await e.hooks.list(a.tenantId, r)).hooks || []).filter(B);
|
|
664
669
|
if (o.length === 0) return i;
|
|
665
670
|
let s = new Set((i.hooks || []).map((e) => e.hook_id)), c = o.filter((e) => !s.has(e.hook_id));
|
|
666
671
|
return {
|
|
@@ -675,31 +680,31 @@ function ie(e, t) {
|
|
|
675
680
|
let a = await t(n);
|
|
676
681
|
if (!a || n === a.tenantId) return i;
|
|
677
682
|
let o = await e.hooks.get(a.tenantId, r);
|
|
678
|
-
return o &&
|
|
683
|
+
return o && B(o) ? o : null;
|
|
679
684
|
}
|
|
680
685
|
};
|
|
681
686
|
}
|
|
682
|
-
function
|
|
683
|
-
return
|
|
687
|
+
function V(e, t) {
|
|
688
|
+
return z(e, t);
|
|
684
689
|
}
|
|
685
690
|
//#endregion
|
|
686
691
|
//#region src/middleware/index.ts
|
|
687
|
-
function
|
|
692
|
+
function H(e) {
|
|
688
693
|
return async (t, n) => {
|
|
689
694
|
let r = t.var.user;
|
|
690
695
|
return r?.tenant_id === e && r.org_name && t.set("tenant_id", r.org_name), n();
|
|
691
696
|
};
|
|
692
697
|
}
|
|
693
|
-
function
|
|
698
|
+
function U(e) {
|
|
694
699
|
return async (n, r) => {
|
|
695
700
|
if (!e.accessControl) return r();
|
|
696
701
|
let { controlPlaneTenantId: i } = e.accessControl, a = n.var.org_name, o = n.var.organization_id, s = a || o, c = n.var.tenant_id, l = n.var.user, u = (l?.aud ? Array.isArray(l.aud) ? l.aud : [l.aud] : []).includes(t);
|
|
697
|
-
if (!c && s && u && (n.set("tenant_id", s), c = s), !c) throw new
|
|
698
|
-
if (!
|
|
702
|
+
if (!c && s && u && (n.set("tenant_id", s), c = s), !c) throw new x(400, { message: "Tenant ID not found in request" });
|
|
703
|
+
if (!C(o, c, i, a)) throw new x(403, { message: `Access denied to tenant ${c}` });
|
|
699
704
|
return r();
|
|
700
705
|
};
|
|
701
706
|
}
|
|
702
|
-
function
|
|
707
|
+
function W(e) {
|
|
703
708
|
return async (t, n) => {
|
|
704
709
|
if (!e.subdomainRouting) return n();
|
|
705
710
|
let { baseDomain: r, reservedSubdomains: i = [], resolveSubdomain: a } = e.subdomainRouting, o = t.req.header("x-forwarded-host") || t.req.header("host") || "", s = null;
|
|
@@ -714,43 +719,43 @@ function K(e) {
|
|
|
714
719
|
let n = await t.env.data.organizations.get(e.accessControl.controlPlaneTenantId, s);
|
|
715
720
|
n && (c = n.id);
|
|
716
721
|
} catch {}
|
|
717
|
-
if (!c) throw new
|
|
722
|
+
if (!c) throw new x(404, { message: `Tenant not found for subdomain: ${s}` });
|
|
718
723
|
return t.set("tenant_id", c), n();
|
|
719
724
|
};
|
|
720
725
|
}
|
|
721
|
-
function
|
|
726
|
+
function G(e) {
|
|
722
727
|
return async (t, n) => {
|
|
723
728
|
if (!e.databaseIsolation) return n();
|
|
724
729
|
let r = t.var.tenant_id;
|
|
725
|
-
if (!r) throw new
|
|
730
|
+
if (!r) throw new x(400, { message: "Tenant ID not found in request" });
|
|
726
731
|
try {
|
|
727
732
|
let n = await e.databaseIsolation.getAdapters(r);
|
|
728
733
|
t.env.data = n;
|
|
729
734
|
} catch (e) {
|
|
730
|
-
throw console.error(`Failed to resolve database for tenant ${r}:`, e), new
|
|
735
|
+
throw console.error(`Failed to resolve database for tenant ${r}:`, e), new x(500, { message: "Failed to resolve tenant database" });
|
|
731
736
|
}
|
|
732
737
|
return n();
|
|
733
738
|
};
|
|
734
739
|
}
|
|
735
|
-
function
|
|
736
|
-
let t =
|
|
740
|
+
function K(e) {
|
|
741
|
+
let t = W(e), n = U(e), r = G(e);
|
|
737
742
|
return async (e, i) => (await t(e, async () => {}), await n(e, async () => {}), await r(e, async () => {}), i());
|
|
738
743
|
}
|
|
739
744
|
//#endregion
|
|
740
745
|
//#region src/init.ts
|
|
741
|
-
function
|
|
746
|
+
function me(e) {
|
|
742
747
|
let { dataAdapter: t, controlPlane: n, controlPlane: { tenantId: r = "control_plane", clientId: i } = {}, resolveControlPlane: a, sync: o = {
|
|
743
748
|
resourceServers: !0,
|
|
744
749
|
roles: !0
|
|
745
|
-
}, defaultPermissions: s = ["tenant:admin"], requireOrganizationMatch:
|
|
750
|
+
}, defaultPermissions: s = ["tenant:admin"], requireOrganizationMatch: c = !1, managementApiExtensions: l = [], entityHooks: d, getChildTenantIds: p, getAdapters: m, ...h } = e;
|
|
746
751
|
if (a && !n) throw Error("initMultiTenant: `resolveControlPlane` requires `controlPlane` to be set. The static `controlPlane.tenantId` is used for access control, sync direction, and tenant management routing; the resolver only overrides per-tenant runtime inheritance lookups on top of it.");
|
|
747
752
|
let g = t, _ = t;
|
|
748
|
-
n && (g =
|
|
753
|
+
n && (g = V(t, {
|
|
749
754
|
controlPlaneTenantId: r,
|
|
750
755
|
controlPlaneClientId: i,
|
|
751
756
|
resolveControlPlane: a
|
|
752
757
|
}), _ = {
|
|
753
|
-
...
|
|
758
|
+
...R(t, {
|
|
754
759
|
controlPlaneTenantId: r,
|
|
755
760
|
resolveControlPlane: a
|
|
756
761
|
}),
|
|
@@ -766,67 +771,88 @@ function ae(e) {
|
|
|
766
771
|
} : {
|
|
767
772
|
resourceServers: !1,
|
|
768
773
|
roles: !1
|
|
769
|
-
}, { entityHooks: b, tenantHooks:
|
|
774
|
+
}, { entityHooks: b, tenantHooks: x } = ie({
|
|
770
775
|
controlPlaneTenantId: r,
|
|
771
|
-
getChildTenantIds: p ?? (async () => (await
|
|
776
|
+
getChildTenantIds: p ?? (async () => (await u((e) => g.tenants.list(e), "tenants", {
|
|
772
777
|
cursorField: "id",
|
|
773
778
|
pageSize: 100
|
|
774
779
|
})).filter((e) => e.id !== r).map((e) => e.id)),
|
|
775
780
|
getAdapters: m ?? (async () => g),
|
|
776
781
|
getControlPlaneAdapters: async () => g,
|
|
777
782
|
sync: y
|
|
778
|
-
}),
|
|
779
|
-
resourceServers: [b.resourceServers, ...
|
|
780
|
-
roles: [b.roles, ...
|
|
781
|
-
connections:
|
|
782
|
-
tenants:
|
|
783
|
-
rolePermissions:
|
|
784
|
-
},
|
|
783
|
+
}), S = {
|
|
784
|
+
resourceServers: [b.resourceServers, ...d?.resourceServers ?? []],
|
|
785
|
+
roles: [b.roles, ...d?.roles ?? []],
|
|
786
|
+
connections: d?.connections ?? [],
|
|
787
|
+
tenants: d?.tenants ?? [],
|
|
788
|
+
rolePermissions: d?.rolePermissions ?? []
|
|
789
|
+
}, C = E({ accessControl: {
|
|
785
790
|
controlPlaneTenantId: r,
|
|
786
|
-
requireOrganizationMatch:
|
|
791
|
+
requireOrganizationMatch: c,
|
|
787
792
|
defaultPermissions: s
|
|
788
|
-
} }),
|
|
793
|
+
} }), w = j({ accessControl: {
|
|
789
794
|
controlPlaneTenantId: r,
|
|
790
|
-
requireOrganizationMatch:
|
|
795
|
+
requireOrganizationMatch: c,
|
|
791
796
|
defaultPermissions: s
|
|
792
797
|
} }, { tenants: {
|
|
793
798
|
async beforeCreate(e, t) {
|
|
794
|
-
return
|
|
799
|
+
return C.beforeCreate && (t = await C.beforeCreate(e, t)), x.beforeCreate && (t = await x.beforeCreate(e, t)), t;
|
|
795
800
|
},
|
|
796
801
|
async afterCreate(e, t) {
|
|
797
|
-
await
|
|
802
|
+
await C.afterCreate?.(e, t), await x.afterCreate?.(e, t);
|
|
798
803
|
},
|
|
799
804
|
async beforeDelete(e, t) {
|
|
800
|
-
await
|
|
805
|
+
await C.beforeDelete?.(e, t), await x.beforeDelete?.(e, t);
|
|
801
806
|
}
|
|
802
|
-
} }), { app:
|
|
807
|
+
} }), { app: T } = f({
|
|
803
808
|
dataAdapter: g,
|
|
804
809
|
managementDataAdapter: _,
|
|
805
810
|
...h,
|
|
806
|
-
entityHooks:
|
|
807
|
-
managementApiExtensions: [...
|
|
811
|
+
entityHooks: S,
|
|
812
|
+
managementApiExtensions: [...l, {
|
|
808
813
|
path: "/tenants",
|
|
809
|
-
router:
|
|
814
|
+
router: w
|
|
810
815
|
}]
|
|
811
816
|
});
|
|
812
|
-
return
|
|
813
|
-
app:
|
|
817
|
+
return T.use("/api/v2/*", H(r)), v && T.use("/api/v2/*", M()), {
|
|
818
|
+
app: T,
|
|
814
819
|
controlPlaneTenantId: r
|
|
815
820
|
};
|
|
816
821
|
}
|
|
817
822
|
//#endregion
|
|
818
823
|
//#region src/rollout/defaults-projection.ts
|
|
819
|
-
function
|
|
824
|
+
function q(e = {}) {
|
|
825
|
+
return {
|
|
826
|
+
connections: e.connections ?? !0,
|
|
827
|
+
resourceServers: e.resourceServers ?? !0,
|
|
828
|
+
hooks: e.hooks ?? !0,
|
|
829
|
+
emailProvider: e.emailProvider ?? !0,
|
|
830
|
+
branding: e.branding ?? !0,
|
|
831
|
+
promptSettings: e.promptSettings ?? !0
|
|
832
|
+
};
|
|
833
|
+
}
|
|
834
|
+
function J() {
|
|
820
835
|
return {
|
|
821
836
|
upserted: 0,
|
|
822
837
|
errors: []
|
|
823
838
|
};
|
|
824
839
|
}
|
|
825
|
-
function
|
|
840
|
+
function he(e) {
|
|
841
|
+
return {
|
|
842
|
+
tenantId: e,
|
|
843
|
+
connections: J(),
|
|
844
|
+
resourceServers: J(),
|
|
845
|
+
hooks: J(),
|
|
846
|
+
emailProvider: J(),
|
|
847
|
+
branding: J(),
|
|
848
|
+
promptSettings: J()
|
|
849
|
+
};
|
|
850
|
+
}
|
|
851
|
+
function ge(e) {
|
|
826
852
|
let t = e.metadata;
|
|
827
853
|
return !!(t && t.inheritable === !0);
|
|
828
854
|
}
|
|
829
|
-
async function
|
|
855
|
+
async function Y(e, t, n, r) {
|
|
830
856
|
try {
|
|
831
857
|
await r();
|
|
832
858
|
} catch (r) {
|
|
@@ -835,90 +861,121 @@ async function X(e, t, n, r) {
|
|
|
835
861
|
e.errors.push(i);
|
|
836
862
|
}
|
|
837
863
|
}
|
|
838
|
-
async function
|
|
839
|
-
|
|
840
|
-
connections:
|
|
841
|
-
resourceServers: o.resourceServers ?? !0,
|
|
842
|
-
hooks: o.hooks ?? !0,
|
|
843
|
-
emailProvider: o.emailProvider ?? !0,
|
|
844
|
-
branding: o.branding ?? !0,
|
|
845
|
-
promptSettings: o.promptSettings ?? !0
|
|
846
|
-
}, f = await r(), p = await a(t), m = {
|
|
847
|
-
tenantId: t,
|
|
848
|
-
connections: Y(),
|
|
849
|
-
resourceServers: Y(),
|
|
850
|
-
hooks: Y(),
|
|
851
|
-
emailProvider: Y(),
|
|
852
|
-
branding: Y(),
|
|
853
|
-
promptSettings: Y()
|
|
854
|
-
};
|
|
855
|
-
if (u.connections) {
|
|
856
|
-
let e = await c((e) => f.connections.list(n, e), "connections", {
|
|
864
|
+
async function _e(e, t, n) {
|
|
865
|
+
return {
|
|
866
|
+
connections: n.connections ? await u((n) => e.connections.list(t, n), "connections", {
|
|
857
867
|
cursorField: "id",
|
|
858
868
|
pageSize: 100
|
|
859
|
-
})
|
|
860
|
-
|
|
861
|
-
let e = t.id;
|
|
862
|
-
e && await X(m.connections, `connection ${e}`, s, async () => {
|
|
863
|
-
let r = i.parse(t);
|
|
864
|
-
await p.connections.get(n, e) ? await p.connections.update(n, e, r) : await p.connections.create(n, r), m.connections.upserted += 1;
|
|
865
|
-
});
|
|
866
|
-
}
|
|
867
|
-
}
|
|
868
|
-
if (u.resourceServers) {
|
|
869
|
-
let e = await c((e) => f.resourceServers.list(n, e), "resource_servers", {
|
|
869
|
+
}) : [],
|
|
870
|
+
resourceServers: n.resourceServers ? await u((n) => e.resourceServers.list(t, n), "resource_servers", {
|
|
870
871
|
cursorField: "id",
|
|
871
872
|
pageSize: 100
|
|
872
|
-
})
|
|
873
|
-
|
|
874
|
-
let e = d.parse(t);
|
|
875
|
-
await p.resourceServers.get(n, t.id) ? await p.resourceServers.update(n, t.id, e) : await p.resourceServers.create(n, e), m.resourceServers.upserted += 1;
|
|
876
|
-
});
|
|
877
|
-
}
|
|
878
|
-
if (u.hooks) {
|
|
879
|
-
let e = await c((e) => f.hooks.list(n, e), "hooks", {
|
|
873
|
+
}) : [],
|
|
874
|
+
hooks: n.hooks ? await u((n) => e.hooks.list(t, n), "hooks", {
|
|
880
875
|
cursorField: "hook_id",
|
|
881
876
|
pageSize: 100
|
|
882
|
-
})
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
877
|
+
}) : [],
|
|
878
|
+
emailProvider: n.emailProvider ? await e.emailProviders.get(t) ?? null : null,
|
|
879
|
+
branding: n.branding ? await e.branding.get(t) ?? null : null,
|
|
880
|
+
promptSettings: n.promptSettings ? await e.promptSettings.get(t) ?? null : null
|
|
881
|
+
};
|
|
882
|
+
}
|
|
883
|
+
async function ve(e, t, n, r, i, o) {
|
|
884
|
+
if (r.connections) for (let r of e.connections) {
|
|
885
|
+
let e = r.id;
|
|
886
|
+
e && await Y(o.connections, `connection ${e}`, i, async () => {
|
|
887
|
+
let i = a.parse(r);
|
|
888
|
+
await t.connections.get(n, e) ? await t.connections.update(n, e, i) : await t.connections.create(n, i), o.connections.upserted += 1;
|
|
886
889
|
});
|
|
887
890
|
}
|
|
888
|
-
|
|
889
|
-
let e =
|
|
890
|
-
|
|
891
|
-
})
|
|
892
|
-
|
|
893
|
-
e
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
891
|
+
if (r.resourceServers) for (let r of e.resourceServers) !r.is_system || !r.id || await Y(o.resourceServers, `resource_server ${r.id}`, i, async () => {
|
|
892
|
+
let e = h.parse(r);
|
|
893
|
+
await t.resourceServers.get(n, r.id) ? await t.resourceServers.update(n, r.id, e) : await t.resourceServers.create(n, e), o.resourceServers.upserted += 1;
|
|
894
|
+
});
|
|
895
|
+
if (r.hooks) for (let r of e.hooks) !ge(r) || !r.hook_id || await Y(o.hooks, `hook ${r.hook_id}`, i, async () => {
|
|
896
|
+
let e = d.parse(r);
|
|
897
|
+
await t.hooks.get(n, r.hook_id) ? await t.hooks.update(n, r.hook_id, e) : await t.hooks.create(n, e), o.hooks.upserted += 1;
|
|
898
|
+
});
|
|
899
|
+
r.emailProvider && e.emailProvider && await Y(o.emailProvider, "email_provider", i, async () => {
|
|
900
|
+
let r = e.emailProvider;
|
|
901
|
+
await t.emailProviders.get(n) ? await t.emailProviders.update(n, r) : await t.emailProviders.create(n, r), o.emailProvider.upserted += 1;
|
|
902
|
+
}), r.branding && e.branding && await Y(o.branding, "branding", i, async () => {
|
|
903
|
+
await t.branding.set(n, e.branding), o.branding.upserted += 1;
|
|
904
|
+
}), r.promptSettings && e.promptSettings && await Y(o.promptSettings, "prompt_settings", i, async () => {
|
|
905
|
+
await t.promptSettings.set(n, e.promptSettings), o.promptSettings.upserted += 1;
|
|
906
|
+
});
|
|
907
|
+
}
|
|
908
|
+
async function X(e, t) {
|
|
909
|
+
let { controlPlaneTenantId: n, getControlPlaneAdapters: r, getAdapters: i, entities: a, continueOnError: o = !1 } = e, s = q(a), c = await _e(await r(), n, s), l = await i(t), u = he(t);
|
|
910
|
+
return await ve(c, l, n, s, o, u), u;
|
|
911
|
+
}
|
|
912
|
+
//#endregion
|
|
913
|
+
//#region src/rollout/payload.ts
|
|
914
|
+
function Z(e) {
|
|
915
|
+
let { pkcs7: t, tenant_id: n, ...r } = e;
|
|
916
|
+
return r;
|
|
917
|
+
}
|
|
918
|
+
async function ye(e, t, n = {}) {
|
|
919
|
+
let r = q(n), i = n.signingKeys ?? !0, a = await _e(e, t, r), o = i ? (await p(e.keys)).map(Z) : [];
|
|
920
|
+
return {
|
|
921
|
+
connections: a.connections,
|
|
922
|
+
resourceServers: a.resourceServers.filter((e) => e.is_system),
|
|
923
|
+
hooks: a.hooks.filter(ge),
|
|
924
|
+
emailProvider: a.emailProvider,
|
|
925
|
+
branding: a.branding,
|
|
926
|
+
promptSettings: a.promptSettings,
|
|
927
|
+
signingKeys: o
|
|
928
|
+
};
|
|
929
|
+
}
|
|
930
|
+
async function be(e, t, n) {
|
|
931
|
+
let r = J();
|
|
932
|
+
if (e.length === 0) return r;
|
|
933
|
+
let i = await p(t.keys), a = new Set(i.map((e) => e.kid));
|
|
934
|
+
for (let i of e) await Y(r, `signing_key ${i.kid}`, n, async () => {
|
|
935
|
+
let e = Z(i);
|
|
936
|
+
a.has(e.kid) || (await t.keys.create(e), a.add(e.kid), r.upserted += 1);
|
|
937
|
+
});
|
|
938
|
+
return r;
|
|
939
|
+
}
|
|
940
|
+
async function xe(e, t, n, r = {}) {
|
|
941
|
+
let a = r.continueOnError ?? !1, o = q(r.entities), s = r.entities?.signingKeys ?? !0, c = {
|
|
942
|
+
connections: e.connections,
|
|
943
|
+
resourceServers: e.resourceServers,
|
|
944
|
+
hooks: e.hooks,
|
|
945
|
+
emailProvider: e.emailProvider ? l.parse(e.emailProvider) : null,
|
|
946
|
+
branding: e.branding ? i.parse(e.branding) : null,
|
|
947
|
+
promptSettings: e.promptSettings ? m.parse(e.promptSettings) : null
|
|
948
|
+
}, u = he(n);
|
|
949
|
+
await ve(c, t, n, o, a, u);
|
|
950
|
+
let d = s ? await be(e.signingKeys, t, a) : J();
|
|
951
|
+
return {
|
|
952
|
+
...u,
|
|
953
|
+
signingKeys: d
|
|
954
|
+
};
|
|
898
955
|
}
|
|
899
956
|
//#endregion
|
|
900
957
|
//#region src/rollout/index.ts
|
|
901
|
-
function
|
|
958
|
+
function Se(e) {
|
|
902
959
|
return {
|
|
903
|
-
syncDefaults: (t) =>
|
|
960
|
+
syncDefaults: (t) => X(e, t),
|
|
904
961
|
syncDefaultsToTenants: async (t) => {
|
|
905
962
|
let n = [];
|
|
906
|
-
for (let r of t) n.push(await
|
|
963
|
+
for (let r of t) n.push(await X(e, r));
|
|
907
964
|
return n;
|
|
908
965
|
}
|
|
909
966
|
};
|
|
910
967
|
}
|
|
911
968
|
//#endregion
|
|
912
969
|
//#region src/plugin.ts
|
|
913
|
-
function
|
|
970
|
+
function Ce(e) {
|
|
914
971
|
let t = Q(e);
|
|
915
972
|
return {
|
|
916
973
|
name: "multi-tenancy",
|
|
917
|
-
middleware:
|
|
974
|
+
middleware: K(e),
|
|
918
975
|
hooks: t,
|
|
919
976
|
routes: [{
|
|
920
977
|
path: "/management",
|
|
921
|
-
handler:
|
|
978
|
+
handler: j(e, t)
|
|
922
979
|
}],
|
|
923
980
|
onRegister: async () => {
|
|
924
981
|
console.log("Multi-tenancy plugin registered"), e.accessControl && console.log(` - Access control enabled (control plane: ${e.accessControl.controlPlaneTenantId})`), e.subdomainRouting && console.log(` - Subdomain routing enabled (base domain: ${e.subdomainRouting.baseDomain})`), e.databaseIsolation && console.log(" - Database isolation enabled");
|
|
@@ -928,7 +985,7 @@ function ce(e) {
|
|
|
928
985
|
//#endregion
|
|
929
986
|
//#region src/index.ts
|
|
930
987
|
function Q(e) {
|
|
931
|
-
let t = e.accessControl ?
|
|
988
|
+
let t = e.accessControl ? S(e.accessControl) : {}, n = e.databaseIsolation ? w(e.databaseIsolation) : {}, r = E(e);
|
|
932
989
|
return {
|
|
933
990
|
...t,
|
|
934
991
|
...n,
|
|
@@ -937,19 +994,19 @@ function Q(e) {
|
|
|
937
994
|
}
|
|
938
995
|
function $(t) {
|
|
939
996
|
let n = new e(), r = Q(t);
|
|
940
|
-
return n.route("/tenants",
|
|
997
|
+
return n.route("/tenants", j(t, r)), n;
|
|
941
998
|
}
|
|
942
|
-
function
|
|
999
|
+
function we(e) {
|
|
943
1000
|
return {
|
|
944
1001
|
hooks: Q(e),
|
|
945
|
-
middleware:
|
|
1002
|
+
middleware: K(e),
|
|
946
1003
|
app: $(e),
|
|
947
1004
|
config: e,
|
|
948
|
-
wrapAdapters: (t, n) =>
|
|
1005
|
+
wrapAdapters: (t, n) => V(t, {
|
|
949
1006
|
controlPlaneTenantId: e.accessControl?.controlPlaneTenantId,
|
|
950
1007
|
controlPlaneClientId: n?.controlPlaneClientId
|
|
951
1008
|
})
|
|
952
1009
|
};
|
|
953
1010
|
}
|
|
954
1011
|
//#endregion
|
|
955
|
-
export {
|
|
1012
|
+
export { xe as applyControlPlaneDefaultsPayload, ye as buildControlPlaneDefaultsPayload, S as createAccessControlHooks, U as createAccessControlMiddleware, H as createControlPlaneTenantMiddleware, w as createDatabaseHooks, G as createDatabaseMiddleware, Se as createDirectRolloutAdapter, $ as createMultiTenancy, Q as createMultiTenancyHooks, K as createMultiTenancyMiddleware, Ce as createMultiTenancyPlugin, M as createProtectSyncedMiddleware, E as createProvisioningHooks, z as createRuntimeFallbackAdapter, W as createSubdomainMiddleware, ie as createSyncHooks, j as createTenantsOpenAPIRouter, me as initMultiTenant, fe as mergeClientWithFallback, X as projectControlPlaneDefaults, we as setupMultiTenancy, C as validateTenantAccess, V as withRuntimeFallback, R as withSystemResourceServerInheritance };
|