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