@authhero/multi-tenancy 13.3.0 → 13.4.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 +18619 -407
- package/dist/multi-tenancy.mjs +506 -282
- package/package.json +4 -3
package/dist/multi-tenancy.mjs
CHANGED
|
@@ -1,27 +1,29 @@
|
|
|
1
|
-
var
|
|
2
|
-
var
|
|
3
|
-
var
|
|
4
|
-
import { Hono as
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
|
|
1
|
+
var R = Object.defineProperty;
|
|
2
|
+
var F = (a, e, s) => e in a ? R(a, e, { enumerable: !0, configurable: !0, writable: !0, value: s }) : a[e] = s;
|
|
3
|
+
var C = (a, e, s) => F(a, typeof e != "symbol" ? e + "" : e, s);
|
|
4
|
+
import { Hono as $ } from "hono";
|
|
5
|
+
import { init as z } from "authhero";
|
|
6
|
+
import { seed as ce } from "authhero";
|
|
7
|
+
import { z as P } from "zod";
|
|
8
|
+
import { auth0QuerySchema as j, tenantInsertSchema as M } from "@authhero/adapter-interfaces";
|
|
9
|
+
function U(a) {
|
|
8
10
|
const { mainTenantId: e, requireOrganizationMatch: s = !0 } = a;
|
|
9
11
|
return {
|
|
10
|
-
async onTenantAccessValidation(
|
|
11
|
-
if (
|
|
12
|
+
async onTenantAccessValidation(n, t) {
|
|
13
|
+
if (t === e)
|
|
12
14
|
return !0;
|
|
13
15
|
if (s) {
|
|
14
|
-
const
|
|
15
|
-
return
|
|
16
|
+
const o = n.var.organization_id;
|
|
17
|
+
return o ? o === t : !1;
|
|
16
18
|
}
|
|
17
19
|
return !0;
|
|
18
20
|
}
|
|
19
21
|
};
|
|
20
22
|
}
|
|
21
|
-
function
|
|
23
|
+
function K(a, e, s) {
|
|
22
24
|
return e === s ? !0 : a ? a === e : !1;
|
|
23
25
|
}
|
|
24
|
-
function
|
|
26
|
+
function V(a) {
|
|
25
27
|
return {
|
|
26
28
|
async resolveDataAdapters(e) {
|
|
27
29
|
try {
|
|
@@ -36,61 +38,61 @@ function I(a) {
|
|
|
36
38
|
}
|
|
37
39
|
};
|
|
38
40
|
}
|
|
39
|
-
function
|
|
41
|
+
function O(a) {
|
|
40
42
|
return {
|
|
41
43
|
async afterCreate(e, s) {
|
|
42
|
-
const { accessControl:
|
|
43
|
-
|
|
44
|
+
const { accessControl: n, databaseIsolation: t, settingsInheritance: o } = a;
|
|
45
|
+
n && e.ctx && await N(e, s, n), t != null && t.onProvision && await t.onProvision(s.id), (o == null ? void 0 : o.inheritFromMain) !== !1 && e.ctx && await E(e, s, a);
|
|
44
46
|
},
|
|
45
47
|
async beforeDelete(e, s) {
|
|
46
|
-
const { accessControl:
|
|
47
|
-
if (
|
|
48
|
+
const { accessControl: n, databaseIsolation: t } = a;
|
|
49
|
+
if (n)
|
|
48
50
|
try {
|
|
49
|
-
const
|
|
50
|
-
|
|
51
|
+
const d = (await e.adapters.organizations.list(
|
|
52
|
+
n.mainTenantId
|
|
51
53
|
)).organizations.find((c) => c.name === s);
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
54
|
+
d && await e.adapters.organizations.remove(
|
|
55
|
+
n.mainTenantId,
|
|
56
|
+
d.id
|
|
55
57
|
);
|
|
56
|
-
} catch (
|
|
58
|
+
} catch (o) {
|
|
57
59
|
console.warn(
|
|
58
60
|
`Failed to remove organization for tenant ${s}:`,
|
|
59
|
-
|
|
61
|
+
o
|
|
60
62
|
);
|
|
61
63
|
}
|
|
62
|
-
if (
|
|
64
|
+
if (t != null && t.onDeprovision)
|
|
63
65
|
try {
|
|
64
|
-
await
|
|
65
|
-
} catch (
|
|
66
|
+
await t.onDeprovision(s);
|
|
67
|
+
} catch (o) {
|
|
66
68
|
console.warn(
|
|
67
69
|
`Failed to deprovision database for tenant ${s}:`,
|
|
68
|
-
|
|
70
|
+
o
|
|
69
71
|
);
|
|
70
72
|
}
|
|
71
73
|
}
|
|
72
74
|
};
|
|
73
75
|
}
|
|
74
|
-
async function
|
|
75
|
-
const { mainTenantId:
|
|
76
|
-
await a.adapters.organizations.create(
|
|
76
|
+
async function N(a, e, s) {
|
|
77
|
+
const { mainTenantId: n, defaultPermissions: t, defaultRoles: o } = s;
|
|
78
|
+
await a.adapters.organizations.create(n, {
|
|
77
79
|
id: e.id,
|
|
78
80
|
name: e.id,
|
|
79
81
|
display_name: e.friendly_name || e.id
|
|
80
|
-
}),
|
|
81
|
-
`Would assign roles ${
|
|
82
|
-
),
|
|
83
|
-
`Would grant permissions ${
|
|
82
|
+
}), o && o.length > 0 && console.log(
|
|
83
|
+
`Would assign roles ${o.join(", ")} to organization ${e.id}`
|
|
84
|
+
), t && t.length > 0 && console.log(
|
|
85
|
+
`Would grant permissions ${t.join(", ")} to organization ${e.id}`
|
|
84
86
|
);
|
|
85
87
|
}
|
|
86
|
-
async function
|
|
87
|
-
const { accessControl:
|
|
88
|
-
if (!
|
|
88
|
+
async function E(a, e, s) {
|
|
89
|
+
const { accessControl: n, settingsInheritance: t } = s;
|
|
90
|
+
if (!n)
|
|
89
91
|
return;
|
|
90
|
-
const
|
|
91
|
-
if (!
|
|
92
|
+
const o = await a.adapters.tenants.get(n.mainTenantId);
|
|
93
|
+
if (!o)
|
|
92
94
|
return;
|
|
93
|
-
let
|
|
95
|
+
let d = { ...o };
|
|
94
96
|
const c = [
|
|
95
97
|
"id",
|
|
96
98
|
"created_at",
|
|
@@ -101,115 +103,156 @@ async function q(a, e, s) {
|
|
|
101
103
|
"sender_email",
|
|
102
104
|
"sender_name"
|
|
103
105
|
];
|
|
104
|
-
for (const
|
|
105
|
-
delete
|
|
106
|
-
if (
|
|
107
|
-
const
|
|
108
|
-
for (const
|
|
109
|
-
|
|
110
|
-
|
|
106
|
+
for (const i of c)
|
|
107
|
+
delete d[i];
|
|
108
|
+
if (t != null && t.inheritedKeys) {
|
|
109
|
+
const i = {};
|
|
110
|
+
for (const r of t.inheritedKeys)
|
|
111
|
+
r in o && !c.includes(r) && (i[r] = o[r]);
|
|
112
|
+
d = i;
|
|
111
113
|
}
|
|
112
|
-
if (
|
|
113
|
-
for (const
|
|
114
|
-
delete
|
|
115
|
-
|
|
116
|
-
|
|
114
|
+
if (t != null && t.excludedKeys)
|
|
115
|
+
for (const i of t.excludedKeys)
|
|
116
|
+
delete d[i];
|
|
117
|
+
t != null && t.transformSettings && (d = t.transformSettings(
|
|
118
|
+
d,
|
|
117
119
|
e.id
|
|
118
|
-
)), Object.keys(
|
|
120
|
+
)), Object.keys(d).length > 0 && await a.adapters.tenants.update(e.id, d);
|
|
121
|
+
}
|
|
122
|
+
async function q(a, e, s = {}) {
|
|
123
|
+
const {
|
|
124
|
+
cursorField: n = "id",
|
|
125
|
+
sortOrder: t = "asc",
|
|
126
|
+
pageSize: o = 100,
|
|
127
|
+
maxItems: d = 1e4,
|
|
128
|
+
q: c
|
|
129
|
+
} = s, i = [];
|
|
130
|
+
let r, u = !0;
|
|
131
|
+
for (; u; ) {
|
|
132
|
+
let f = c || "";
|
|
133
|
+
if (r) {
|
|
134
|
+
const w = `${n}:${t === "asc" ? ">" : "<"}${r}`;
|
|
135
|
+
f = f ? `(${f}) AND ${w}` : w;
|
|
136
|
+
}
|
|
137
|
+
const l = {
|
|
138
|
+
per_page: o,
|
|
139
|
+
page: 0,
|
|
140
|
+
// Always use page 0 since we're doing cursor-based pagination
|
|
141
|
+
sort: {
|
|
142
|
+
sort_by: n,
|
|
143
|
+
sort_order: t
|
|
144
|
+
},
|
|
145
|
+
...f && { q: f }
|
|
146
|
+
}, T = (await a(l))[e] || [];
|
|
147
|
+
if (T.length === 0)
|
|
148
|
+
u = !1;
|
|
149
|
+
else {
|
|
150
|
+
i.push(...T);
|
|
151
|
+
const _ = T[T.length - 1];
|
|
152
|
+
if (_ && typeof _ == "object") {
|
|
153
|
+
const w = _[n];
|
|
154
|
+
w != null && (r = String(w));
|
|
155
|
+
}
|
|
156
|
+
T.length < o && (u = !1), d !== -1 && i.length >= d && (console.warn(
|
|
157
|
+
`fetchAll: Reached maxItems limit (${d}). There may be more items.`
|
|
158
|
+
), u = !1);
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
return i;
|
|
119
162
|
}
|
|
120
|
-
function
|
|
163
|
+
function W(a) {
|
|
121
164
|
const {
|
|
122
165
|
mainTenantId: e,
|
|
123
166
|
getChildTenantIds: s,
|
|
124
|
-
getAdapters:
|
|
125
|
-
shouldSync:
|
|
126
|
-
transformForSync:
|
|
167
|
+
getAdapters: n,
|
|
168
|
+
shouldSync: t = () => !0,
|
|
169
|
+
transformForSync: o
|
|
127
170
|
} = a;
|
|
128
|
-
async function
|
|
129
|
-
return (await
|
|
130
|
-
q: `identifier:${
|
|
171
|
+
async function d(r, u, f) {
|
|
172
|
+
return (await r.resourceServers.list(u, {
|
|
173
|
+
q: `identifier:${f}`,
|
|
131
174
|
per_page: 1
|
|
132
175
|
})).resource_servers[0] ?? null;
|
|
133
176
|
}
|
|
134
|
-
async function c(
|
|
135
|
-
const
|
|
177
|
+
async function c(r, u) {
|
|
178
|
+
const f = await s();
|
|
136
179
|
await Promise.all(
|
|
137
|
-
|
|
180
|
+
f.map(async (l) => {
|
|
138
181
|
try {
|
|
139
|
-
const m = await
|
|
140
|
-
name:
|
|
141
|
-
identifier:
|
|
142
|
-
scopes:
|
|
143
|
-
signing_alg:
|
|
144
|
-
signing_secret:
|
|
145
|
-
token_lifetime:
|
|
146
|
-
token_lifetime_for_web:
|
|
147
|
-
skip_consent_for_verifiable_first_party_clients:
|
|
148
|
-
allow_offline_access:
|
|
149
|
-
verificationKey:
|
|
150
|
-
options:
|
|
151
|
-
};
|
|
152
|
-
if (
|
|
153
|
-
const
|
|
182
|
+
const m = await n(l), _ = { ...o ? o(r, l) : {
|
|
183
|
+
name: r.name,
|
|
184
|
+
identifier: r.identifier,
|
|
185
|
+
scopes: r.scopes,
|
|
186
|
+
signing_alg: r.signing_alg,
|
|
187
|
+
signing_secret: r.signing_secret,
|
|
188
|
+
token_lifetime: r.token_lifetime,
|
|
189
|
+
token_lifetime_for_web: r.token_lifetime_for_web,
|
|
190
|
+
skip_consent_for_verifiable_first_party_clients: r.skip_consent_for_verifiable_first_party_clients,
|
|
191
|
+
allow_offline_access: r.allow_offline_access,
|
|
192
|
+
verificationKey: r.verificationKey,
|
|
193
|
+
options: r.options
|
|
194
|
+
}, is_system: !0 };
|
|
195
|
+
if (u === "create") {
|
|
196
|
+
const w = await d(
|
|
154
197
|
m,
|
|
155
|
-
|
|
156
|
-
|
|
198
|
+
l,
|
|
199
|
+
r.identifier
|
|
157
200
|
);
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
) : await m.resourceServers.create(
|
|
201
|
+
w && w.id ? await m.resourceServers.update(
|
|
202
|
+
l,
|
|
203
|
+
w.id,
|
|
204
|
+
_
|
|
205
|
+
) : await m.resourceServers.create(l, _);
|
|
163
206
|
} else {
|
|
164
|
-
const
|
|
207
|
+
const w = await d(
|
|
165
208
|
m,
|
|
166
|
-
|
|
167
|
-
|
|
209
|
+
l,
|
|
210
|
+
r.identifier
|
|
168
211
|
);
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
212
|
+
w && w.id && await m.resourceServers.update(
|
|
213
|
+
l,
|
|
214
|
+
w.id,
|
|
215
|
+
_
|
|
173
216
|
);
|
|
174
217
|
}
|
|
175
218
|
} catch (m) {
|
|
176
219
|
console.error(
|
|
177
|
-
`Failed to sync resource server "${
|
|
220
|
+
`Failed to sync resource server "${r.identifier}" to tenant "${l}":`,
|
|
178
221
|
m
|
|
179
222
|
);
|
|
180
223
|
}
|
|
181
224
|
})
|
|
182
225
|
);
|
|
183
226
|
}
|
|
184
|
-
async function
|
|
185
|
-
const
|
|
227
|
+
async function i(r) {
|
|
228
|
+
const u = await s();
|
|
186
229
|
await Promise.all(
|
|
187
|
-
|
|
230
|
+
u.map(async (f) => {
|
|
188
231
|
try {
|
|
189
|
-
const
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
232
|
+
const l = await n(f), m = await d(
|
|
233
|
+
l,
|
|
234
|
+
f,
|
|
235
|
+
r
|
|
193
236
|
);
|
|
194
|
-
m && m.id && await
|
|
195
|
-
} catch (
|
|
237
|
+
m && m.id && await l.resourceServers.remove(f, m.id);
|
|
238
|
+
} catch (l) {
|
|
196
239
|
console.error(
|
|
197
|
-
`Failed to delete resource server "${
|
|
198
|
-
|
|
240
|
+
`Failed to delete resource server "${r}" from tenant "${f}":`,
|
|
241
|
+
l
|
|
199
242
|
);
|
|
200
243
|
}
|
|
201
244
|
})
|
|
202
245
|
);
|
|
203
246
|
}
|
|
204
247
|
return {
|
|
205
|
-
afterCreate: async (
|
|
206
|
-
|
|
248
|
+
afterCreate: async (r, u) => {
|
|
249
|
+
r.tenantId === e && t(u) && await c(u, "create");
|
|
207
250
|
},
|
|
208
|
-
afterUpdate: async (
|
|
209
|
-
|
|
251
|
+
afterUpdate: async (r, u, f) => {
|
|
252
|
+
r.tenantId === e && t(f) && await c(f, "update");
|
|
210
253
|
},
|
|
211
|
-
afterDelete: async (
|
|
212
|
-
|
|
254
|
+
afterDelete: async (r, u) => {
|
|
255
|
+
r.tenantId === e && await i(u);
|
|
213
256
|
}
|
|
214
257
|
};
|
|
215
258
|
}
|
|
@@ -217,56 +260,58 @@ function Q(a) {
|
|
|
217
260
|
const {
|
|
218
261
|
mainTenantId: e,
|
|
219
262
|
getMainTenantAdapters: s,
|
|
220
|
-
getAdapters:
|
|
221
|
-
shouldSync:
|
|
222
|
-
transformForSync:
|
|
263
|
+
getAdapters: n,
|
|
264
|
+
shouldSync: t = () => !0,
|
|
265
|
+
transformForSync: o
|
|
223
266
|
} = a;
|
|
224
267
|
return {
|
|
225
|
-
async afterCreate(
|
|
268
|
+
async afterCreate(d, c) {
|
|
226
269
|
if (c.id !== e)
|
|
227
270
|
try {
|
|
228
|
-
const
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
271
|
+
const i = await s(), r = await n(c.id), u = await q(
|
|
272
|
+
(f) => i.resourceServers.list(e, f),
|
|
273
|
+
"resource_servers",
|
|
274
|
+
{ cursorField: "id", pageSize: 100 }
|
|
275
|
+
);
|
|
232
276
|
await Promise.all(
|
|
233
|
-
|
|
277
|
+
u.filter((f) => t(f)).map(async (f) => {
|
|
278
|
+
const l = f;
|
|
234
279
|
try {
|
|
235
|
-
const
|
|
236
|
-
name:
|
|
237
|
-
identifier:
|
|
238
|
-
scopes:
|
|
239
|
-
signing_alg:
|
|
240
|
-
signing_secret:
|
|
241
|
-
token_lifetime:
|
|
242
|
-
token_lifetime_for_web:
|
|
243
|
-
skip_consent_for_verifiable_first_party_clients:
|
|
244
|
-
allow_offline_access:
|
|
245
|
-
verificationKey:
|
|
246
|
-
options:
|
|
280
|
+
const m = o ? o(l, c.id) : {
|
|
281
|
+
name: l.name,
|
|
282
|
+
identifier: l.identifier,
|
|
283
|
+
scopes: l.scopes,
|
|
284
|
+
signing_alg: l.signing_alg,
|
|
285
|
+
signing_secret: l.signing_secret,
|
|
286
|
+
token_lifetime: l.token_lifetime,
|
|
287
|
+
token_lifetime_for_web: l.token_lifetime_for_web,
|
|
288
|
+
skip_consent_for_verifiable_first_party_clients: l.skip_consent_for_verifiable_first_party_clients,
|
|
289
|
+
allow_offline_access: l.allow_offline_access,
|
|
290
|
+
verificationKey: l.verificationKey,
|
|
291
|
+
options: l.options
|
|
247
292
|
};
|
|
248
|
-
await
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
);
|
|
252
|
-
} catch (
|
|
293
|
+
await r.resourceServers.create(c.id, {
|
|
294
|
+
...m,
|
|
295
|
+
is_system: !0
|
|
296
|
+
});
|
|
297
|
+
} catch (m) {
|
|
253
298
|
console.error(
|
|
254
|
-
`Failed to sync resource server "${
|
|
255
|
-
|
|
299
|
+
`Failed to sync resource server "${l.identifier}" to new tenant "${c.id}":`,
|
|
300
|
+
m
|
|
256
301
|
);
|
|
257
302
|
}
|
|
258
303
|
})
|
|
259
304
|
);
|
|
260
|
-
} catch (
|
|
305
|
+
} catch (i) {
|
|
261
306
|
console.error(
|
|
262
307
|
`Failed to sync resource servers to new tenant "${c.id}":`,
|
|
263
|
-
|
|
308
|
+
i
|
|
264
309
|
);
|
|
265
310
|
}
|
|
266
311
|
}
|
|
267
312
|
};
|
|
268
313
|
}
|
|
269
|
-
var
|
|
314
|
+
var p = class extends Error {
|
|
270
315
|
/**
|
|
271
316
|
* Creates an instance of `HTTPException`.
|
|
272
317
|
* @param status - HTTP status code for the exception. Defaults to 500.
|
|
@@ -274,8 +319,8 @@ var w = class extends Error {
|
|
|
274
319
|
*/
|
|
275
320
|
constructor(e = 500, s) {
|
|
276
321
|
super(s == null ? void 0 : s.message, { cause: s == null ? void 0 : s.cause });
|
|
277
|
-
|
|
278
|
-
|
|
322
|
+
C(this, "res");
|
|
323
|
+
C(this, "status");
|
|
279
324
|
this.res = s == null ? void 0 : s.res, this.status = e;
|
|
280
325
|
}
|
|
281
326
|
/**
|
|
@@ -292,215 +337,277 @@ var w = class extends Error {
|
|
|
292
337
|
});
|
|
293
338
|
}
|
|
294
339
|
};
|
|
295
|
-
function
|
|
296
|
-
const s = new
|
|
297
|
-
return s.get("/", async (
|
|
298
|
-
var
|
|
299
|
-
if (a.accessControl && await ((
|
|
340
|
+
function S(a, e) {
|
|
341
|
+
const s = new $();
|
|
342
|
+
return s.get("/", async (n) => {
|
|
343
|
+
var u;
|
|
344
|
+
if (a.accessControl && await ((u = e.onTenantAccessValidation) == null ? void 0 : u.call(
|
|
300
345
|
e,
|
|
301
|
-
|
|
346
|
+
n,
|
|
302
347
|
a.accessControl.mainTenantId
|
|
303
348
|
)) === !1)
|
|
304
|
-
throw new
|
|
349
|
+
throw new p(403, {
|
|
305
350
|
message: "Access denied to tenant management"
|
|
306
351
|
});
|
|
307
|
-
const
|
|
308
|
-
page:
|
|
309
|
-
per_page:
|
|
352
|
+
const t = j.parse(n.req.query()), { page: o, per_page: d, include_totals: c, q: i } = t, r = await n.env.data.tenants.list({
|
|
353
|
+
page: o,
|
|
354
|
+
per_page: d,
|
|
310
355
|
include_totals: c,
|
|
311
|
-
q:
|
|
356
|
+
q: i
|
|
312
357
|
});
|
|
313
|
-
return c ?
|
|
314
|
-
}), s.get("/:id", async (
|
|
358
|
+
return c ? n.json(r) : n.json(r.tenants);
|
|
359
|
+
}), s.get("/:id", async (n) => {
|
|
315
360
|
var c;
|
|
316
|
-
const
|
|
317
|
-
if (await ((c = e.onTenantAccessValidation) == null ? void 0 : c.call(e,
|
|
318
|
-
throw new
|
|
361
|
+
const t = n.req.param("id");
|
|
362
|
+
if (await ((c = e.onTenantAccessValidation) == null ? void 0 : c.call(e, n, t)) === !1)
|
|
363
|
+
throw new p(403, {
|
|
319
364
|
message: "Access denied to this tenant"
|
|
320
365
|
});
|
|
321
|
-
const
|
|
322
|
-
if (!
|
|
323
|
-
throw new
|
|
366
|
+
const d = await n.env.data.tenants.get(t);
|
|
367
|
+
if (!d)
|
|
368
|
+
throw new p(404, {
|
|
324
369
|
message: "Tenant not found"
|
|
325
370
|
});
|
|
326
|
-
return
|
|
327
|
-
}), s.post("/", async (
|
|
328
|
-
var
|
|
371
|
+
return n.json(d);
|
|
372
|
+
}), s.post("/", async (n) => {
|
|
373
|
+
var t, o, d, c;
|
|
329
374
|
try {
|
|
330
|
-
if (a.accessControl && await ((
|
|
375
|
+
if (a.accessControl && await ((t = e.onTenantAccessValidation) == null ? void 0 : t.call(
|
|
331
376
|
e,
|
|
332
|
-
|
|
377
|
+
n,
|
|
333
378
|
a.accessControl.mainTenantId
|
|
334
379
|
)) === !1)
|
|
335
|
-
throw new
|
|
380
|
+
throw new p(403, {
|
|
336
381
|
message: "Access denied to create tenants"
|
|
337
382
|
});
|
|
338
|
-
let
|
|
339
|
-
await
|
|
383
|
+
let i = M.parse(
|
|
384
|
+
await n.req.json()
|
|
340
385
|
);
|
|
341
|
-
const
|
|
342
|
-
adapters:
|
|
343
|
-
ctx:
|
|
386
|
+
const r = {
|
|
387
|
+
adapters: n.env.data,
|
|
388
|
+
ctx: n
|
|
344
389
|
};
|
|
345
|
-
(
|
|
346
|
-
const
|
|
347
|
-
return (
|
|
348
|
-
} catch (
|
|
349
|
-
throw
|
|
390
|
+
(o = e.tenants) != null && o.beforeCreate && (i = await e.tenants.beforeCreate(r, i));
|
|
391
|
+
const u = await n.env.data.tenants.create(i);
|
|
392
|
+
return (d = e.tenants) != null && d.afterCreate && await e.tenants.afterCreate(r, u), n.json(u, 201);
|
|
393
|
+
} catch (i) {
|
|
394
|
+
throw i instanceof P.ZodError ? new p(400, {
|
|
350
395
|
message: "Validation error",
|
|
351
|
-
cause:
|
|
352
|
-
}) :
|
|
396
|
+
cause: i
|
|
397
|
+
}) : i instanceof Error && ("code" in i && i.code === "SQLITE_CONSTRAINT_PRIMARYKEY" || (c = i.message) != null && c.includes("UNIQUE constraint failed")) ? new p(409, {
|
|
353
398
|
message: "Tenant with this ID already exists"
|
|
354
|
-
}) :
|
|
399
|
+
}) : i;
|
|
355
400
|
}
|
|
356
|
-
}), s.patch("/:id", async (
|
|
357
|
-
var m,
|
|
358
|
-
const
|
|
359
|
-
if (await ((m = e.onTenantAccessValidation) == null ? void 0 : m.call(e,
|
|
360
|
-
throw new
|
|
401
|
+
}), s.patch("/:id", async (n) => {
|
|
402
|
+
var m, T, _;
|
|
403
|
+
const t = n.req.param("id");
|
|
404
|
+
if (await ((m = e.onTenantAccessValidation) == null ? void 0 : m.call(e, n, t)) === !1)
|
|
405
|
+
throw new p(403, {
|
|
361
406
|
message: "Access denied to update this tenant"
|
|
362
407
|
});
|
|
363
|
-
const
|
|
364
|
-
if (!await
|
|
365
|
-
throw new
|
|
408
|
+
const d = M.partial().parse(await n.req.json()), { id: c, ...i } = d;
|
|
409
|
+
if (!await n.env.data.tenants.get(t))
|
|
410
|
+
throw new p(404, {
|
|
366
411
|
message: "Tenant not found"
|
|
367
412
|
});
|
|
368
|
-
const
|
|
369
|
-
adapters:
|
|
370
|
-
ctx:
|
|
413
|
+
const u = {
|
|
414
|
+
adapters: n.env.data,
|
|
415
|
+
ctx: n
|
|
371
416
|
};
|
|
372
|
-
let
|
|
373
|
-
(
|
|
374
|
-
const
|
|
375
|
-
if (!
|
|
376
|
-
throw new
|
|
417
|
+
let f = i;
|
|
418
|
+
(T = e.tenants) != null && T.beforeUpdate && (f = await e.tenants.beforeUpdate(u, t, i)), await n.env.data.tenants.update(t, f);
|
|
419
|
+
const l = await n.env.data.tenants.get(t);
|
|
420
|
+
if (!l)
|
|
421
|
+
throw new p(404, {
|
|
377
422
|
message: "Tenant not found after update"
|
|
378
423
|
});
|
|
379
|
-
return (
|
|
380
|
-
}), s.delete("/:id", async (
|
|
381
|
-
var c,
|
|
382
|
-
const
|
|
383
|
-
if (a.accessControl &&
|
|
384
|
-
throw new
|
|
424
|
+
return (_ = e.tenants) != null && _.afterUpdate && await e.tenants.afterUpdate(u, l), n.json(l);
|
|
425
|
+
}), s.delete("/:id", async (n) => {
|
|
426
|
+
var c, i, r;
|
|
427
|
+
const t = n.req.param("id");
|
|
428
|
+
if (a.accessControl && t === a.accessControl.mainTenantId)
|
|
429
|
+
throw new p(400, {
|
|
385
430
|
message: "Cannot delete the main tenant"
|
|
386
431
|
});
|
|
387
432
|
if (a.accessControl && await ((c = e.onTenantAccessValidation) == null ? void 0 : c.call(
|
|
388
433
|
e,
|
|
389
|
-
|
|
434
|
+
n,
|
|
390
435
|
a.accessControl.mainTenantId
|
|
391
436
|
)) === !1)
|
|
392
|
-
throw new
|
|
437
|
+
throw new p(403, {
|
|
393
438
|
message: "Access denied to delete tenants"
|
|
394
439
|
});
|
|
395
|
-
if (!await
|
|
396
|
-
throw new
|
|
440
|
+
if (!await n.env.data.tenants.get(t))
|
|
441
|
+
throw new p(404, {
|
|
397
442
|
message: "Tenant not found"
|
|
398
443
|
});
|
|
399
|
-
const
|
|
400
|
-
adapters:
|
|
401
|
-
ctx:
|
|
444
|
+
const d = {
|
|
445
|
+
adapters: n.env.data,
|
|
446
|
+
ctx: n
|
|
402
447
|
};
|
|
403
|
-
return (
|
|
448
|
+
return (i = e.tenants) != null && i.beforeDelete && await e.tenants.beforeDelete(d, t), await n.env.data.tenants.remove(t), (r = e.tenants) != null && r.afterDelete && await e.tenants.afterDelete(d, t), n.body(null, 204);
|
|
404
449
|
}), s;
|
|
405
450
|
}
|
|
406
|
-
function
|
|
451
|
+
function L(a) {
|
|
452
|
+
const e = [
|
|
453
|
+
{
|
|
454
|
+
pattern: /\/api\/v2\/resource-servers\/([^/]+)$/,
|
|
455
|
+
type: "resource_server"
|
|
456
|
+
},
|
|
457
|
+
{ pattern: /\/api\/v2\/roles\/([^/]+)$/, type: "role" },
|
|
458
|
+
{ pattern: /\/api\/v2\/connections\/([^/]+)$/, type: "connection" }
|
|
459
|
+
];
|
|
460
|
+
for (const { pattern: s, type: n } of e) {
|
|
461
|
+
const t = a.match(s);
|
|
462
|
+
if (t && t[1])
|
|
463
|
+
return { type: n, id: t[1] };
|
|
464
|
+
}
|
|
465
|
+
return null;
|
|
466
|
+
}
|
|
467
|
+
async function Y(a, e, s) {
|
|
468
|
+
try {
|
|
469
|
+
switch (s.type) {
|
|
470
|
+
case "resource_server": {
|
|
471
|
+
const n = await a.resourceServers.get(e, s.id);
|
|
472
|
+
return (n == null ? void 0 : n.is_system) === !0;
|
|
473
|
+
}
|
|
474
|
+
case "role": {
|
|
475
|
+
const n = await a.roles.get(e, s.id);
|
|
476
|
+
return (n == null ? void 0 : n.is_system) === !0;
|
|
477
|
+
}
|
|
478
|
+
case "connection": {
|
|
479
|
+
const n = await a.connections.get(e, s.id);
|
|
480
|
+
return (n == null ? void 0 : n.is_system) === !0;
|
|
481
|
+
}
|
|
482
|
+
default:
|
|
483
|
+
return !1;
|
|
484
|
+
}
|
|
485
|
+
} catch {
|
|
486
|
+
return !1;
|
|
487
|
+
}
|
|
488
|
+
}
|
|
489
|
+
function B(a) {
|
|
490
|
+
return {
|
|
491
|
+
resource_server: "resource server",
|
|
492
|
+
role: "role",
|
|
493
|
+
connection: "connection"
|
|
494
|
+
}[a];
|
|
495
|
+
}
|
|
496
|
+
function Z() {
|
|
497
|
+
return async (a, e) => {
|
|
498
|
+
if (!["PATCH", "PUT", "DELETE"].includes(a.req.method))
|
|
499
|
+
return e();
|
|
500
|
+
const s = L(a.req.path);
|
|
501
|
+
if (!s)
|
|
502
|
+
return e();
|
|
503
|
+
const n = a.var.tenant_id || a.req.header("x-tenant-id") || a.req.header("tenant-id");
|
|
504
|
+
if (!n)
|
|
505
|
+
return e();
|
|
506
|
+
if (await Y(a.env.data, n, s))
|
|
507
|
+
throw new p(403, {
|
|
508
|
+
message: `This ${B(s.type)} is a system resource and cannot be modified. Make changes in the main tenant instead.`
|
|
509
|
+
});
|
|
510
|
+
return e();
|
|
511
|
+
};
|
|
512
|
+
}
|
|
513
|
+
function G(a) {
|
|
407
514
|
return async (e, s) => {
|
|
408
515
|
if (!a.accessControl)
|
|
409
516
|
return s();
|
|
410
|
-
const
|
|
411
|
-
if (!
|
|
412
|
-
throw new
|
|
517
|
+
const n = e.var.tenant_id, t = e.var.organization_id;
|
|
518
|
+
if (!n)
|
|
519
|
+
throw new p(400, {
|
|
413
520
|
message: "Tenant ID not found in request"
|
|
414
521
|
});
|
|
415
|
-
if (!
|
|
416
|
-
n,
|
|
522
|
+
if (!K(
|
|
417
523
|
t,
|
|
524
|
+
n,
|
|
418
525
|
a.accessControl.mainTenantId
|
|
419
526
|
))
|
|
420
|
-
throw new
|
|
421
|
-
message: `Access denied to tenant ${
|
|
527
|
+
throw new p(403, {
|
|
528
|
+
message: `Access denied to tenant ${n}`
|
|
422
529
|
});
|
|
423
530
|
return s();
|
|
424
531
|
};
|
|
425
532
|
}
|
|
426
|
-
function
|
|
533
|
+
function J(a) {
|
|
427
534
|
return async (e, s) => {
|
|
428
535
|
if (!a.subdomainRouting)
|
|
429
536
|
return s();
|
|
430
537
|
const {
|
|
431
|
-
baseDomain:
|
|
432
|
-
reservedSubdomains:
|
|
433
|
-
resolveSubdomain:
|
|
434
|
-
} = a.subdomainRouting,
|
|
538
|
+
baseDomain: n,
|
|
539
|
+
reservedSubdomains: t = [],
|
|
540
|
+
resolveSubdomain: o
|
|
541
|
+
} = a.subdomainRouting, d = e.req.header("host") || "";
|
|
435
542
|
let c = null;
|
|
436
|
-
if (
|
|
437
|
-
const
|
|
438
|
-
|
|
543
|
+
if (d.endsWith(n)) {
|
|
544
|
+
const r = d.slice(0, -(n.length + 1));
|
|
545
|
+
r && !r.includes(".") && (c = r);
|
|
439
546
|
}
|
|
440
|
-
if (c &&
|
|
547
|
+
if (c && t.includes(c) && (c = null), !c)
|
|
441
548
|
return a.accessControl && e.set("tenant_id", a.accessControl.mainTenantId), s();
|
|
442
|
-
let
|
|
443
|
-
if (
|
|
444
|
-
|
|
549
|
+
let i = null;
|
|
550
|
+
if (o)
|
|
551
|
+
i = await o(c);
|
|
445
552
|
else if (a.subdomainRouting.useOrganizations !== !1 && a.accessControl)
|
|
446
553
|
try {
|
|
447
|
-
const
|
|
554
|
+
const r = await e.env.data.organizations.get(
|
|
448
555
|
a.accessControl.mainTenantId,
|
|
449
556
|
c
|
|
450
557
|
);
|
|
451
|
-
|
|
558
|
+
r && (i = r.id);
|
|
452
559
|
} catch {
|
|
453
560
|
}
|
|
454
|
-
if (!
|
|
455
|
-
throw new
|
|
561
|
+
if (!i)
|
|
562
|
+
throw new p(404, {
|
|
456
563
|
message: `Tenant not found for subdomain: ${c}`
|
|
457
564
|
});
|
|
458
|
-
return e.set("tenant_id",
|
|
565
|
+
return e.set("tenant_id", i), s();
|
|
459
566
|
};
|
|
460
567
|
}
|
|
461
|
-
function
|
|
568
|
+
function X(a) {
|
|
462
569
|
return async (e, s) => {
|
|
463
570
|
if (!a.databaseIsolation)
|
|
464
571
|
return s();
|
|
465
|
-
const
|
|
466
|
-
if (!
|
|
467
|
-
throw new
|
|
572
|
+
const n = e.var.tenant_id;
|
|
573
|
+
if (!n)
|
|
574
|
+
throw new p(400, {
|
|
468
575
|
message: "Tenant ID not found in request"
|
|
469
576
|
});
|
|
470
577
|
try {
|
|
471
|
-
const
|
|
472
|
-
e.env.data =
|
|
473
|
-
} catch (
|
|
578
|
+
const t = await a.databaseIsolation.getAdapters(n);
|
|
579
|
+
e.env.data = t;
|
|
580
|
+
} catch (t) {
|
|
474
581
|
throw console.error(
|
|
475
|
-
`Failed to resolve database for tenant ${
|
|
476
|
-
|
|
477
|
-
), new
|
|
582
|
+
`Failed to resolve database for tenant ${n}:`,
|
|
583
|
+
t
|
|
584
|
+
), new p(500, {
|
|
478
585
|
message: "Failed to resolve tenant database"
|
|
479
586
|
});
|
|
480
587
|
}
|
|
481
588
|
return s();
|
|
482
589
|
};
|
|
483
590
|
}
|
|
484
|
-
function
|
|
485
|
-
const e =
|
|
486
|
-
return async (
|
|
487
|
-
}), await s(
|
|
488
|
-
}), await t
|
|
489
|
-
}),
|
|
591
|
+
function D(a) {
|
|
592
|
+
const e = J(a), s = G(a), n = X(a);
|
|
593
|
+
return async (t, o) => (await e(t, async () => {
|
|
594
|
+
}), await s(t, async () => {
|
|
595
|
+
}), await n(t, async () => {
|
|
596
|
+
}), o());
|
|
490
597
|
}
|
|
491
|
-
function
|
|
492
|
-
const e =
|
|
598
|
+
function ne(a) {
|
|
599
|
+
const e = A(a);
|
|
493
600
|
return {
|
|
494
601
|
name: "multi-tenancy",
|
|
495
602
|
// Apply multi-tenancy middleware for subdomain routing, database resolution, etc.
|
|
496
|
-
middleware:
|
|
603
|
+
middleware: D(a),
|
|
497
604
|
// Provide lifecycle hooks
|
|
498
605
|
hooks: e,
|
|
499
606
|
// Mount tenant management routes
|
|
500
607
|
routes: [
|
|
501
608
|
{
|
|
502
609
|
path: "/management",
|
|
503
|
-
handler:
|
|
610
|
+
handler: S(a, e)
|
|
504
611
|
}
|
|
505
612
|
],
|
|
506
613
|
// Called when plugin is registered
|
|
@@ -513,40 +620,157 @@ function W(a) {
|
|
|
513
620
|
}
|
|
514
621
|
};
|
|
515
622
|
}
|
|
516
|
-
function
|
|
517
|
-
const e = a.accessControl ?
|
|
623
|
+
function A(a) {
|
|
624
|
+
const e = a.accessControl ? U(a.accessControl) : {}, s = a.databaseIsolation ? V(a.databaseIsolation) : {}, n = O(a);
|
|
518
625
|
return {
|
|
519
626
|
...e,
|
|
520
627
|
...s,
|
|
521
|
-
tenants:
|
|
628
|
+
tenants: n
|
|
522
629
|
};
|
|
523
630
|
}
|
|
524
|
-
function
|
|
525
|
-
const e = new
|
|
526
|
-
return e.route("/tenants",
|
|
631
|
+
function H(a) {
|
|
632
|
+
const e = new $(), s = A(a);
|
|
633
|
+
return e.route("/tenants", S(a, s)), e;
|
|
527
634
|
}
|
|
528
|
-
function
|
|
635
|
+
function se(a) {
|
|
529
636
|
return {
|
|
530
|
-
hooks:
|
|
531
|
-
middleware:
|
|
532
|
-
app:
|
|
637
|
+
hooks: A(a),
|
|
638
|
+
middleware: D(a),
|
|
639
|
+
app: H(a),
|
|
533
640
|
config: a
|
|
534
641
|
};
|
|
535
642
|
}
|
|
643
|
+
function re(a) {
|
|
644
|
+
const {
|
|
645
|
+
mainTenantId: e = "main",
|
|
646
|
+
syncResourceServers: s = !0,
|
|
647
|
+
multiTenancy: n,
|
|
648
|
+
entityHooks: t,
|
|
649
|
+
...o
|
|
650
|
+
} = a, d = {
|
|
651
|
+
...n,
|
|
652
|
+
accessControl: {
|
|
653
|
+
mainTenantId: e,
|
|
654
|
+
requireOrganizationMatch: !1,
|
|
655
|
+
defaultPermissions: ["tenant:admin"],
|
|
656
|
+
...n == null ? void 0 : n.accessControl
|
|
657
|
+
}
|
|
658
|
+
}, c = A(d);
|
|
659
|
+
let i, r;
|
|
660
|
+
s && (i = W({
|
|
661
|
+
mainTenantId: e,
|
|
662
|
+
getChildTenantIds: async () => (await q(
|
|
663
|
+
(y) => a.dataAdapter.tenants.list(y),
|
|
664
|
+
"tenants",
|
|
665
|
+
{ cursorField: "id", pageSize: 100 }
|
|
666
|
+
)).filter((y) => y.id !== e).map((y) => y.id),
|
|
667
|
+
getAdapters: async (g) => a.dataAdapter
|
|
668
|
+
}), r = Q({
|
|
669
|
+
mainTenantId: e,
|
|
670
|
+
getMainTenantAdapters: async () => a.dataAdapter,
|
|
671
|
+
getAdapters: async (g) => a.dataAdapter
|
|
672
|
+
}));
|
|
673
|
+
const u = async (g, y, ...h) => {
|
|
674
|
+
const v = [];
|
|
675
|
+
if (g)
|
|
676
|
+
try {
|
|
677
|
+
await g(...h);
|
|
678
|
+
} catch (b) {
|
|
679
|
+
v.push(b instanceof Error ? b : new Error(String(b)));
|
|
680
|
+
}
|
|
681
|
+
if (y)
|
|
682
|
+
try {
|
|
683
|
+
await y(...h);
|
|
684
|
+
} catch (b) {
|
|
685
|
+
v.push(b instanceof Error ? b : new Error(String(b)));
|
|
686
|
+
}
|
|
687
|
+
if (v.length === 1)
|
|
688
|
+
throw v[0];
|
|
689
|
+
if (v.length > 1)
|
|
690
|
+
throw new AggregateError(
|
|
691
|
+
v,
|
|
692
|
+
`Multiple hook errors: ${v.map((b) => b.message).join("; ")}`
|
|
693
|
+
);
|
|
694
|
+
}, f = {
|
|
695
|
+
...t,
|
|
696
|
+
resourceServers: i ? {
|
|
697
|
+
...t == null ? void 0 : t.resourceServers,
|
|
698
|
+
afterCreate: async (g, y) => {
|
|
699
|
+
var h;
|
|
700
|
+
await u(
|
|
701
|
+
(h = t == null ? void 0 : t.resourceServers) == null ? void 0 : h.afterCreate,
|
|
702
|
+
i == null ? void 0 : i.afterCreate,
|
|
703
|
+
g,
|
|
704
|
+
y
|
|
705
|
+
);
|
|
706
|
+
},
|
|
707
|
+
afterUpdate: async (g, y, h) => {
|
|
708
|
+
var v;
|
|
709
|
+
await u(
|
|
710
|
+
(v = t == null ? void 0 : t.resourceServers) == null ? void 0 : v.afterUpdate,
|
|
711
|
+
i == null ? void 0 : i.afterUpdate,
|
|
712
|
+
g,
|
|
713
|
+
y,
|
|
714
|
+
h
|
|
715
|
+
);
|
|
716
|
+
},
|
|
717
|
+
afterDelete: async (g, y) => {
|
|
718
|
+
var h;
|
|
719
|
+
await u(
|
|
720
|
+
(h = t == null ? void 0 : t.resourceServers) == null ? void 0 : h.afterDelete,
|
|
721
|
+
i == null ? void 0 : i.afterDelete,
|
|
722
|
+
g,
|
|
723
|
+
y
|
|
724
|
+
);
|
|
725
|
+
}
|
|
726
|
+
} : t == null ? void 0 : t.resourceServers,
|
|
727
|
+
tenants: r ? {
|
|
728
|
+
...t == null ? void 0 : t.tenants,
|
|
729
|
+
afterCreate: async (g, y) => {
|
|
730
|
+
var h;
|
|
731
|
+
await u(
|
|
732
|
+
(h = t == null ? void 0 : t.tenants) == null ? void 0 : h.afterCreate,
|
|
733
|
+
r == null ? void 0 : r.afterCreate,
|
|
734
|
+
g,
|
|
735
|
+
y
|
|
736
|
+
);
|
|
737
|
+
}
|
|
738
|
+
} : t == null ? void 0 : t.tenants
|
|
739
|
+
}, l = z({
|
|
740
|
+
...o,
|
|
741
|
+
entityHooks: f
|
|
742
|
+
}), { app: m, managementApp: T, ..._ } = l, w = new $();
|
|
743
|
+
w.use("/api/v2/*", Z()), w.route("/", m);
|
|
744
|
+
const I = S(
|
|
745
|
+
d,
|
|
746
|
+
c
|
|
747
|
+
);
|
|
748
|
+
return w.route("/api/v2/tenants", I), {
|
|
749
|
+
app: w,
|
|
750
|
+
managementApp: T,
|
|
751
|
+
..._,
|
|
752
|
+
multiTenancyConfig: d,
|
|
753
|
+
multiTenancyHooks: c
|
|
754
|
+
};
|
|
755
|
+
}
|
|
536
756
|
export {
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
757
|
+
U as createAccessControlHooks,
|
|
758
|
+
G as createAccessControlMiddleware,
|
|
759
|
+
V as createDatabaseHooks,
|
|
760
|
+
X as createDatabaseMiddleware,
|
|
761
|
+
H as createMultiTenancy,
|
|
762
|
+
A as createMultiTenancyHooks,
|
|
763
|
+
D as createMultiTenancyMiddleware,
|
|
764
|
+
ne as createMultiTenancyPlugin,
|
|
765
|
+
Z as createProtectSyncedMiddleware,
|
|
766
|
+
O as createProvisioningHooks,
|
|
767
|
+
W as createResourceServerSyncHooks,
|
|
768
|
+
J as createSubdomainMiddleware,
|
|
548
769
|
Q as createTenantResourceServerSyncHooks,
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
770
|
+
S as createTenantsRouter,
|
|
771
|
+
q as fetchAll,
|
|
772
|
+
re as init,
|
|
773
|
+
ce as seed,
|
|
774
|
+
se as setupMultiTenancy,
|
|
775
|
+
K as validateTenantAccess
|
|
552
776
|
};
|