@authhero/multi-tenancy 13.6.0 → 13.7.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.d.ts +68 -3
- package/dist/multi-tenancy.mjs +723 -388
- package/package.json +2 -2
package/dist/multi-tenancy.mjs
CHANGED
|
@@ -1,33 +1,34 @@
|
|
|
1
|
-
var
|
|
2
|
-
var
|
|
3
|
-
var
|
|
4
|
-
import { Hono as
|
|
5
|
-
import { MANAGEMENT_API_SCOPES as
|
|
6
|
-
import { MANAGEMENT_API_SCOPES as
|
|
7
|
-
import { z as
|
|
8
|
-
import { auth0QuerySchema as
|
|
9
|
-
|
|
10
|
-
|
|
1
|
+
var U = Object.defineProperty;
|
|
2
|
+
var F = (a, n, s) => n in a ? U(a, n, { enumerable: !0, configurable: !0, writable: !0, value: s }) : a[n] = s;
|
|
3
|
+
var j = (a, n, s) => F(a, typeof n != "symbol" ? n + "" : n, s);
|
|
4
|
+
import { Hono as S } from "hono";
|
|
5
|
+
import { getTenantAudience as P, MANAGEMENT_API_SCOPES as E, init as K } from "authhero";
|
|
6
|
+
import { MANAGEMENT_API_SCOPES as he, seed as ye } from "authhero";
|
|
7
|
+
import { z as N } from "zod";
|
|
8
|
+
import { auth0QuerySchema as R, tenantInsertSchema as I, tenantSchema as q } from "@authhero/adapter-interfaces";
|
|
9
|
+
import { OpenAPIHono as B, createRoute as O, z as b } from "@hono/zod-openapi";
|
|
10
|
+
function V(a) {
|
|
11
|
+
const { mainTenantId: n, requireOrganizationMatch: s = !0 } = a;
|
|
11
12
|
return {
|
|
12
|
-
async onTenantAccessValidation(
|
|
13
|
-
if (
|
|
13
|
+
async onTenantAccessValidation(e, t) {
|
|
14
|
+
if (t === n)
|
|
14
15
|
return !0;
|
|
15
16
|
if (s) {
|
|
16
|
-
const
|
|
17
|
-
return
|
|
17
|
+
const c = e.var.organization_id;
|
|
18
|
+
return c ? c === t : !1;
|
|
18
19
|
}
|
|
19
20
|
return !0;
|
|
20
21
|
}
|
|
21
22
|
};
|
|
22
23
|
}
|
|
23
|
-
function
|
|
24
|
-
return n === s ? !0 :
|
|
24
|
+
function W(a, n, s) {
|
|
25
|
+
return n === s ? !0 : a ? a === n : !1;
|
|
25
26
|
}
|
|
26
|
-
function
|
|
27
|
+
function L(a) {
|
|
27
28
|
return {
|
|
28
29
|
async resolveDataAdapters(n) {
|
|
29
30
|
try {
|
|
30
|
-
return await
|
|
31
|
+
return await a.getAdapters(n);
|
|
31
32
|
} catch (s) {
|
|
32
33
|
console.error(
|
|
33
34
|
`Failed to resolve data adapters for tenant ${n}:`,
|
|
@@ -38,72 +39,78 @@ function K(e) {
|
|
|
38
39
|
}
|
|
39
40
|
};
|
|
40
41
|
}
|
|
41
|
-
function
|
|
42
|
+
function Q(a) {
|
|
42
43
|
return {
|
|
44
|
+
async beforeCreate(n, s) {
|
|
45
|
+
return !s.audience && s.id ? {
|
|
46
|
+
...s,
|
|
47
|
+
audience: P(s.id)
|
|
48
|
+
} : s;
|
|
49
|
+
},
|
|
43
50
|
async afterCreate(n, s) {
|
|
44
|
-
const { accessControl:
|
|
45
|
-
|
|
51
|
+
const { accessControl: e, databaseIsolation: t, settingsInheritance: c } = a;
|
|
52
|
+
e && n.ctx && await G(n, s, e), t != null && t.onProvision && await t.onProvision(s.id), (c == null ? void 0 : c.inheritFromMain) !== !1 && n.ctx && await Z(n, s, a);
|
|
46
53
|
},
|
|
47
54
|
async beforeDelete(n, s) {
|
|
48
|
-
const { accessControl:
|
|
49
|
-
if (
|
|
55
|
+
const { accessControl: e, databaseIsolation: t } = a;
|
|
56
|
+
if (e)
|
|
50
57
|
try {
|
|
51
|
-
const
|
|
52
|
-
|
|
58
|
+
const o = (await n.adapters.organizations.list(
|
|
59
|
+
e.mainTenantId
|
|
53
60
|
)).organizations.find((i) => i.name === s);
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
61
|
+
o && await n.adapters.organizations.remove(
|
|
62
|
+
e.mainTenantId,
|
|
63
|
+
o.id
|
|
57
64
|
);
|
|
58
|
-
} catch (
|
|
65
|
+
} catch (c) {
|
|
59
66
|
console.warn(
|
|
60
67
|
`Failed to remove organization for tenant ${s}:`,
|
|
61
|
-
|
|
68
|
+
c
|
|
62
69
|
);
|
|
63
70
|
}
|
|
64
|
-
if (
|
|
71
|
+
if (t != null && t.onDeprovision)
|
|
65
72
|
try {
|
|
66
|
-
await
|
|
67
|
-
} catch (
|
|
73
|
+
await t.onDeprovision(s);
|
|
74
|
+
} catch (c) {
|
|
68
75
|
console.warn(
|
|
69
76
|
`Failed to deprovision database for tenant ${s}:`,
|
|
70
|
-
|
|
77
|
+
c
|
|
71
78
|
);
|
|
72
79
|
}
|
|
73
80
|
}
|
|
74
81
|
};
|
|
75
82
|
}
|
|
76
|
-
async function
|
|
83
|
+
async function G(a, n, s) {
|
|
77
84
|
const {
|
|
78
|
-
mainTenantId:
|
|
79
|
-
defaultPermissions:
|
|
80
|
-
defaultRoles:
|
|
81
|
-
issuer:
|
|
85
|
+
mainTenantId: e,
|
|
86
|
+
defaultPermissions: t,
|
|
87
|
+
defaultRoles: c,
|
|
88
|
+
issuer: o,
|
|
82
89
|
adminRoleName: i = "Tenant Admin",
|
|
83
|
-
adminRoleDescription:
|
|
90
|
+
adminRoleDescription: d = "Full access to all tenant management operations",
|
|
84
91
|
addCreatorToOrganization: r = !0
|
|
85
92
|
} = s;
|
|
86
|
-
await
|
|
93
|
+
await a.adapters.organizations.create(e, {
|
|
87
94
|
id: n.id,
|
|
88
95
|
name: n.id,
|
|
89
96
|
display_name: n.friendly_name || n.id
|
|
90
97
|
});
|
|
91
98
|
let l = null;
|
|
92
|
-
if (
|
|
99
|
+
if (o && (l = await Y(
|
|
100
|
+
a,
|
|
93
101
|
e,
|
|
94
|
-
|
|
95
|
-
d,
|
|
102
|
+
o,
|
|
96
103
|
i,
|
|
97
|
-
|
|
98
|
-
)), r &&
|
|
99
|
-
const f =
|
|
104
|
+
d
|
|
105
|
+
)), r && a.ctx) {
|
|
106
|
+
const f = a.ctx.var.user;
|
|
100
107
|
if (f != null && f.sub)
|
|
101
108
|
try {
|
|
102
|
-
await
|
|
109
|
+
await a.adapters.userOrganizations.create(e, {
|
|
103
110
|
user_id: f.sub,
|
|
104
111
|
organization_id: n.id
|
|
105
|
-
}), l && await
|
|
106
|
-
|
|
112
|
+
}), l && await a.adapters.userRoles.create(
|
|
113
|
+
e,
|
|
107
114
|
f.sub,
|
|
108
115
|
l,
|
|
109
116
|
n.id
|
|
@@ -116,34 +123,34 @@ async function W(e, n, s) {
|
|
|
116
123
|
);
|
|
117
124
|
}
|
|
118
125
|
}
|
|
119
|
-
|
|
120
|
-
`Would assign roles ${
|
|
121
|
-
),
|
|
122
|
-
`Would grant permissions ${
|
|
126
|
+
c && c.length > 0 && console.log(
|
|
127
|
+
`Would assign roles ${c.join(", ")} to organization ${n.id}`
|
|
128
|
+
), t && t.length > 0 && console.log(
|
|
129
|
+
`Would grant permissions ${t.join(", ")} to organization ${n.id}`
|
|
123
130
|
);
|
|
124
131
|
}
|
|
125
|
-
async function
|
|
126
|
-
const
|
|
127
|
-
if (
|
|
128
|
-
return
|
|
129
|
-
const i = await
|
|
130
|
-
name:
|
|
131
|
-
description:
|
|
132
|
-
}),
|
|
132
|
+
async function Y(a, n, s, e, t) {
|
|
133
|
+
const o = (await a.adapters.roles.list(n, {})).roles.find((l) => l.name === e);
|
|
134
|
+
if (o)
|
|
135
|
+
return o.id;
|
|
136
|
+
const i = await a.adapters.roles.create(n, {
|
|
137
|
+
name: e,
|
|
138
|
+
description: t
|
|
139
|
+
}), d = `${s}api/v2/`, r = E.map((l) => ({
|
|
133
140
|
role_id: i.id,
|
|
134
|
-
resource_server_identifier:
|
|
141
|
+
resource_server_identifier: d,
|
|
135
142
|
permission_name: l.value
|
|
136
143
|
}));
|
|
137
|
-
return await
|
|
144
|
+
return await a.adapters.rolePermissions.assign(n, i.id, r), i.id;
|
|
138
145
|
}
|
|
139
|
-
async function
|
|
140
|
-
const { accessControl:
|
|
141
|
-
if (!
|
|
146
|
+
async function Z(a, n, s) {
|
|
147
|
+
const { accessControl: e, settingsInheritance: t } = s;
|
|
148
|
+
if (!e)
|
|
142
149
|
return;
|
|
143
|
-
const
|
|
144
|
-
if (!
|
|
150
|
+
const c = await a.adapters.tenants.get(e.mainTenantId);
|
|
151
|
+
if (!c)
|
|
145
152
|
return;
|
|
146
|
-
let
|
|
153
|
+
let o = { ...c };
|
|
147
154
|
const i = [
|
|
148
155
|
"id",
|
|
149
156
|
"created_at",
|
|
@@ -154,72 +161,72 @@ async function Q(e, n, s) {
|
|
|
154
161
|
"sender_email",
|
|
155
162
|
"sender_name"
|
|
156
163
|
];
|
|
157
|
-
for (const
|
|
158
|
-
delete d
|
|
159
|
-
if (
|
|
160
|
-
const
|
|
161
|
-
for (const r of
|
|
162
|
-
r in
|
|
163
|
-
|
|
164
|
+
for (const d of i)
|
|
165
|
+
delete o[d];
|
|
166
|
+
if (t != null && t.inheritedKeys) {
|
|
167
|
+
const d = {};
|
|
168
|
+
for (const r of t.inheritedKeys)
|
|
169
|
+
r in c && !i.includes(r) && (d[r] = c[r]);
|
|
170
|
+
o = d;
|
|
164
171
|
}
|
|
165
|
-
if (
|
|
166
|
-
for (const
|
|
167
|
-
delete d
|
|
168
|
-
|
|
169
|
-
|
|
172
|
+
if (t != null && t.excludedKeys)
|
|
173
|
+
for (const d of t.excludedKeys)
|
|
174
|
+
delete o[d];
|
|
175
|
+
t != null && t.transformSettings && (o = t.transformSettings(
|
|
176
|
+
o,
|
|
170
177
|
n.id
|
|
171
|
-
)), Object.keys(
|
|
178
|
+
)), Object.keys(o).length > 0 && await a.adapters.tenants.update(n.id, o);
|
|
172
179
|
}
|
|
173
|
-
async function
|
|
180
|
+
async function z(a, n, s = {}) {
|
|
174
181
|
const {
|
|
175
|
-
cursorField:
|
|
176
|
-
sortOrder:
|
|
177
|
-
pageSize:
|
|
178
|
-
maxItems:
|
|
182
|
+
cursorField: e = "id",
|
|
183
|
+
sortOrder: t = "asc",
|
|
184
|
+
pageSize: c = 100,
|
|
185
|
+
maxItems: o = 1e4,
|
|
179
186
|
q: i
|
|
180
|
-
} = s,
|
|
187
|
+
} = s, d = [];
|
|
181
188
|
let r, l = !0;
|
|
182
189
|
for (; l; ) {
|
|
183
190
|
let f = i || "";
|
|
184
191
|
if (r) {
|
|
185
|
-
const w = `${
|
|
192
|
+
const w = `${e}:${t === "asc" ? ">" : "<"}${r}`;
|
|
186
193
|
f = f ? `(${f}) AND ${w}` : w;
|
|
187
194
|
}
|
|
188
195
|
const u = {
|
|
189
|
-
per_page:
|
|
196
|
+
per_page: c,
|
|
190
197
|
page: 0,
|
|
191
198
|
// Always use page 0 since we're doing cursor-based pagination
|
|
192
199
|
sort: {
|
|
193
|
-
sort_by:
|
|
194
|
-
sort_order:
|
|
200
|
+
sort_by: e,
|
|
201
|
+
sort_order: t
|
|
195
202
|
},
|
|
196
203
|
...f && { q: f }
|
|
197
|
-
},
|
|
198
|
-
if (
|
|
204
|
+
}, v = (await a(u))[n] || [];
|
|
205
|
+
if (v.length === 0)
|
|
199
206
|
l = !1;
|
|
200
207
|
else {
|
|
201
|
-
|
|
202
|
-
const
|
|
203
|
-
if (
|
|
204
|
-
const w =
|
|
208
|
+
d.push(...v);
|
|
209
|
+
const h = v[v.length - 1];
|
|
210
|
+
if (h && typeof h == "object") {
|
|
211
|
+
const w = h[e];
|
|
205
212
|
w != null && (r = String(w));
|
|
206
213
|
}
|
|
207
|
-
|
|
208
|
-
`fetchAll: Reached maxItems limit (${
|
|
214
|
+
v.length < c && (l = !1), o !== -1 && d.length >= o && (console.warn(
|
|
215
|
+
`fetchAll: Reached maxItems limit (${o}). There may be more items.`
|
|
209
216
|
), l = !1);
|
|
210
217
|
}
|
|
211
218
|
}
|
|
212
|
-
return
|
|
219
|
+
return d;
|
|
213
220
|
}
|
|
214
|
-
function
|
|
221
|
+
function H(a) {
|
|
215
222
|
const {
|
|
216
223
|
mainTenantId: n,
|
|
217
224
|
getChildTenantIds: s,
|
|
218
|
-
getAdapters:
|
|
219
|
-
shouldSync:
|
|
220
|
-
transformForSync:
|
|
221
|
-
} =
|
|
222
|
-
async function
|
|
225
|
+
getAdapters: e,
|
|
226
|
+
shouldSync: t = () => !0,
|
|
227
|
+
transformForSync: c
|
|
228
|
+
} = a;
|
|
229
|
+
async function o(r, l, f) {
|
|
223
230
|
return (await r.resourceServers.list(l, {
|
|
224
231
|
q: `identifier:${f}`,
|
|
225
232
|
per_page: 1
|
|
@@ -230,7 +237,7 @@ function V(e) {
|
|
|
230
237
|
await Promise.all(
|
|
231
238
|
f.map(async (u) => {
|
|
232
239
|
try {
|
|
233
|
-
const m = await
|
|
240
|
+
const m = await e(u), h = { ...c ? c(r, u) : {
|
|
234
241
|
name: r.name,
|
|
235
242
|
identifier: r.identifier,
|
|
236
243
|
scopes: r.scopes,
|
|
@@ -244,7 +251,7 @@ function V(e) {
|
|
|
244
251
|
options: r.options
|
|
245
252
|
}, is_system: !0 };
|
|
246
253
|
if (l === "create") {
|
|
247
|
-
const w = await
|
|
254
|
+
const w = await o(
|
|
248
255
|
m,
|
|
249
256
|
u,
|
|
250
257
|
r.identifier
|
|
@@ -252,10 +259,10 @@ function V(e) {
|
|
|
252
259
|
w && w.id ? await m.resourceServers.update(
|
|
253
260
|
u,
|
|
254
261
|
w.id,
|
|
255
|
-
|
|
256
|
-
) : await m.resourceServers.create(u,
|
|
262
|
+
h
|
|
263
|
+
) : await m.resourceServers.create(u, h);
|
|
257
264
|
} else {
|
|
258
|
-
const w = await
|
|
265
|
+
const w = await o(
|
|
259
266
|
m,
|
|
260
267
|
u,
|
|
261
268
|
r.identifier
|
|
@@ -263,7 +270,7 @@ function V(e) {
|
|
|
263
270
|
w && w.id && await m.resourceServers.update(
|
|
264
271
|
u,
|
|
265
272
|
w.id,
|
|
266
|
-
|
|
273
|
+
h
|
|
267
274
|
);
|
|
268
275
|
}
|
|
269
276
|
} catch (m) {
|
|
@@ -275,12 +282,12 @@ function V(e) {
|
|
|
275
282
|
})
|
|
276
283
|
);
|
|
277
284
|
}
|
|
278
|
-
async function
|
|
285
|
+
async function d(r) {
|
|
279
286
|
const l = await s();
|
|
280
287
|
await Promise.all(
|
|
281
288
|
l.map(async (f) => {
|
|
282
289
|
try {
|
|
283
|
-
const u = await
|
|
290
|
+
const u = await e(f), m = await o(
|
|
284
291
|
u,
|
|
285
292
|
f,
|
|
286
293
|
r
|
|
@@ -297,38 +304,38 @@ function V(e) {
|
|
|
297
304
|
}
|
|
298
305
|
return {
|
|
299
306
|
afterCreate: async (r, l) => {
|
|
300
|
-
r.tenantId === n &&
|
|
307
|
+
r.tenantId === n && t(l) && await i(l, "create");
|
|
301
308
|
},
|
|
302
309
|
afterUpdate: async (r, l, f) => {
|
|
303
|
-
r.tenantId === n &&
|
|
310
|
+
r.tenantId === n && t(f) && await i(f, "update");
|
|
304
311
|
},
|
|
305
312
|
afterDelete: async (r, l) => {
|
|
306
|
-
r.tenantId === n && await
|
|
313
|
+
r.tenantId === n && await d(l);
|
|
307
314
|
}
|
|
308
315
|
};
|
|
309
316
|
}
|
|
310
|
-
function
|
|
317
|
+
function J(a) {
|
|
311
318
|
const {
|
|
312
319
|
mainTenantId: n,
|
|
313
320
|
getMainTenantAdapters: s,
|
|
314
|
-
getAdapters:
|
|
315
|
-
shouldSync:
|
|
316
|
-
transformForSync:
|
|
317
|
-
} =
|
|
321
|
+
getAdapters: e,
|
|
322
|
+
shouldSync: t = () => !0,
|
|
323
|
+
transformForSync: c
|
|
324
|
+
} = a;
|
|
318
325
|
return {
|
|
319
|
-
async afterCreate(
|
|
326
|
+
async afterCreate(o, i) {
|
|
320
327
|
if (i.id !== n)
|
|
321
328
|
try {
|
|
322
|
-
const
|
|
323
|
-
(f) =>
|
|
329
|
+
const d = await s(), r = await e(i.id), l = await z(
|
|
330
|
+
(f) => d.resourceServers.list(n, f),
|
|
324
331
|
"resource_servers",
|
|
325
332
|
{ cursorField: "id", pageSize: 100 }
|
|
326
333
|
);
|
|
327
334
|
await Promise.all(
|
|
328
|
-
l.filter((f) =>
|
|
335
|
+
l.filter((f) => t(f)).map(async (f) => {
|
|
329
336
|
const u = f;
|
|
330
337
|
try {
|
|
331
|
-
const m =
|
|
338
|
+
const m = c ? c(u, i.id) : {
|
|
332
339
|
name: u.name,
|
|
333
340
|
identifier: u.identifier,
|
|
334
341
|
scopes: u.scopes,
|
|
@@ -353,10 +360,10 @@ function G(e) {
|
|
|
353
360
|
}
|
|
354
361
|
})
|
|
355
362
|
);
|
|
356
|
-
} catch (
|
|
363
|
+
} catch (d) {
|
|
357
364
|
console.error(
|
|
358
365
|
`Failed to sync resource servers to new tenant "${i.id}":`,
|
|
359
|
-
|
|
366
|
+
d
|
|
360
367
|
);
|
|
361
368
|
}
|
|
362
369
|
}
|
|
@@ -370,8 +377,8 @@ var p = class extends Error {
|
|
|
370
377
|
*/
|
|
371
378
|
constructor(n = 500, s) {
|
|
372
379
|
super(s == null ? void 0 : s.message, { cause: s == null ? void 0 : s.cause });
|
|
373
|
-
|
|
374
|
-
|
|
380
|
+
j(this, "res");
|
|
381
|
+
j(this, "status");
|
|
375
382
|
this.res = s == null ? void 0 : s.res, this.status = n;
|
|
376
383
|
}
|
|
377
384
|
/**
|
|
@@ -388,162 +395,486 @@ var p = class extends Error {
|
|
|
388
395
|
});
|
|
389
396
|
}
|
|
390
397
|
};
|
|
391
|
-
function
|
|
392
|
-
const s = new
|
|
393
|
-
return s.get("/", async (
|
|
398
|
+
function D(a, n) {
|
|
399
|
+
const s = new S();
|
|
400
|
+
return s.get("/", async (e) => {
|
|
394
401
|
var f, u;
|
|
395
|
-
const
|
|
396
|
-
if (
|
|
397
|
-
const m =
|
|
402
|
+
const t = R.parse(e.req.query()), { page: c, per_page: o, include_totals: i, q: d } = t, r = e.var.user;
|
|
403
|
+
if (a.accessControl && (r != null && r.sub)) {
|
|
404
|
+
const m = a.accessControl.mainTenantId, h = (await e.env.data.userOrganizations.listUserOrganizations(
|
|
398
405
|
m,
|
|
399
406
|
r.sub,
|
|
400
407
|
{}
|
|
401
|
-
)).organizations.map((
|
|
402
|
-
|
|
403
|
-
const w = await
|
|
404
|
-
page:
|
|
405
|
-
per_page:
|
|
408
|
+
)).organizations.map((g) => g.id);
|
|
409
|
+
h.includes(m) || h.push(m);
|
|
410
|
+
const w = await e.env.data.tenants.list({
|
|
411
|
+
page: c,
|
|
412
|
+
per_page: o,
|
|
406
413
|
include_totals: i,
|
|
407
|
-
q:
|
|
408
|
-
}),
|
|
409
|
-
(
|
|
414
|
+
q: d
|
|
415
|
+
}), T = w.tenants.filter(
|
|
416
|
+
(g) => h.includes(g.id)
|
|
410
417
|
);
|
|
411
|
-
return i ?
|
|
412
|
-
tenants:
|
|
418
|
+
return i ? e.json({
|
|
419
|
+
tenants: T,
|
|
413
420
|
start: ((f = w.totals) == null ? void 0 : f.start) ?? 0,
|
|
414
|
-
limit: ((u = w.totals) == null ? void 0 : u.limit) ??
|
|
415
|
-
length:
|
|
416
|
-
}) :
|
|
421
|
+
limit: ((u = w.totals) == null ? void 0 : u.limit) ?? o,
|
|
422
|
+
length: T.length
|
|
423
|
+
}) : e.json(T);
|
|
417
424
|
}
|
|
418
|
-
const l = await
|
|
419
|
-
page:
|
|
420
|
-
per_page:
|
|
425
|
+
const l = await e.env.data.tenants.list({
|
|
426
|
+
page: c,
|
|
427
|
+
per_page: o,
|
|
421
428
|
include_totals: i,
|
|
422
|
-
q:
|
|
429
|
+
q: d
|
|
423
430
|
});
|
|
424
|
-
return i ?
|
|
425
|
-
}), s.get("/:id", async (
|
|
426
|
-
const
|
|
427
|
-
if (
|
|
428
|
-
const
|
|
429
|
-
if (
|
|
430
|
-
if (!(
|
|
431
|
+
return i ? e.json(l) : e.json(l.tenants);
|
|
432
|
+
}), s.get("/:id", async (e) => {
|
|
433
|
+
const t = e.req.param("id");
|
|
434
|
+
if (a.accessControl) {
|
|
435
|
+
const o = e.var.user, i = a.accessControl.mainTenantId;
|
|
436
|
+
if (t !== i) {
|
|
437
|
+
if (!(o != null && o.sub))
|
|
431
438
|
throw new p(401, {
|
|
432
439
|
message: "Authentication required"
|
|
433
440
|
});
|
|
434
|
-
if (!(await
|
|
441
|
+
if (!(await e.env.data.userOrganizations.listUserOrganizations(
|
|
435
442
|
i,
|
|
436
|
-
|
|
443
|
+
o.sub,
|
|
437
444
|
{}
|
|
438
|
-
)).organizations.some((l) => l.id ===
|
|
445
|
+
)).organizations.some((l) => l.id === t))
|
|
439
446
|
throw new p(403, {
|
|
440
447
|
message: "Access denied to this tenant"
|
|
441
448
|
});
|
|
442
449
|
}
|
|
443
450
|
}
|
|
444
|
-
const
|
|
445
|
-
if (!
|
|
451
|
+
const c = await e.env.data.tenants.get(t);
|
|
452
|
+
if (!c)
|
|
446
453
|
throw new p(404, {
|
|
447
454
|
message: "Tenant not found"
|
|
448
455
|
});
|
|
449
|
-
return
|
|
450
|
-
}), s.post("/", async (
|
|
451
|
-
var
|
|
456
|
+
return e.json(c);
|
|
457
|
+
}), s.post("/", async (e) => {
|
|
458
|
+
var t, c, o;
|
|
452
459
|
try {
|
|
453
|
-
const i =
|
|
460
|
+
const i = e.var.user;
|
|
454
461
|
if (!(i != null && i.sub))
|
|
455
462
|
throw new p(401, {
|
|
456
463
|
message: "Authentication required to create tenants"
|
|
457
464
|
});
|
|
458
|
-
let
|
|
459
|
-
await
|
|
465
|
+
let d = I.parse(
|
|
466
|
+
await e.req.json()
|
|
460
467
|
);
|
|
461
468
|
const r = {
|
|
462
|
-
adapters:
|
|
463
|
-
ctx:
|
|
469
|
+
adapters: e.env.data,
|
|
470
|
+
ctx: e
|
|
464
471
|
};
|
|
465
|
-
(
|
|
466
|
-
const l = await
|
|
467
|
-
return (
|
|
472
|
+
(t = n.tenants) != null && t.beforeCreate && (d = await n.tenants.beforeCreate(r, d));
|
|
473
|
+
const l = await e.env.data.tenants.create(d);
|
|
474
|
+
return (c = n.tenants) != null && c.afterCreate && await n.tenants.afterCreate(r, l), e.json(l, 201);
|
|
468
475
|
} catch (i) {
|
|
469
|
-
throw i instanceof
|
|
476
|
+
throw i instanceof N.ZodError ? new p(400, {
|
|
470
477
|
message: "Validation error",
|
|
471
478
|
cause: i
|
|
472
|
-
}) : i instanceof Error && ("code" in i && i.code === "SQLITE_CONSTRAINT_PRIMARYKEY" || (
|
|
479
|
+
}) : i instanceof Error && ("code" in i && i.code === "SQLITE_CONSTRAINT_PRIMARYKEY" || (o = i.message) != null && o.includes("UNIQUE constraint failed")) ? new p(409, {
|
|
473
480
|
message: "Tenant with this ID already exists"
|
|
474
481
|
}) : i;
|
|
475
482
|
}
|
|
476
|
-
}), s.patch("/:id", async (
|
|
483
|
+
}), s.patch("/:id", async (e) => {
|
|
477
484
|
var u, m;
|
|
478
|
-
const
|
|
479
|
-
if (
|
|
480
|
-
const
|
|
481
|
-
if (!(
|
|
485
|
+
const t = e.req.param("id");
|
|
486
|
+
if (a.accessControl) {
|
|
487
|
+
const v = e.var.user;
|
|
488
|
+
if (!(v != null && v.sub))
|
|
482
489
|
throw new p(401, {
|
|
483
490
|
message: "Authentication required to update tenants"
|
|
484
491
|
});
|
|
485
|
-
const
|
|
486
|
-
if (
|
|
487
|
-
|
|
488
|
-
|
|
492
|
+
const h = a.accessControl.mainTenantId;
|
|
493
|
+
if (t !== h && !(await e.env.data.userOrganizations.listUserOrganizations(
|
|
494
|
+
h,
|
|
495
|
+
v.sub,
|
|
489
496
|
{}
|
|
490
|
-
)).organizations.some((
|
|
497
|
+
)).organizations.some((g) => g.id === t))
|
|
491
498
|
throw new p(403, {
|
|
492
499
|
message: "Access denied to update this tenant"
|
|
493
500
|
});
|
|
494
501
|
}
|
|
495
|
-
const
|
|
496
|
-
if (!await
|
|
502
|
+
const c = I.partial().parse(await e.req.json()), { id: o, ...i } = c;
|
|
503
|
+
if (!await e.env.data.tenants.get(t))
|
|
497
504
|
throw new p(404, {
|
|
498
505
|
message: "Tenant not found"
|
|
499
506
|
});
|
|
500
507
|
const r = {
|
|
501
|
-
adapters:
|
|
502
|
-
ctx:
|
|
508
|
+
adapters: e.env.data,
|
|
509
|
+
ctx: e
|
|
503
510
|
};
|
|
504
511
|
let l = i;
|
|
505
|
-
(u = n.tenants) != null && u.beforeUpdate && (l = await n.tenants.beforeUpdate(r,
|
|
506
|
-
const f = await
|
|
512
|
+
(u = n.tenants) != null && u.beforeUpdate && (l = await n.tenants.beforeUpdate(r, t, i)), await e.env.data.tenants.update(t, l);
|
|
513
|
+
const f = await e.env.data.tenants.get(t);
|
|
507
514
|
if (!f)
|
|
508
515
|
throw new p(404, {
|
|
509
516
|
message: "Tenant not found after update"
|
|
510
517
|
});
|
|
511
|
-
return (m = n.tenants) != null && m.afterUpdate && await n.tenants.afterUpdate(r, f),
|
|
512
|
-
}), s.delete("/:id", async (
|
|
513
|
-
var i,
|
|
514
|
-
const
|
|
515
|
-
if (
|
|
518
|
+
return (m = n.tenants) != null && m.afterUpdate && await n.tenants.afterUpdate(r, f), e.json(f);
|
|
519
|
+
}), s.delete("/:id", async (e) => {
|
|
520
|
+
var i, d;
|
|
521
|
+
const t = e.req.param("id");
|
|
522
|
+
if (a.accessControl && t === a.accessControl.mainTenantId)
|
|
516
523
|
throw new p(400, {
|
|
517
524
|
message: "Cannot delete the main tenant"
|
|
518
525
|
});
|
|
519
|
-
if (
|
|
520
|
-
const r =
|
|
526
|
+
if (a.accessControl) {
|
|
527
|
+
const r = e.var.user;
|
|
521
528
|
if (!(r != null && r.sub))
|
|
522
529
|
throw new p(401, {
|
|
523
530
|
message: "Authentication required to delete tenants"
|
|
524
531
|
});
|
|
525
|
-
const l =
|
|
526
|
-
if (!(await
|
|
532
|
+
const l = a.accessControl.mainTenantId;
|
|
533
|
+
if (!(await e.env.data.userOrganizations.listUserOrganizations(
|
|
527
534
|
l,
|
|
528
535
|
r.sub,
|
|
529
536
|
{}
|
|
530
|
-
)).organizations.some((m) => m.id ===
|
|
537
|
+
)).organizations.some((m) => m.id === t))
|
|
531
538
|
throw new p(403, {
|
|
532
539
|
message: "Access denied to delete this tenant"
|
|
533
540
|
});
|
|
534
541
|
}
|
|
535
|
-
if (!await
|
|
542
|
+
if (!await e.env.data.tenants.get(t))
|
|
536
543
|
throw new p(404, {
|
|
537
544
|
message: "Tenant not found"
|
|
538
545
|
});
|
|
539
|
-
const
|
|
540
|
-
adapters:
|
|
541
|
-
ctx:
|
|
546
|
+
const o = {
|
|
547
|
+
adapters: e.env.data,
|
|
548
|
+
ctx: e
|
|
542
549
|
};
|
|
543
|
-
return (i = n.tenants) != null && i.beforeDelete && await n.tenants.beforeDelete(
|
|
550
|
+
return (i = n.tenants) != null && i.beforeDelete && await n.tenants.beforeDelete(o, t), await e.env.data.tenants.remove(t), (d = n.tenants) != null && d.afterDelete && await n.tenants.afterDelete(o, t), e.body(null, 204);
|
|
544
551
|
}), s;
|
|
545
552
|
}
|
|
546
|
-
function
|
|
553
|
+
function X(a, n) {
|
|
554
|
+
const s = new B();
|
|
555
|
+
return s.openapi(
|
|
556
|
+
O({
|
|
557
|
+
tags: ["tenants"],
|
|
558
|
+
method: "get",
|
|
559
|
+
path: "/",
|
|
560
|
+
request: {
|
|
561
|
+
query: R
|
|
562
|
+
},
|
|
563
|
+
security: [
|
|
564
|
+
{
|
|
565
|
+
Bearer: ["auth:read"]
|
|
566
|
+
}
|
|
567
|
+
],
|
|
568
|
+
responses: {
|
|
569
|
+
200: {
|
|
570
|
+
content: {
|
|
571
|
+
"application/json": {
|
|
572
|
+
schema: b.object({
|
|
573
|
+
tenants: b.array(q),
|
|
574
|
+
start: b.number().optional(),
|
|
575
|
+
limit: b.number().optional(),
|
|
576
|
+
length: b.number().optional()
|
|
577
|
+
})
|
|
578
|
+
}
|
|
579
|
+
},
|
|
580
|
+
description: "List of tenants"
|
|
581
|
+
}
|
|
582
|
+
}
|
|
583
|
+
}),
|
|
584
|
+
async (e) => {
|
|
585
|
+
var f, u, m, v;
|
|
586
|
+
const t = e.req.valid("query"), { page: c, per_page: o, include_totals: i, q: d } = t, r = e.var.user;
|
|
587
|
+
if (a.accessControl && (r != null && r.sub)) {
|
|
588
|
+
const h = a.accessControl.mainTenantId, T = (await z(
|
|
589
|
+
(_) => e.env.data.userOrganizations.listUserOrganizations(
|
|
590
|
+
h,
|
|
591
|
+
r.sub,
|
|
592
|
+
_
|
|
593
|
+
),
|
|
594
|
+
"organizations"
|
|
595
|
+
)).map((_) => _.id);
|
|
596
|
+
T.includes(h) || T.push(h);
|
|
597
|
+
const g = await e.env.data.tenants.list({
|
|
598
|
+
page: c,
|
|
599
|
+
per_page: o,
|
|
600
|
+
include_totals: i,
|
|
601
|
+
q: d
|
|
602
|
+
}), y = g.tenants.filter(
|
|
603
|
+
(_) => T.includes(_.id)
|
|
604
|
+
);
|
|
605
|
+
return i ? e.json({
|
|
606
|
+
tenants: y,
|
|
607
|
+
start: ((f = g.totals) == null ? void 0 : f.start) ?? 0,
|
|
608
|
+
limit: ((u = g.totals) == null ? void 0 : u.limit) ?? o,
|
|
609
|
+
length: y.length
|
|
610
|
+
}) : e.json({ tenants: y });
|
|
611
|
+
}
|
|
612
|
+
const l = await e.env.data.tenants.list({
|
|
613
|
+
page: c,
|
|
614
|
+
per_page: o,
|
|
615
|
+
include_totals: i,
|
|
616
|
+
q: d
|
|
617
|
+
});
|
|
618
|
+
return i ? e.json({
|
|
619
|
+
tenants: l.tenants,
|
|
620
|
+
start: ((m = l.totals) == null ? void 0 : m.start) ?? 0,
|
|
621
|
+
limit: ((v = l.totals) == null ? void 0 : v.limit) ?? o,
|
|
622
|
+
length: l.tenants.length
|
|
623
|
+
}) : e.json({ tenants: l.tenants });
|
|
624
|
+
}
|
|
625
|
+
), s.openapi(
|
|
626
|
+
O({
|
|
627
|
+
tags: ["tenants"],
|
|
628
|
+
method: "get",
|
|
629
|
+
path: "/{id}",
|
|
630
|
+
request: {
|
|
631
|
+
params: b.object({
|
|
632
|
+
id: b.string()
|
|
633
|
+
})
|
|
634
|
+
},
|
|
635
|
+
security: [
|
|
636
|
+
{
|
|
637
|
+
Bearer: ["auth:read"]
|
|
638
|
+
}
|
|
639
|
+
],
|
|
640
|
+
responses: {
|
|
641
|
+
200: {
|
|
642
|
+
content: {
|
|
643
|
+
"application/json": {
|
|
644
|
+
schema: q
|
|
645
|
+
}
|
|
646
|
+
},
|
|
647
|
+
description: "Tenant details"
|
|
648
|
+
},
|
|
649
|
+
404: {
|
|
650
|
+
description: "Tenant not found"
|
|
651
|
+
}
|
|
652
|
+
}
|
|
653
|
+
}),
|
|
654
|
+
async (e) => {
|
|
655
|
+
const { id: t } = e.req.valid("param");
|
|
656
|
+
if (a.accessControl) {
|
|
657
|
+
const o = e.var.user, i = a.accessControl.mainTenantId;
|
|
658
|
+
if (t !== i) {
|
|
659
|
+
if (!(o != null && o.sub))
|
|
660
|
+
throw new p(401, {
|
|
661
|
+
message: "Authentication required"
|
|
662
|
+
});
|
|
663
|
+
if (!(await z(
|
|
664
|
+
(l) => e.env.data.userOrganizations.listUserOrganizations(
|
|
665
|
+
i,
|
|
666
|
+
o.sub,
|
|
667
|
+
l
|
|
668
|
+
),
|
|
669
|
+
"organizations"
|
|
670
|
+
)).some((l) => l.id === t))
|
|
671
|
+
throw new p(403, {
|
|
672
|
+
message: "Access denied to this tenant"
|
|
673
|
+
});
|
|
674
|
+
}
|
|
675
|
+
}
|
|
676
|
+
const c = await e.env.data.tenants.get(t);
|
|
677
|
+
if (!c)
|
|
678
|
+
throw new p(404, {
|
|
679
|
+
message: "Tenant not found"
|
|
680
|
+
});
|
|
681
|
+
return e.json(c);
|
|
682
|
+
}
|
|
683
|
+
), s.openapi(
|
|
684
|
+
O({
|
|
685
|
+
tags: ["tenants"],
|
|
686
|
+
method: "post",
|
|
687
|
+
path: "/",
|
|
688
|
+
request: {
|
|
689
|
+
body: {
|
|
690
|
+
content: {
|
|
691
|
+
"application/json": {
|
|
692
|
+
schema: I
|
|
693
|
+
}
|
|
694
|
+
}
|
|
695
|
+
}
|
|
696
|
+
},
|
|
697
|
+
security: [
|
|
698
|
+
{
|
|
699
|
+
Bearer: ["auth:write"]
|
|
700
|
+
}
|
|
701
|
+
],
|
|
702
|
+
responses: {
|
|
703
|
+
201: {
|
|
704
|
+
content: {
|
|
705
|
+
"application/json": {
|
|
706
|
+
schema: q
|
|
707
|
+
}
|
|
708
|
+
},
|
|
709
|
+
description: "Tenant created"
|
|
710
|
+
},
|
|
711
|
+
400: {
|
|
712
|
+
description: "Validation error"
|
|
713
|
+
}
|
|
714
|
+
}
|
|
715
|
+
}),
|
|
716
|
+
async (e) => {
|
|
717
|
+
var d, r;
|
|
718
|
+
const t = e.var.user;
|
|
719
|
+
if (!(t != null && t.sub))
|
|
720
|
+
throw new p(401, {
|
|
721
|
+
message: "Authentication required to create tenants"
|
|
722
|
+
});
|
|
723
|
+
let c = e.req.valid("json");
|
|
724
|
+
const o = {
|
|
725
|
+
adapters: e.env.data,
|
|
726
|
+
ctx: e
|
|
727
|
+
};
|
|
728
|
+
(d = n.tenants) != null && d.beforeCreate && (c = await n.tenants.beforeCreate(o, c));
|
|
729
|
+
const i = await e.env.data.tenants.create(c);
|
|
730
|
+
return (r = n.tenants) != null && r.afterCreate && await n.tenants.afterCreate(o, i), e.json(i, 201);
|
|
731
|
+
}
|
|
732
|
+
), s.openapi(
|
|
733
|
+
O({
|
|
734
|
+
tags: ["tenants"],
|
|
735
|
+
method: "patch",
|
|
736
|
+
path: "/{id}",
|
|
737
|
+
request: {
|
|
738
|
+
params: b.object({
|
|
739
|
+
id: b.string()
|
|
740
|
+
}),
|
|
741
|
+
body: {
|
|
742
|
+
content: {
|
|
743
|
+
"application/json": {
|
|
744
|
+
schema: b.object(I.shape).partial()
|
|
745
|
+
}
|
|
746
|
+
}
|
|
747
|
+
}
|
|
748
|
+
},
|
|
749
|
+
security: [
|
|
750
|
+
{
|
|
751
|
+
Bearer: ["auth:write"]
|
|
752
|
+
}
|
|
753
|
+
],
|
|
754
|
+
responses: {
|
|
755
|
+
200: {
|
|
756
|
+
content: {
|
|
757
|
+
"application/json": {
|
|
758
|
+
schema: q
|
|
759
|
+
}
|
|
760
|
+
},
|
|
761
|
+
description: "Tenant updated"
|
|
762
|
+
},
|
|
763
|
+
403: {
|
|
764
|
+
description: "Access denied"
|
|
765
|
+
},
|
|
766
|
+
404: {
|
|
767
|
+
description: "Tenant not found"
|
|
768
|
+
}
|
|
769
|
+
}
|
|
770
|
+
}),
|
|
771
|
+
async (e) => {
|
|
772
|
+
var l, f;
|
|
773
|
+
const { id: t } = e.req.valid("param");
|
|
774
|
+
if (a.accessControl) {
|
|
775
|
+
const u = e.var.user, m = a.accessControl.mainTenantId;
|
|
776
|
+
if (!(u != null && u.sub))
|
|
777
|
+
throw new p(401, {
|
|
778
|
+
message: "Authentication required"
|
|
779
|
+
});
|
|
780
|
+
if (t !== m && !(await z(
|
|
781
|
+
(w) => e.env.data.userOrganizations.listUserOrganizations(
|
|
782
|
+
m,
|
|
783
|
+
u.sub,
|
|
784
|
+
w
|
|
785
|
+
),
|
|
786
|
+
"organizations"
|
|
787
|
+
)).some((w) => w.id === t))
|
|
788
|
+
throw new p(403, {
|
|
789
|
+
message: "Access denied to this tenant"
|
|
790
|
+
});
|
|
791
|
+
}
|
|
792
|
+
if (!await e.env.data.tenants.get(t))
|
|
793
|
+
throw new p(404, {
|
|
794
|
+
message: "Tenant not found"
|
|
795
|
+
});
|
|
796
|
+
const o = e.req.valid("json"), i = {
|
|
797
|
+
adapters: e.env.data,
|
|
798
|
+
ctx: e
|
|
799
|
+
};
|
|
800
|
+
let d = o;
|
|
801
|
+
(l = n.tenants) != null && l.beforeUpdate && (d = await n.tenants.beforeUpdate(
|
|
802
|
+
i,
|
|
803
|
+
t,
|
|
804
|
+
o
|
|
805
|
+
)), await e.env.data.tenants.update(t, d);
|
|
806
|
+
const r = await e.env.data.tenants.get(t);
|
|
807
|
+
if (!r)
|
|
808
|
+
throw new p(500, {
|
|
809
|
+
message: "Failed to retrieve updated tenant"
|
|
810
|
+
});
|
|
811
|
+
return (f = n.tenants) != null && f.afterUpdate && await n.tenants.afterUpdate(i, r), e.json(r);
|
|
812
|
+
}
|
|
813
|
+
), s.openapi(
|
|
814
|
+
O({
|
|
815
|
+
tags: ["tenants"],
|
|
816
|
+
method: "delete",
|
|
817
|
+
path: "/{id}",
|
|
818
|
+
request: {
|
|
819
|
+
params: b.object({
|
|
820
|
+
id: b.string()
|
|
821
|
+
})
|
|
822
|
+
},
|
|
823
|
+
security: [
|
|
824
|
+
{
|
|
825
|
+
Bearer: ["auth:write"]
|
|
826
|
+
}
|
|
827
|
+
],
|
|
828
|
+
responses: {
|
|
829
|
+
204: {
|
|
830
|
+
description: "Tenant deleted"
|
|
831
|
+
},
|
|
832
|
+
403: {
|
|
833
|
+
description: "Access denied or cannot delete main tenant"
|
|
834
|
+
},
|
|
835
|
+
404: {
|
|
836
|
+
description: "Tenant not found"
|
|
837
|
+
}
|
|
838
|
+
}
|
|
839
|
+
}),
|
|
840
|
+
async (e) => {
|
|
841
|
+
var i, d;
|
|
842
|
+
const { id: t } = e.req.valid("param");
|
|
843
|
+
if (a.accessControl) {
|
|
844
|
+
const r = e.var.user, l = a.accessControl.mainTenantId;
|
|
845
|
+
if (!(r != null && r.sub))
|
|
846
|
+
throw new p(401, {
|
|
847
|
+
message: "Authentication required"
|
|
848
|
+
});
|
|
849
|
+
if (t === l)
|
|
850
|
+
throw new p(403, {
|
|
851
|
+
message: "Cannot delete the main tenant"
|
|
852
|
+
});
|
|
853
|
+
if (!(await z(
|
|
854
|
+
(m) => e.env.data.userOrganizations.listUserOrganizations(
|
|
855
|
+
l,
|
|
856
|
+
r.sub,
|
|
857
|
+
m
|
|
858
|
+
),
|
|
859
|
+
"organizations"
|
|
860
|
+
)).some((m) => m.id === t))
|
|
861
|
+
throw new p(403, {
|
|
862
|
+
message: "Access denied to this tenant"
|
|
863
|
+
});
|
|
864
|
+
}
|
|
865
|
+
if (!await e.env.data.tenants.get(t))
|
|
866
|
+
throw new p(404, {
|
|
867
|
+
message: "Tenant not found"
|
|
868
|
+
});
|
|
869
|
+
const o = {
|
|
870
|
+
adapters: e.env.data,
|
|
871
|
+
ctx: e
|
|
872
|
+
};
|
|
873
|
+
return (i = n.tenants) != null && i.beforeDelete && await n.tenants.beforeDelete(o, t), await e.env.data.tenants.remove(t), (d = n.tenants) != null && d.afterDelete && await n.tenants.afterDelete(o, t), e.body(null, 204);
|
|
874
|
+
}
|
|
875
|
+
), s;
|
|
876
|
+
}
|
|
877
|
+
function k(a) {
|
|
547
878
|
const n = [
|
|
548
879
|
{
|
|
549
880
|
pattern: /\/api\/v2\/resource-servers\/([^/]+)$/,
|
|
@@ -552,27 +883,27 @@ function L(e) {
|
|
|
552
883
|
{ pattern: /\/api\/v2\/roles\/([^/]+)$/, type: "role" },
|
|
553
884
|
{ pattern: /\/api\/v2\/connections\/([^/]+)$/, type: "connection" }
|
|
554
885
|
];
|
|
555
|
-
for (const { pattern: s, type:
|
|
556
|
-
const
|
|
557
|
-
if (
|
|
558
|
-
return { type:
|
|
886
|
+
for (const { pattern: s, type: e } of n) {
|
|
887
|
+
const t = a.match(s);
|
|
888
|
+
if (t && t[1])
|
|
889
|
+
return { type: e, id: t[1] };
|
|
559
890
|
}
|
|
560
891
|
return null;
|
|
561
892
|
}
|
|
562
|
-
async function
|
|
893
|
+
async function x(a, n, s) {
|
|
563
894
|
try {
|
|
564
895
|
switch (s.type) {
|
|
565
896
|
case "resource_server": {
|
|
566
|
-
const
|
|
567
|
-
return (
|
|
897
|
+
const e = await a.resourceServers.get(n, s.id);
|
|
898
|
+
return (e == null ? void 0 : e.is_system) === !0;
|
|
568
899
|
}
|
|
569
900
|
case "role": {
|
|
570
|
-
const
|
|
571
|
-
return (
|
|
901
|
+
const e = await a.roles.get(n, s.id);
|
|
902
|
+
return (e == null ? void 0 : e.is_system) === !0;
|
|
572
903
|
}
|
|
573
904
|
case "connection": {
|
|
574
|
-
const
|
|
575
|
-
return (
|
|
905
|
+
const e = await a.connections.get(n, s.id);
|
|
906
|
+
return (e == null ? void 0 : e.is_system) === !0;
|
|
576
907
|
}
|
|
577
908
|
default:
|
|
578
909
|
return !1;
|
|
@@ -581,101 +912,101 @@ async function Y(e, n, s) {
|
|
|
581
912
|
return !1;
|
|
582
913
|
}
|
|
583
914
|
}
|
|
584
|
-
function
|
|
915
|
+
function ee(a) {
|
|
585
916
|
return {
|
|
586
917
|
resource_server: "resource server",
|
|
587
918
|
role: "role",
|
|
588
919
|
connection: "connection"
|
|
589
|
-
}[
|
|
920
|
+
}[a];
|
|
590
921
|
}
|
|
591
|
-
function
|
|
592
|
-
return async (
|
|
593
|
-
if (!["PATCH", "PUT", "DELETE"].includes(
|
|
922
|
+
function te() {
|
|
923
|
+
return async (a, n) => {
|
|
924
|
+
if (!["PATCH", "PUT", "DELETE"].includes(a.req.method))
|
|
594
925
|
return n();
|
|
595
|
-
const s =
|
|
926
|
+
const s = k(a.req.path);
|
|
596
927
|
if (!s)
|
|
597
928
|
return n();
|
|
598
|
-
const
|
|
599
|
-
if (!
|
|
929
|
+
const e = a.var.tenant_id || a.req.header("x-tenant-id") || a.req.header("tenant-id");
|
|
930
|
+
if (!e)
|
|
600
931
|
return n();
|
|
601
|
-
if (await
|
|
932
|
+
if (await x(a.env.data, e, s))
|
|
602
933
|
throw new p(403, {
|
|
603
|
-
message: `This ${
|
|
934
|
+
message: `This ${ee(s.type)} is a system resource and cannot be modified. Make changes in the main tenant instead.`
|
|
604
935
|
});
|
|
605
936
|
return n();
|
|
606
937
|
};
|
|
607
938
|
}
|
|
608
|
-
function
|
|
939
|
+
function ae(a) {
|
|
609
940
|
return async (n, s) => {
|
|
610
|
-
if (!
|
|
941
|
+
if (!a.accessControl)
|
|
611
942
|
return s();
|
|
612
|
-
const
|
|
613
|
-
if (!
|
|
943
|
+
const e = n.var.tenant_id, t = n.var.organization_id;
|
|
944
|
+
if (!e)
|
|
614
945
|
throw new p(400, {
|
|
615
946
|
message: "Tenant ID not found in request"
|
|
616
947
|
});
|
|
617
|
-
if (!
|
|
618
|
-
a,
|
|
948
|
+
if (!W(
|
|
619
949
|
t,
|
|
620
|
-
e
|
|
950
|
+
e,
|
|
951
|
+
a.accessControl.mainTenantId
|
|
621
952
|
))
|
|
622
953
|
throw new p(403, {
|
|
623
|
-
message: `Access denied to tenant ${
|
|
954
|
+
message: `Access denied to tenant ${e}`
|
|
624
955
|
});
|
|
625
956
|
return s();
|
|
626
957
|
};
|
|
627
958
|
}
|
|
628
|
-
function
|
|
959
|
+
function ne(a) {
|
|
629
960
|
return async (n, s) => {
|
|
630
|
-
if (!
|
|
961
|
+
if (!a.subdomainRouting)
|
|
631
962
|
return s();
|
|
632
963
|
const {
|
|
633
|
-
baseDomain:
|
|
634
|
-
reservedSubdomains:
|
|
635
|
-
resolveSubdomain:
|
|
636
|
-
} =
|
|
964
|
+
baseDomain: e,
|
|
965
|
+
reservedSubdomains: t = [],
|
|
966
|
+
resolveSubdomain: c
|
|
967
|
+
} = a.subdomainRouting, o = n.req.header("host") || "";
|
|
637
968
|
let i = null;
|
|
638
|
-
if (
|
|
639
|
-
const r =
|
|
969
|
+
if (o.endsWith(e)) {
|
|
970
|
+
const r = o.slice(0, -(e.length + 1));
|
|
640
971
|
r && !r.includes(".") && (i = r);
|
|
641
972
|
}
|
|
642
|
-
if (i &&
|
|
643
|
-
return
|
|
644
|
-
let
|
|
645
|
-
if (
|
|
646
|
-
|
|
647
|
-
else if (
|
|
973
|
+
if (i && t.includes(i) && (i = null), !i)
|
|
974
|
+
return a.accessControl && n.set("tenant_id", a.accessControl.mainTenantId), s();
|
|
975
|
+
let d = null;
|
|
976
|
+
if (c)
|
|
977
|
+
d = await c(i);
|
|
978
|
+
else if (a.subdomainRouting.useOrganizations !== !1 && a.accessControl)
|
|
648
979
|
try {
|
|
649
980
|
const r = await n.env.data.organizations.get(
|
|
650
|
-
|
|
981
|
+
a.accessControl.mainTenantId,
|
|
651
982
|
i
|
|
652
983
|
);
|
|
653
|
-
r && (
|
|
984
|
+
r && (d = r.id);
|
|
654
985
|
} catch {
|
|
655
986
|
}
|
|
656
|
-
if (!
|
|
987
|
+
if (!d)
|
|
657
988
|
throw new p(404, {
|
|
658
989
|
message: `Tenant not found for subdomain: ${i}`
|
|
659
990
|
});
|
|
660
|
-
return n.set("tenant_id",
|
|
991
|
+
return n.set("tenant_id", d), s();
|
|
661
992
|
};
|
|
662
993
|
}
|
|
663
|
-
function
|
|
994
|
+
function se(a) {
|
|
664
995
|
return async (n, s) => {
|
|
665
|
-
if (!
|
|
996
|
+
if (!a.databaseIsolation)
|
|
666
997
|
return s();
|
|
667
|
-
const
|
|
668
|
-
if (!
|
|
998
|
+
const e = n.var.tenant_id;
|
|
999
|
+
if (!e)
|
|
669
1000
|
throw new p(400, {
|
|
670
1001
|
message: "Tenant ID not found in request"
|
|
671
1002
|
});
|
|
672
1003
|
try {
|
|
673
|
-
const
|
|
674
|
-
n.env.data =
|
|
675
|
-
} catch (
|
|
1004
|
+
const t = await a.databaseIsolation.getAdapters(e);
|
|
1005
|
+
n.env.data = t;
|
|
1006
|
+
} catch (t) {
|
|
676
1007
|
throw console.error(
|
|
677
|
-
`Failed to resolve database for tenant ${
|
|
678
|
-
|
|
1008
|
+
`Failed to resolve database for tenant ${e}:`,
|
|
1009
|
+
t
|
|
679
1010
|
), new p(500, {
|
|
680
1011
|
message: "Failed to resolve tenant database"
|
|
681
1012
|
});
|
|
@@ -683,190 +1014,194 @@ function H(e) {
|
|
|
683
1014
|
return s();
|
|
684
1015
|
};
|
|
685
1016
|
}
|
|
686
|
-
function M(
|
|
687
|
-
const n =
|
|
688
|
-
return async (
|
|
689
|
-
}), await s(
|
|
690
|
-
}), await t
|
|
691
|
-
}),
|
|
1017
|
+
function M(a) {
|
|
1018
|
+
const n = ne(a), s = ae(a), e = se(a);
|
|
1019
|
+
return async (t, c) => (await n(t, async () => {
|
|
1020
|
+
}), await s(t, async () => {
|
|
1021
|
+
}), await e(t, async () => {
|
|
1022
|
+
}), c());
|
|
692
1023
|
}
|
|
693
|
-
function
|
|
694
|
-
const n =
|
|
1024
|
+
function fe(a) {
|
|
1025
|
+
const n = $(a);
|
|
695
1026
|
return {
|
|
696
1027
|
name: "multi-tenancy",
|
|
697
1028
|
// Apply multi-tenancy middleware for subdomain routing, database resolution, etc.
|
|
698
|
-
middleware: M(
|
|
1029
|
+
middleware: M(a),
|
|
699
1030
|
// Provide lifecycle hooks
|
|
700
1031
|
hooks: n,
|
|
701
1032
|
// Mount tenant management routes
|
|
702
1033
|
routes: [
|
|
703
1034
|
{
|
|
704
1035
|
path: "/management",
|
|
705
|
-
handler:
|
|
1036
|
+
handler: D(a, n)
|
|
706
1037
|
}
|
|
707
1038
|
],
|
|
708
1039
|
// Called when plugin is registered
|
|
709
1040
|
onRegister: async () => {
|
|
710
|
-
console.log("Multi-tenancy plugin registered"),
|
|
711
|
-
` - Access control enabled (main tenant: ${
|
|
712
|
-
),
|
|
713
|
-
` - Subdomain routing enabled (base domain: ${
|
|
714
|
-
),
|
|
1041
|
+
console.log("Multi-tenancy plugin registered"), a.accessControl && console.log(
|
|
1042
|
+
` - Access control enabled (main tenant: ${a.accessControl.mainTenantId})`
|
|
1043
|
+
), a.subdomainRouting && console.log(
|
|
1044
|
+
` - Subdomain routing enabled (base domain: ${a.subdomainRouting.baseDomain})`
|
|
1045
|
+
), a.databaseIsolation && console.log(" - Database isolation enabled");
|
|
715
1046
|
}
|
|
716
1047
|
};
|
|
717
1048
|
}
|
|
718
|
-
function
|
|
719
|
-
const n =
|
|
1049
|
+
function $(a) {
|
|
1050
|
+
const n = a.accessControl ? V(a.accessControl) : {}, s = a.databaseIsolation ? L(a.databaseIsolation) : {}, e = Q(a);
|
|
720
1051
|
return {
|
|
721
1052
|
...n,
|
|
722
1053
|
...s,
|
|
723
|
-
tenants:
|
|
1054
|
+
tenants: e
|
|
724
1055
|
};
|
|
725
1056
|
}
|
|
726
|
-
function
|
|
727
|
-
const n = new
|
|
728
|
-
return n.route("/tenants",
|
|
1057
|
+
function re(a) {
|
|
1058
|
+
const n = new S(), s = $(a);
|
|
1059
|
+
return n.route("/tenants", D(a, s)), n;
|
|
729
1060
|
}
|
|
730
|
-
function
|
|
1061
|
+
function me(a) {
|
|
731
1062
|
return {
|
|
732
|
-
hooks:
|
|
733
|
-
middleware: M(
|
|
734
|
-
app:
|
|
735
|
-
config:
|
|
1063
|
+
hooks: $(a),
|
|
1064
|
+
middleware: M(a),
|
|
1065
|
+
app: re(a),
|
|
1066
|
+
config: a
|
|
736
1067
|
};
|
|
737
1068
|
}
|
|
738
|
-
function
|
|
1069
|
+
function pe(a) {
|
|
739
1070
|
const {
|
|
740
1071
|
mainTenantId: n = "main",
|
|
741
1072
|
syncResourceServers: s = !0,
|
|
742
|
-
multiTenancy:
|
|
743
|
-
entityHooks:
|
|
744
|
-
...
|
|
745
|
-
} =
|
|
746
|
-
...
|
|
1073
|
+
multiTenancy: e,
|
|
1074
|
+
entityHooks: t,
|
|
1075
|
+
...c
|
|
1076
|
+
} = a, o = {
|
|
1077
|
+
...e,
|
|
747
1078
|
accessControl: {
|
|
748
1079
|
mainTenantId: n,
|
|
749
1080
|
requireOrganizationMatch: !1,
|
|
750
1081
|
defaultPermissions: ["tenant:admin"],
|
|
751
|
-
...
|
|
1082
|
+
...e == null ? void 0 : e.accessControl
|
|
752
1083
|
}
|
|
753
|
-
}, i =
|
|
754
|
-
let
|
|
755
|
-
s && (
|
|
1084
|
+
}, i = $(o);
|
|
1085
|
+
let d, r;
|
|
1086
|
+
s && (d = H({
|
|
756
1087
|
mainTenantId: n,
|
|
757
|
-
getChildTenantIds: async () => (await
|
|
758
|
-
(
|
|
1088
|
+
getChildTenantIds: async () => (await z(
|
|
1089
|
+
(y) => a.dataAdapter.tenants.list(y),
|
|
759
1090
|
"tenants",
|
|
760
1091
|
{ cursorField: "id", pageSize: 100 }
|
|
761
|
-
)).filter((
|
|
762
|
-
getAdapters: async (
|
|
763
|
-
}), r =
|
|
1092
|
+
)).filter((y) => y.id !== n).map((y) => y.id),
|
|
1093
|
+
getAdapters: async (g) => a.dataAdapter
|
|
1094
|
+
}), r = J({
|
|
764
1095
|
mainTenantId: n,
|
|
765
|
-
getMainTenantAdapters: async () =>
|
|
766
|
-
getAdapters: async (
|
|
1096
|
+
getMainTenantAdapters: async () => a.dataAdapter,
|
|
1097
|
+
getAdapters: async (g) => a.dataAdapter
|
|
767
1098
|
}));
|
|
768
|
-
const l = async (
|
|
769
|
-
const
|
|
770
|
-
if (
|
|
1099
|
+
const l = async (g, y, ..._) => {
|
|
1100
|
+
const A = [];
|
|
1101
|
+
if (g)
|
|
771
1102
|
try {
|
|
772
|
-
await
|
|
773
|
-
} catch (
|
|
774
|
-
|
|
1103
|
+
await g(..._);
|
|
1104
|
+
} catch (C) {
|
|
1105
|
+
A.push(C instanceof Error ? C : new Error(String(C)));
|
|
775
1106
|
}
|
|
776
|
-
if (
|
|
1107
|
+
if (y)
|
|
777
1108
|
try {
|
|
778
|
-
await
|
|
779
|
-
} catch (
|
|
780
|
-
|
|
1109
|
+
await y(..._);
|
|
1110
|
+
} catch (C) {
|
|
1111
|
+
A.push(C instanceof Error ? C : new Error(String(C)));
|
|
781
1112
|
}
|
|
782
|
-
if (
|
|
783
|
-
throw
|
|
784
|
-
if (
|
|
1113
|
+
if (A.length === 1)
|
|
1114
|
+
throw A[0];
|
|
1115
|
+
if (A.length > 1)
|
|
785
1116
|
throw new AggregateError(
|
|
786
|
-
|
|
787
|
-
`Multiple hook errors: ${
|
|
1117
|
+
A,
|
|
1118
|
+
`Multiple hook errors: ${A.map((C) => C.message).join("; ")}`
|
|
788
1119
|
);
|
|
789
1120
|
}, f = {
|
|
790
|
-
...
|
|
791
|
-
resourceServers:
|
|
792
|
-
...
|
|
793
|
-
afterCreate: async (
|
|
794
|
-
var
|
|
1121
|
+
...t,
|
|
1122
|
+
resourceServers: d ? {
|
|
1123
|
+
...t == null ? void 0 : t.resourceServers,
|
|
1124
|
+
afterCreate: async (g, y) => {
|
|
1125
|
+
var _;
|
|
795
1126
|
await l(
|
|
796
|
-
(
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
1127
|
+
(_ = t == null ? void 0 : t.resourceServers) == null ? void 0 : _.afterCreate,
|
|
1128
|
+
d == null ? void 0 : d.afterCreate,
|
|
1129
|
+
g,
|
|
1130
|
+
y
|
|
800
1131
|
);
|
|
801
1132
|
},
|
|
802
|
-
afterUpdate: async (
|
|
803
|
-
var
|
|
1133
|
+
afterUpdate: async (g, y, _) => {
|
|
1134
|
+
var A;
|
|
804
1135
|
await l(
|
|
805
|
-
(
|
|
806
|
-
|
|
1136
|
+
(A = t == null ? void 0 : t.resourceServers) == null ? void 0 : A.afterUpdate,
|
|
1137
|
+
d == null ? void 0 : d.afterUpdate,
|
|
1138
|
+
g,
|
|
807
1139
|
y,
|
|
808
|
-
|
|
809
|
-
v
|
|
1140
|
+
_
|
|
810
1141
|
);
|
|
811
1142
|
},
|
|
812
|
-
afterDelete: async (
|
|
813
|
-
var
|
|
1143
|
+
afterDelete: async (g, y) => {
|
|
1144
|
+
var _;
|
|
814
1145
|
await l(
|
|
815
|
-
(
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
1146
|
+
(_ = t == null ? void 0 : t.resourceServers) == null ? void 0 : _.afterDelete,
|
|
1147
|
+
d == null ? void 0 : d.afterDelete,
|
|
1148
|
+
g,
|
|
1149
|
+
y
|
|
819
1150
|
);
|
|
820
1151
|
}
|
|
821
|
-
} :
|
|
1152
|
+
} : t == null ? void 0 : t.resourceServers,
|
|
822
1153
|
tenants: r ? {
|
|
823
|
-
...
|
|
824
|
-
afterCreate: async (
|
|
825
|
-
var
|
|
1154
|
+
...t == null ? void 0 : t.tenants,
|
|
1155
|
+
afterCreate: async (g, y) => {
|
|
1156
|
+
var _;
|
|
826
1157
|
await l(
|
|
827
|
-
(
|
|
1158
|
+
(_ = t == null ? void 0 : t.tenants) == null ? void 0 : _.afterCreate,
|
|
828
1159
|
r == null ? void 0 : r.afterCreate,
|
|
829
|
-
|
|
830
|
-
|
|
1160
|
+
g,
|
|
1161
|
+
y
|
|
831
1162
|
);
|
|
832
1163
|
}
|
|
833
|
-
} :
|
|
834
|
-
}, u =
|
|
835
|
-
|
|
836
|
-
entityHooks: f
|
|
837
|
-
}), { app: m, managementApp: _, ...g } = u, w = new $();
|
|
838
|
-
w.use("/api/v2/*", Z()), w.route("/", m);
|
|
839
|
-
const C = S(
|
|
840
|
-
d,
|
|
1164
|
+
} : t == null ? void 0 : t.tenants
|
|
1165
|
+
}, u = X(
|
|
1166
|
+
o,
|
|
841
1167
|
i
|
|
842
|
-
)
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
1168
|
+
), m = K({
|
|
1169
|
+
...c,
|
|
1170
|
+
entityHooks: f,
|
|
1171
|
+
// Register tenant routes via the extension mechanism
|
|
1172
|
+
// This ensures they go through the full middleware chain (caching, tenant, auth, entity hooks)
|
|
1173
|
+
managementApiExtensions: [
|
|
1174
|
+
...c.managementApiExtensions || [],
|
|
1175
|
+
{ path: "/tenants", router: u }
|
|
1176
|
+
]
|
|
1177
|
+
}), { app: v, managementApp: h, ...w } = m, T = new S();
|
|
1178
|
+
return T.use("/api/v2/*", te()), T.route("/", v), {
|
|
1179
|
+
app: T,
|
|
1180
|
+
managementApp: h,
|
|
1181
|
+
...w,
|
|
1182
|
+
multiTenancyConfig: o,
|
|
848
1183
|
multiTenancyHooks: i
|
|
849
1184
|
};
|
|
850
1185
|
}
|
|
851
1186
|
export {
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
1187
|
+
he as MANAGEMENT_API_SCOPES,
|
|
1188
|
+
V as createAccessControlHooks,
|
|
1189
|
+
ae as createAccessControlMiddleware,
|
|
1190
|
+
L as createDatabaseHooks,
|
|
1191
|
+
se as createDatabaseMiddleware,
|
|
1192
|
+
re as createMultiTenancy,
|
|
1193
|
+
$ as createMultiTenancyHooks,
|
|
859
1194
|
M as createMultiTenancyMiddleware,
|
|
860
|
-
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
1195
|
+
fe as createMultiTenancyPlugin,
|
|
1196
|
+
te as createProtectSyncedMiddleware,
|
|
1197
|
+
Q as createProvisioningHooks,
|
|
1198
|
+
H as createResourceServerSyncHooks,
|
|
1199
|
+
ne as createSubdomainMiddleware,
|
|
1200
|
+
J as createTenantResourceServerSyncHooks,
|
|
1201
|
+
D as createTenantsRouter,
|
|
1202
|
+
z as fetchAll,
|
|
1203
|
+
pe as init,
|
|
1204
|
+
ye as seed,
|
|
1205
|
+
me as setupMultiTenancy,
|
|
1206
|
+
W as validateTenantAccess
|
|
872
1207
|
};
|