@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.
@@ -1,27 +1,29 @@
1
- var h = Object.defineProperty;
2
- var v = (a, e, s) => e in a ? h(a, e, { enumerable: !0, configurable: !0, writable: !0, value: s }) : a[e] = s;
3
- var _ = (a, e, s) => v(a, typeof e != "symbol" ? e + "" : e, s);
4
- import { Hono as b } from "hono";
5
- import { z as $ } from "zod";
6
- import { auth0QuerySchema as R, tenantInsertSchema as T } from "@authhero/adapter-interfaces";
7
- function D(a) {
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(t, n) {
11
- if (n === e)
12
+ async onTenantAccessValidation(n, t) {
13
+ if (t === e)
12
14
  return !0;
13
15
  if (s) {
14
- const r = t.var.organization_id;
15
- return r ? r === n : !1;
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 M(a, e, s) {
23
+ function K(a, e, s) {
22
24
  return e === s ? !0 : a ? a === e : !1;
23
25
  }
24
- function I(a) {
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 z(a) {
41
+ function O(a) {
40
42
  return {
41
43
  async afterCreate(e, s) {
42
- const { accessControl: t, databaseIsolation: n, settingsInheritance: r } = a;
43
- t && e.ctx && await F(e, s, t), n != null && n.onProvision && await n.onProvision(s.id), (r == null ? void 0 : r.inheritFromMain) !== !1 && e.ctx && await q(e, s, a);
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: t, databaseIsolation: n } = a;
47
- if (t)
48
+ const { accessControl: n, databaseIsolation: t } = a;
49
+ if (n)
48
50
  try {
49
- const l = (await e.adapters.organizations.list(
50
- t.mainTenantId
51
+ const d = (await e.adapters.organizations.list(
52
+ n.mainTenantId
51
53
  )).organizations.find((c) => c.name === s);
52
- l && await e.adapters.organizations.remove(
53
- t.mainTenantId,
54
- l.id
54
+ d && await e.adapters.organizations.remove(
55
+ n.mainTenantId,
56
+ d.id
55
57
  );
56
- } catch (r) {
58
+ } catch (o) {
57
59
  console.warn(
58
60
  `Failed to remove organization for tenant ${s}:`,
59
- r
61
+ o
60
62
  );
61
63
  }
62
- if (n != null && n.onDeprovision)
64
+ if (t != null && t.onDeprovision)
63
65
  try {
64
- await n.onDeprovision(s);
65
- } catch (r) {
66
+ await t.onDeprovision(s);
67
+ } catch (o) {
66
68
  console.warn(
67
69
  `Failed to deprovision database for tenant ${s}:`,
68
- r
70
+ o
69
71
  );
70
72
  }
71
73
  }
72
74
  };
73
75
  }
74
- async function F(a, e, s) {
75
- const { mainTenantId: t, defaultPermissions: n, defaultRoles: r } = s;
76
- await a.adapters.organizations.create(t, {
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
- }), r && r.length > 0 && console.log(
81
- `Would assign roles ${r.join(", ")} to organization ${e.id}`
82
- ), n && n.length > 0 && console.log(
83
- `Would grant permissions ${n.join(", ")} to organization ${e.id}`
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 q(a, e, s) {
87
- const { accessControl: t, settingsInheritance: n } = s;
88
- if (!t)
88
+ async function E(a, e, s) {
89
+ const { accessControl: n, settingsInheritance: t } = s;
90
+ if (!n)
89
91
  return;
90
- const r = await a.adapters.tenants.get(t.mainTenantId);
91
- if (!r)
92
+ const o = await a.adapters.tenants.get(n.mainTenantId);
93
+ if (!o)
92
94
  return;
93
- let l = { ...r };
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 o of c)
105
- delete l[o];
106
- if (n != null && n.inheritedKeys) {
107
- const o = {};
108
- for (const i of n.inheritedKeys)
109
- i in r && !c.includes(i) && (o[i] = r[i]);
110
- l = o;
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 (n != null && n.excludedKeys)
113
- for (const o of n.excludedKeys)
114
- delete l[o];
115
- n != null && n.transformSettings && (l = n.transformSettings(
116
- l,
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(l).length > 0 && await a.adapters.tenants.update(e.id, l);
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 N(a) {
163
+ function W(a) {
121
164
  const {
122
165
  mainTenantId: e,
123
166
  getChildTenantIds: s,
124
- getAdapters: t,
125
- shouldSync: n = () => !0,
126
- transformForSync: r
167
+ getAdapters: n,
168
+ shouldSync: t = () => !0,
169
+ transformForSync: o
127
170
  } = a;
128
- async function l(i, f, d) {
129
- return (await i.resourceServers.list(f, {
130
- q: `identifier:${d}`,
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(i, f) {
135
- const d = await s();
177
+ async function c(r, u) {
178
+ const f = await s();
136
179
  await Promise.all(
137
- d.map(async (u) => {
180
+ f.map(async (l) => {
138
181
  try {
139
- const m = await t(u), p = r ? r(i, u) : {
140
- name: i.name,
141
- identifier: i.identifier,
142
- scopes: i.scopes,
143
- signing_alg: i.signing_alg,
144
- signing_secret: i.signing_secret,
145
- token_lifetime: i.token_lifetime,
146
- token_lifetime_for_web: i.token_lifetime_for_web,
147
- skip_consent_for_verifiable_first_party_clients: i.skip_consent_for_verifiable_first_party_clients,
148
- allow_offline_access: i.allow_offline_access,
149
- verificationKey: i.verificationKey,
150
- options: i.options
151
- };
152
- if (f === "create") {
153
- const y = await l(
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
- u,
156
- i.identifier
198
+ l,
199
+ r.identifier
157
200
  );
158
- y && y.id ? await m.resourceServers.update(
159
- u,
160
- y.id,
161
- p
162
- ) : await m.resourceServers.create(u, p);
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 y = await l(
207
+ const w = await d(
165
208
  m,
166
- u,
167
- i.identifier
209
+ l,
210
+ r.identifier
168
211
  );
169
- y && y.id && await m.resourceServers.update(
170
- u,
171
- y.id,
172
- p
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 "${i.identifier}" to tenant "${u}":`,
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 o(i) {
185
- const f = await s();
227
+ async function i(r) {
228
+ const u = await s();
186
229
  await Promise.all(
187
- f.map(async (d) => {
230
+ u.map(async (f) => {
188
231
  try {
189
- const u = await t(d), m = await l(
190
- u,
191
- d,
192
- i
232
+ const l = await n(f), m = await d(
233
+ l,
234
+ f,
235
+ r
193
236
  );
194
- m && m.id && await u.resourceServers.remove(d, m.id);
195
- } catch (u) {
237
+ m && m.id && await l.resourceServers.remove(f, m.id);
238
+ } catch (l) {
196
239
  console.error(
197
- `Failed to delete resource server "${i}" from tenant "${d}":`,
198
- u
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 (i, f) => {
206
- i.tenantId === e && n(f) && await c(f, "create");
248
+ afterCreate: async (r, u) => {
249
+ r.tenantId === e && t(u) && await c(u, "create");
207
250
  },
208
- afterUpdate: async (i, f, d) => {
209
- i.tenantId === e && n(d) && await c(d, "update");
251
+ afterUpdate: async (r, u, f) => {
252
+ r.tenantId === e && t(f) && await c(f, "update");
210
253
  },
211
- afterDelete: async (i, f) => {
212
- i.tenantId === e && await o(f);
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: t,
221
- shouldSync: n = () => !0,
222
- transformForSync: r
263
+ getAdapters: n,
264
+ shouldSync: t = () => !0,
265
+ transformForSync: o
223
266
  } = a;
224
267
  return {
225
- async afterCreate(l, c) {
268
+ async afterCreate(d, c) {
226
269
  if (c.id !== e)
227
270
  try {
228
- const o = await s(), i = await t(c.id), f = await o.resourceServers.list(e, {
229
- per_page: 100
230
- // Adjust if you expect more resource servers
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
- f.resource_servers.filter((d) => n(d)).map(async (d) => {
277
+ u.filter((f) => t(f)).map(async (f) => {
278
+ const l = f;
234
279
  try {
235
- const u = r ? r(d, c.id) : {
236
- name: d.name,
237
- identifier: d.identifier,
238
- scopes: d.scopes,
239
- signing_alg: d.signing_alg,
240
- signing_secret: d.signing_secret,
241
- token_lifetime: d.token_lifetime,
242
- token_lifetime_for_web: d.token_lifetime_for_web,
243
- skip_consent_for_verifiable_first_party_clients: d.skip_consent_for_verifiable_first_party_clients,
244
- allow_offline_access: d.allow_offline_access,
245
- verificationKey: d.verificationKey,
246
- options: d.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 i.resourceServers.create(
249
- c.id,
250
- u
251
- );
252
- } catch (u) {
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 "${d.identifier}" to new tenant "${c.id}":`,
255
- u
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 (o) {
305
+ } catch (i) {
261
306
  console.error(
262
307
  `Failed to sync resource servers to new tenant "${c.id}":`,
263
- o
308
+ i
264
309
  );
265
310
  }
266
311
  }
267
312
  };
268
313
  }
269
- var w = class extends Error {
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
- _(this, "res");
278
- _(this, "status");
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 C(a, e) {
296
- const s = new b();
297
- return s.get("/", async (t) => {
298
- var f;
299
- if (a.accessControl && await ((f = e.onTenantAccessValidation) == null ? void 0 : f.call(
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
- t,
346
+ n,
302
347
  a.accessControl.mainTenantId
303
348
  )) === !1)
304
- throw new w(403, {
349
+ throw new p(403, {
305
350
  message: "Access denied to tenant management"
306
351
  });
307
- const n = R.parse(t.req.query()), { page: r, per_page: l, include_totals: c, q: o } = n, i = await t.env.data.tenants.list({
308
- page: r,
309
- per_page: l,
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: o
356
+ q: i
312
357
  });
313
- return c ? t.json(i) : t.json(i.tenants);
314
- }), s.get("/:id", async (t) => {
358
+ return c ? n.json(r) : n.json(r.tenants);
359
+ }), s.get("/:id", async (n) => {
315
360
  var c;
316
- const n = t.req.param("id");
317
- if (await ((c = e.onTenantAccessValidation) == null ? void 0 : c.call(e, t, n)) === !1)
318
- throw new w(403, {
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 l = await t.env.data.tenants.get(n);
322
- if (!l)
323
- throw new w(404, {
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 t.json(l);
327
- }), s.post("/", async (t) => {
328
- var n, r, l, c;
371
+ return n.json(d);
372
+ }), s.post("/", async (n) => {
373
+ var t, o, d, c;
329
374
  try {
330
- if (a.accessControl && await ((n = e.onTenantAccessValidation) == null ? void 0 : n.call(
375
+ if (a.accessControl && await ((t = e.onTenantAccessValidation) == null ? void 0 : t.call(
331
376
  e,
332
- t,
377
+ n,
333
378
  a.accessControl.mainTenantId
334
379
  )) === !1)
335
- throw new w(403, {
380
+ throw new p(403, {
336
381
  message: "Access denied to create tenants"
337
382
  });
338
- let o = T.parse(
339
- await t.req.json()
383
+ let i = M.parse(
384
+ await n.req.json()
340
385
  );
341
- const i = {
342
- adapters: t.env.data,
343
- ctx: t
386
+ const r = {
387
+ adapters: n.env.data,
388
+ ctx: n
344
389
  };
345
- (r = e.tenants) != null && r.beforeCreate && (o = await e.tenants.beforeCreate(i, o));
346
- const f = await t.env.data.tenants.create(o);
347
- return (l = e.tenants) != null && l.afterCreate && await e.tenants.afterCreate(i, f), t.json(f, 201);
348
- } catch (o) {
349
- throw o instanceof $.ZodError ? new w(400, {
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: o
352
- }) : o instanceof Error && ("code" in o && o.code === "SQLITE_CONSTRAINT_PRIMARYKEY" || (c = o.message) != null && c.includes("UNIQUE constraint failed")) ? new w(409, {
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
- }) : o;
399
+ }) : i;
355
400
  }
356
- }), s.patch("/:id", async (t) => {
357
- var m, p, y;
358
- const n = t.req.param("id");
359
- if (await ((m = e.onTenantAccessValidation) == null ? void 0 : m.call(e, t, n)) === !1)
360
- throw new w(403, {
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 l = T.partial().parse(await t.req.json()), { id: c, ...o } = l;
364
- if (!await t.env.data.tenants.get(n))
365
- throw new w(404, {
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 f = {
369
- adapters: t.env.data,
370
- ctx: t
413
+ const u = {
414
+ adapters: n.env.data,
415
+ ctx: n
371
416
  };
372
- let d = o;
373
- (p = e.tenants) != null && p.beforeUpdate && (d = await e.tenants.beforeUpdate(f, n, o)), await t.env.data.tenants.update(n, d);
374
- const u = await t.env.data.tenants.get(n);
375
- if (!u)
376
- throw new w(404, {
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 (y = e.tenants) != null && y.afterUpdate && await e.tenants.afterUpdate(f, u), t.json(u);
380
- }), s.delete("/:id", async (t) => {
381
- var c, o, i;
382
- const n = t.req.param("id");
383
- if (a.accessControl && n === a.accessControl.mainTenantId)
384
- throw new w(400, {
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
- t,
434
+ n,
390
435
  a.accessControl.mainTenantId
391
436
  )) === !1)
392
- throw new w(403, {
437
+ throw new p(403, {
393
438
  message: "Access denied to delete tenants"
394
439
  });
395
- if (!await t.env.data.tenants.get(n))
396
- throw new w(404, {
440
+ if (!await n.env.data.tenants.get(t))
441
+ throw new p(404, {
397
442
  message: "Tenant not found"
398
443
  });
399
- const l = {
400
- adapters: t.env.data,
401
- ctx: t
444
+ const d = {
445
+ adapters: n.env.data,
446
+ ctx: n
402
447
  };
403
- return (o = e.tenants) != null && o.beforeDelete && await e.tenants.beforeDelete(l, n), await t.env.data.tenants.remove(n), (i = e.tenants) != null && i.afterDelete && await e.tenants.afterDelete(l, n), t.body(null, 204);
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 H(a) {
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 t = e.var.tenant_id, n = e.var.organization_id;
411
- if (!t)
412
- throw new w(400, {
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 (!M(
416
- n,
522
+ if (!K(
417
523
  t,
524
+ n,
418
525
  a.accessControl.mainTenantId
419
526
  ))
420
- throw new w(403, {
421
- message: `Access denied to tenant ${t}`
527
+ throw new p(403, {
528
+ message: `Access denied to tenant ${n}`
422
529
  });
423
530
  return s();
424
531
  };
425
532
  }
426
- function j(a) {
533
+ function J(a) {
427
534
  return async (e, s) => {
428
535
  if (!a.subdomainRouting)
429
536
  return s();
430
537
  const {
431
- baseDomain: t,
432
- reservedSubdomains: n = [],
433
- resolveSubdomain: r
434
- } = a.subdomainRouting, l = e.req.header("host") || "";
538
+ baseDomain: n,
539
+ reservedSubdomains: t = [],
540
+ resolveSubdomain: o
541
+ } = a.subdomainRouting, d = e.req.header("host") || "";
435
542
  let c = null;
436
- if (l.endsWith(t)) {
437
- const i = l.slice(0, -(t.length + 1));
438
- i && !i.includes(".") && (c = i);
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 && n.includes(c) && (c = null), !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 o = null;
443
- if (r)
444
- o = await r(c);
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 i = await e.env.data.organizations.get(
554
+ const r = await e.env.data.organizations.get(
448
555
  a.accessControl.mainTenantId,
449
556
  c
450
557
  );
451
- i && (o = i.id);
558
+ r && (i = r.id);
452
559
  } catch {
453
560
  }
454
- if (!o)
455
- throw new w(404, {
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", o), s();
565
+ return e.set("tenant_id", i), s();
459
566
  };
460
567
  }
461
- function P(a) {
568
+ function X(a) {
462
569
  return async (e, s) => {
463
570
  if (!a.databaseIsolation)
464
571
  return s();
465
- const t = e.var.tenant_id;
466
- if (!t)
467
- throw new w(400, {
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 n = await a.databaseIsolation.getAdapters(t);
472
- e.env.data = n;
473
- } catch (n) {
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 ${t}:`,
476
- n
477
- ), new w(500, {
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 A(a) {
485
- const e = j(a), s = H(a), t = P(a);
486
- return async (n, r) => (await e(n, async () => {
487
- }), await s(n, async () => {
488
- }), await t(n, async () => {
489
- }), r());
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 W(a) {
492
- const e = g(a);
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: A(a),
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: C(a, e)
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 g(a) {
517
- const e = a.accessControl ? D(a.accessControl) : {}, s = a.databaseIsolation ? I(a.databaseIsolation) : {}, t = z(a);
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: t
628
+ tenants: n
522
629
  };
523
630
  }
524
- function K(a) {
525
- const e = new b(), s = g(a);
526
- return e.route("/tenants", C(a, s)), e;
631
+ function H(a) {
632
+ const e = new $(), s = A(a);
633
+ return e.route("/tenants", S(a, s)), e;
527
634
  }
528
- function Y(a) {
635
+ function se(a) {
529
636
  return {
530
- hooks: g(a),
531
- middleware: A(a),
532
- app: K(a),
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
- D as createAccessControlHooks,
538
- H as createAccessControlMiddleware,
539
- I as createDatabaseHooks,
540
- P as createDatabaseMiddleware,
541
- K as createMultiTenancy,
542
- g as createMultiTenancyHooks,
543
- A as createMultiTenancyMiddleware,
544
- W as createMultiTenancyPlugin,
545
- z as createProvisioningHooks,
546
- N as createResourceServerSyncHooks,
547
- j as createSubdomainMiddleware,
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
- C as createTenantsRouter,
550
- Y as setupMultiTenancy,
551
- M as validateTenantAccess
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
  };