@authhero/multi-tenancy 13.11.0 → 13.12.1

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 Z=Object.defineProperty;var H=(e,t,s)=>t in e?Z(e,t,{enumerable:!0,configurable:!0,writable:!0,value:s}):e[t]=s;var j=(e,t,s)=>H(e,typeof t!="symbol"?t+"":t,s);Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const N=require("hono"),b=require("authhero"),C=require("@hono/zod-openapi"),I=require("@authhero/adapter-interfaces");var v=class extends Error{constructor(t=500,s){super(s==null?void 0:s.message,{cause:s==null?void 0:s.cause});j(this,"res");j(this,"status");this.res=s==null?void 0:s.res,this.status=t}getResponse(){return this.res?new Response(this.res.body,{status:this.status,headers:this.res.headers}):new Response(this.message,{status:this.status})}};function U(e){const{controlPlaneTenantId:t,requireOrganizationMatch:s=!0}=e;return{async onTenantAccessValidation(a,i){if(i===t)return!0;if(s){const n=a.var.org_name,u=a.var.organization_id,l=n||u;return l?l===i:!1}return!0}}}function E(e,t,s,a){if(t===s)return!0;const i=a||e;return i?i===t:!1}function K(e){return{async resolveDataAdapters(t){try{return await e.getAdapters(t)}catch(s){console.error(`Failed to resolve data adapters for tenant ${t}:`,s);return}}}}function B(e){return{async beforeCreate(t,s){return!s.audience&&s.id?{...s,audience:b.getTenantAudience(s.id)}:s},async afterCreate(t,s){const{accessControl:a,databaseIsolation:i,settingsInheritance:n}=e;a&&t.ctx&&await x(t,s,a),i!=null&&i.onProvision&&await i.onProvision(s.id),(n==null?void 0:n.inheritFromControlPlane)!==!1&&t.ctx&&await te(t,s,e)},async beforeDelete(t,s){const{accessControl:a,databaseIsolation:i}=e;if(a)try{const u=(await t.adapters.organizations.list(a.controlPlaneTenantId)).organizations.find(l=>l.name===s);u&&await t.adapters.organizations.remove(a.controlPlaneTenantId,u.id)}catch(n){console.warn(`Failed to remove organization for tenant ${s}:`,n)}if(i!=null&&i.onDeprovision)try{await i.onDeprovision(s)}catch(n){console.warn(`Failed to deprovision database for tenant ${s}:`,n)}}}}async function x(e,t,s){const{controlPlaneTenantId:a,defaultPermissions:i,defaultRoles:n,issuer:u,adminRoleName:l="Tenant Admin",adminRoleDescription:c="Full access to all tenant management operations",addCreatorToOrganization:r=!0}=s,f=await e.adapters.organizations.create(a,{name:t.id,display_name:t.friendly_name||t.id});let d;if(u&&(d=await ee(e,a,l,c)),r&&e.ctx){const o=e.ctx.var.user;if(o!=null&&o.sub)try{await e.adapters.userOrganizations.create(a,{user_id:o.sub,organization_id:f.id}),d&&await e.adapters.userRoles.create(a,o.sub,d,f.id)}catch(p){console.warn(`Failed to add creator ${o.sub} to organization ${f.id}:`,p)}}n&&n.length>0&&console.log(`Would assign roles ${n.join(", ")} to organization ${f.id}`),i&&i.length>0&&console.log(`Would grant permissions ${i.join(", ")} to organization ${f.id}`)}async function ee(e,t,s,a){const n=(await e.adapters.roles.list(t,{})).roles.find(r=>r.name===s);if(n)return n.id;const u=await e.adapters.roles.create(t,{name:s,description:a}),l=b.MANAGEMENT_API_AUDIENCE,c=b.MANAGEMENT_API_SCOPES.map(r=>({role_id:u.id,resource_server_identifier:l,permission_name:r.value}));return await e.adapters.rolePermissions.assign(t,u.id,c),u.id}async function te(e,t,s){const{accessControl:a,settingsInheritance:i}=s;if(!a)return;const n=await e.adapters.tenants.get(a.controlPlaneTenantId);if(!n)return;let u={...n};const l=["id","created_at","updated_at","friendly_name","audience","sender_email","sender_name"];for(const c of l)delete u[c];if(i!=null&&i.inheritedKeys){const c={};for(const r of i.inheritedKeys)r in n&&!l.includes(r)&&(c[r]=n[r]);u=c}if(i!=null&&i.excludedKeys)for(const c of i.excludedKeys)delete u[c];i!=null&&i.transformSettings&&(u=i.transformSettings(u,t.id)),Object.keys(u).length>0&&await e.adapters.tenants.update(t.id,u)}function W(e){const{controlPlaneTenantId:t,getChildTenantIds:s,getAdapters:a,shouldSync:i=()=>!0,transformForSync:n}=e;async function u(r,f,d){return(await r.resourceServers.list(f,{q:`identifier:${d}`,per_page:1})).resource_servers[0]??null}async function l(r,f){const d=await s();await Promise.all(d.map(async o=>{try{const p=await a(o),h={...n?n(r,o):{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(f==="create"){const A=await u(p,o,r.identifier);A&&A.id?await p.resourceServers.update(o,A.id,h):await p.resourceServers.create(o,h)}else{const A=await u(p,o,r.identifier);A&&A.id?await p.resourceServers.update(o,A.id,h):await p.resourceServers.create(o,h)}}catch(p){console.error(`Failed to sync resource server "${r.identifier}" to tenant "${o}":`,p)}}))}async function c(r){const f=await s();await Promise.all(f.map(async d=>{try{const o=await a(d),p=await u(o,d,r);p&&p.id&&await o.resourceServers.remove(d,p.id)}catch(o){console.error(`Failed to delete resource server "${r}" from tenant "${d}":`,o)}}))}return{afterCreate:async(r,f)=>{r.tenantId===t&&i(f)&&await l(f,"create")},afterUpdate:async(r,f,d)=>{r.tenantId===t&&i(d)&&await l(d,"update")},afterDelete:async(r,f)=>{r.tenantId===t&&await c(f)}}}function G(e){const{controlPlaneTenantId:t,getControlPlaneAdapters:s,getAdapters:a,shouldSync:i=()=>!0,transformForSync:n}=e;return{async afterCreate(u,l){if(l.id!==t)try{const c=await s(),r=await a(l.id),f=await b.fetchAll(d=>c.resourceServers.list(t,d),"resource_servers",{cursorField:"id",pageSize:100});await Promise.all(f.filter(d=>i(d)).map(async d=>{const o=d;try{const p=n?n(o,l.id):{name:o.name,identifier:o.identifier,scopes:o.scopes,signing_alg:o.signing_alg,signing_secret:o.signing_secret,token_lifetime:o.token_lifetime,token_lifetime_for_web:o.token_lifetime_for_web,skip_consent_for_verifiable_first_party_clients:o.skip_consent_for_verifiable_first_party_clients,allow_offline_access:o.allow_offline_access,verificationKey:o.verificationKey,options:o.options};await r.resourceServers.create(l.id,{...p,is_system:!0})}catch(p){console.error(`Failed to sync resource server "${o.identifier}" to new tenant "${l.id}":`,p)}}))}catch(c){console.error(`Failed to sync resource servers to new tenant "${l.id}":`,c)}}}}function L(e){const{controlPlaneTenantId:t,getChildTenantIds:s,getAdapters:a,shouldSync:i=()=>!0,transformForSync:n}=e;async function u(c,r,f){return(await c.roles.list(r,{q:`name:${f}`,per_page:1})).roles[0]??null}async function l(c,r){const f=await s();await Promise.all(f.map(async d=>{try{const o=await a(d),g={...n?n(c,d):{name:c.name,description:c.description},is_system:!0};if(r==="create"){const h=await u(o,d,c.name);h&&h.id?await o.roles.update(d,h.id,g):await o.roles.create(d,g)}else{const h=await u(o,d,c.name);h&&h.id?await o.roles.update(d,h.id,g):await o.roles.create(d,g)}}catch(o){console.error(`Failed to sync role "${c.name}" to tenant "${d}":`,o)}}))}return{afterCreate:async(c,r)=>{c.tenantId===t&&i(r)&&await l(r,"create")},afterUpdate:async(c,r,f)=>{c.tenantId===t&&i(f)&&await l(f,"update")},afterDelete:async(c,r)=>{c.tenantId===t&&console.warn(`Role ${r} was deleted from control plane. Child tenant roles with matching names should be deleted manually or implement role name tracking.`)}}}function Q(e){const{controlPlaneTenantId:t,getControlPlaneAdapters:s,getAdapters:a,shouldSync:i=()=>!0,transformForSync:n,syncPermissions:u=!0}=e;return{async afterCreate(l,c){if(c.id!==t)try{const r=await s(),f=await a(c.id),d=await b.fetchAll(p=>r.roles.list(t,p),"roles",{cursorField:"id",pageSize:100}),o=new Map;if(await Promise.all(d.filter(p=>i(p)).map(async p=>{const g=p;try{const h=n?n(g,c.id):{name:g.name,description:g.description},A=await f.roles.create(c.id,{...h,is_system:!0});o.set(g.id,A.id)}catch(h){console.error(`Failed to sync role "${g.name}" to new tenant "${c.id}":`,h)}})),u)for(const[p,g]of o)try{const h=await r.rolePermissions.list(t,p,{});h.length>0&&await f.rolePermissions.assign(c.id,g,h.map(A=>({role_id:g,resource_server_identifier:A.resource_server_identifier,permission_name:A.permission_name})))}catch(h){console.error(`Failed to sync permissions for role to new tenant "${c.id}":`,h)}}catch(r){console.error(`Failed to sync roles to new tenant "${c.id}":`,r)}}}}function D(e,t){const s=new C.OpenAPIHono;return s.openapi(C.createRoute({tags:["tenants"],method:"get",path:"/",request:{query:I.auth0QuerySchema},security:[{Bearer:[]}],responses:{200:{content:{"application/json":{schema:C.z.object({tenants:C.z.array(I.tenantSchema),start:C.z.number().optional(),limit:C.z.number().optional(),length:C.z.number().optional()})}},description:"List of tenants"}}}),async a=>{var p,g,h,A;const i=a.req.valid("query"),{page:n,per_page:u,include_totals:l,q:c}=i,r=a.var.user,f=((r==null?void 0:r.scope)||"").split(" "),d=f.includes("auth:read");if(console.log("User scopes:",f,"hasAuthRead:",d),d){const S=await a.env.data.tenants.list({page:n,per_page:u,include_totals:l,q:c});return l?a.json({tenants:S.tenants,start:((p=S.totals)==null?void 0:p.start)??0,limit:((g=S.totals)==null?void 0:g.limit)??u,length:S.tenants.length}):a.json({tenants:S.tenants})}if(e.accessControl&&(r!=null&&r.sub)){const S=e.accessControl.controlPlaneTenantId,M=(await b.fetchAll(R=>a.env.data.userOrganizations.listUserOrganizations(S,r.sub,R),"organizations")).map(R=>R.name);if(M.length===0)return l?a.json({tenants:[],start:0,limit:u??50,length:0}):a.json({tenants:[]});const $=M.length,F=n??0,P=u??50,w=F*P,m=M.slice(w,w+P);if(m.length===0)return l?a.json({tenants:[],start:w,limit:P,length:$}):a.json({tenants:[]});const y=m.map(R=>`id:${R}`).join(" OR "),_=c?`(${y}) AND (${c})`:y,T=await a.env.data.tenants.list({q:_,per_page:P,include_totals:!1});return l?a.json({tenants:T.tenants,start:w,limit:P,length:$}):a.json({tenants:T.tenants})}const o=await a.env.data.tenants.list({page:n,per_page:u,include_totals:l,q:c});return l?a.json({tenants:o.tenants,start:((h=o.totals)==null?void 0:h.start)??0,limit:((A=o.totals)==null?void 0:A.limit)??u,length:o.tenants.length}):a.json({tenants:o.tenants})}),s.openapi(C.createRoute({tags:["tenants"],method:"post",path:"/",request:{body:{content:{"application/json":{schema:I.tenantInsertSchema}}}},security:[{Bearer:[]}],responses:{201:{content:{"application/json":{schema:I.tenantSchema}},description:"Tenant created"},400:{description:"Validation error"},409:{description:"Tenant with this ID already exists"}}}),async a=>{var c,r;const i=a.var.user;if(!(i!=null&&i.sub))throw new v(401,{message:"Authentication required to create tenants"});let n=a.req.valid("json");const u={adapters:a.env.data,ctx:a};(c=t.tenants)!=null&&c.beforeCreate&&(n=await t.tenants.beforeCreate(u,n));const l=await a.env.data.tenants.create(n);return(r=t.tenants)!=null&&r.afterCreate&&await t.tenants.afterCreate(u,l),a.json(l,201)}),s.openapi(C.createRoute({tags:["tenants"],method:"delete",path:"/{id}",request:{params:C.z.object({id:C.z.string()})},security:[{Bearer:["delete:tenants"]}],responses:{204:{description:"Tenant deleted"},403:{description:"Access denied or cannot delete the control plane"},404:{description:"Tenant not found"}}}),async a=>{var l,c;const{id:i}=a.req.valid("param");if(e.accessControl){const r=a.var.user,f=e.accessControl.controlPlaneTenantId;if(!(r!=null&&r.sub))throw new v(401,{message:"Authentication required"});if(i===f)throw new v(403,{message:"Cannot delete the control plane"});if(!(await b.fetchAll(p=>a.env.data.userOrganizations.listUserOrganizations(f,r.sub,p),"organizations")).some(p=>p.name===i))throw new v(403,{message:"Access denied to this tenant"})}if(!await a.env.data.tenants.get(i))throw new v(404,{message:"Tenant not found"});const u={adapters:a.env.data,ctx:a};return(l=t.tenants)!=null&&l.beforeDelete&&await t.tenants.beforeDelete(u,i),await a.env.data.tenants.remove(i),(c=t.tenants)!=null&&c.afterDelete&&await t.tenants.afterDelete(u,i),a.body(null,204)}),s}function ae(e){const t=[{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:a}of t){const i=e.match(s);if(i&&i[1])return{type:a,id:i[1]}}return null}async function ne(e,t,s){try{switch(s.type){case"resource_server":{const a=await e.resourceServers.get(t,s.id);return(a==null?void 0:a.is_system)===!0}case"role":{const a=await e.roles.get(t,s.id);return(a==null?void 0:a.is_system)===!0}case"connection":{const a=await e.connections.get(t,s.id);return(a==null?void 0:a.is_system)===!0}default:return!1}}catch{return!1}}function re(e){return{resource_server:"resource server",role:"role",connection:"connection"}[e]}function V(){return async(e,t)=>{if(!["PATCH","PUT","DELETE"].includes(e.req.method))return t();const s=ae(e.req.path);if(!s)return t();const a=e.var.tenant_id||e.req.header("x-tenant-id")||e.req.header("tenant-id");if(!a)return t();if(await ne(e.env.data,a,s))throw new v(403,{message:`This ${re(s.type)} is a system resource and cannot be modified. Make changes in the control plane instead.`});return t()}}function k(e){return async(t,s)=>{if(!e.accessControl)return s();const a=t.var.tenant_id,i=t.var.organization_id;if(!a)throw new v(400,{message:"Tenant ID not found in request"});if(!E(i,a,e.accessControl.controlPlaneTenantId))throw new v(403,{message:`Access denied to tenant ${a}`});return s()}}function J(e){return async(t,s)=>{if(!e.subdomainRouting)return s();const{baseDomain:a,reservedSubdomains:i=[],resolveSubdomain:n}=e.subdomainRouting,u=t.req.header("host")||"";let l=null;if(u.endsWith(a)){const r=u.slice(0,-(a.length+1));r&&!r.includes(".")&&(l=r)}if(l&&i.includes(l)&&(l=null),!l)return e.accessControl&&t.set("tenant_id",e.accessControl.controlPlaneTenantId),s();let c=null;if(n)c=await n(l);else if(e.subdomainRouting.useOrganizations!==!1&&e.accessControl)try{const r=await t.env.data.organizations.get(e.accessControl.controlPlaneTenantId,l);r&&(c=r.id)}catch{}if(!c)throw new v(404,{message:`Tenant not found for subdomain: ${l}`});return t.set("tenant_id",c),s()}}function X(e){return async(t,s)=>{if(!e.databaseIsolation)return s();const a=t.var.tenant_id;if(!a)throw new v(400,{message:"Tenant ID not found in request"});try{const i=await e.databaseIsolation.getAdapters(a);t.env.data=i}catch(i){throw console.error(`Failed to resolve database for tenant ${a}:`,i),new v(500,{message:"Failed to resolve tenant database"})}return s()}}function q(e){const t=J(e),s=k(e),a=X(e);return async(i,n)=>(await t(i,async()=>{}),await s(i,async()=>{}),await a(i,async()=>{}),n())}function se(e){const t=z(e);return{name:"multi-tenancy",middleware:q(e),hooks:t,routes:[{path:"/management",handler:D(e,t)}],onRegister:async()=>{console.log("Multi-tenancy plugin registered"),e.accessControl&&console.log(` - Access control enabled (control plane: ${e.accessControl.controlPlaneTenantId})`),e.subdomainRouting&&console.log(` - Subdomain routing enabled (base domain: ${e.subdomainRouting.baseDomain})`),e.databaseIsolation&&console.log(" - Database isolation enabled")}}}function z(e){const t=e.accessControl?U(e.accessControl):{},s=e.databaseIsolation?K(e.databaseIsolation):{},a=B(e);return{...t,...s,tenants:a}}function Y(e){const t=new N.Hono,s=z(e);return t.route("/tenants",D(e,s)),t}function ie(e){return{hooks:z(e),middleware:q(e),app:Y(e),config:e}}function oe(e){const{controlPlaneTenantId:t="control_plane",syncResourceServers:s=!0,syncRoles:a=!0,multiTenancy:i,entityHooks:n,...u}=e,l={...i,accessControl:{controlPlaneTenantId:t,requireOrganizationMatch:!1,defaultPermissions:["tenant:admin"],...i==null?void 0:i.accessControl}},c=z(l);let r,f;s&&(r=W({controlPlaneTenantId:t,getChildTenantIds:async()=>(await b.fetchAll(m=>e.dataAdapter.tenants.list(m),"tenants",{cursorField:"id",pageSize:100})).filter(m=>m.id!==t).map(m=>m.id),getAdapters:async w=>e.dataAdapter}),f=G({controlPlaneTenantId:t,getControlPlaneAdapters:async()=>e.dataAdapter,getAdapters:async w=>e.dataAdapter}));let d,o;a&&(d=L({controlPlaneTenantId:t,getChildTenantIds:async()=>(await b.fetchAll(m=>e.dataAdapter.tenants.list(m),"tenants",{cursorField:"id",pageSize:100})).filter(m=>m.id!==t).map(m=>m.id),getAdapters:async w=>e.dataAdapter}),o=Q({controlPlaneTenantId:t,getControlPlaneAdapters:async()=>e.dataAdapter,getAdapters:async w=>e.dataAdapter,syncPermissions:!0}));const p=async(w,m,...y)=>{const _=[];if(w)try{await w(...y)}catch(T){_.push(T instanceof Error?T:new Error(String(T)))}if(m)try{await m(...y)}catch(T){_.push(T instanceof Error?T:new Error(String(T)))}if(_.length===1)throw _[0];if(_.length>1)throw new AggregateError(_,`Multiple hook errors: ${_.map(T=>T.message).join("; ")}`)},g=async(w,...m)=>{const y=[];for(const _ of w)if(_)try{await _(...m)}catch(T){y.push(T instanceof Error?T:new Error(String(T)))}if(y.length===1)throw y[0];if(y.length>1)throw new AggregateError(y,`Multiple hook errors: ${y.map(_=>_.message).join("; ")}`)},h={...n,resourceServers:r?{...n==null?void 0:n.resourceServers,afterCreate:async(w,m)=>{var y;await p((y=n==null?void 0:n.resourceServers)==null?void 0:y.afterCreate,r==null?void 0:r.afterCreate,w,m)},afterUpdate:async(w,m,y)=>{var _;await p((_=n==null?void 0:n.resourceServers)==null?void 0:_.afterUpdate,r==null?void 0:r.afterUpdate,w,m,y)},afterDelete:async(w,m)=>{var y;await p((y=n==null?void 0:n.resourceServers)==null?void 0:y.afterDelete,r==null?void 0:r.afterDelete,w,m)}}:n==null?void 0:n.resourceServers,roles:d?{...n==null?void 0:n.roles,afterCreate:async(w,m)=>{var y;await p((y=n==null?void 0:n.roles)==null?void 0:y.afterCreate,d==null?void 0:d.afterCreate,w,m)},afterUpdate:async(w,m,y)=>{var _;await p((_=n==null?void 0:n.roles)==null?void 0:_.afterUpdate,d==null?void 0:d.afterUpdate,w,m,y)},afterDelete:async(w,m)=>{var y;await p((y=n==null?void 0:n.roles)==null?void 0:y.afterDelete,d==null?void 0:d.afterDelete,w,m)}}:n==null?void 0:n.roles,tenants:f||o?{...n==null?void 0:n.tenants,afterCreate:async(w,m)=>{var y;await g([(y=n==null?void 0:n.tenants)==null?void 0:y.afterCreate,f==null?void 0:f.afterCreate,o==null?void 0:o.afterCreate],w,m)}}:n==null?void 0:n.tenants},A={...c,tenants:f||o?{...c.tenants,afterCreate:async(w,m)=>{var y;(y=c.tenants)!=null&&y.afterCreate&&await c.tenants.afterCreate(w,m),await g([f==null?void 0:f.afterCreate,o==null?void 0:o.afterCreate],w,m)}}:c.tenants},S=D(l,A),O=b.init({...u,entityHooks:h,managementApiExtensions:[...u.managementApiExtensions||[],{path:"/tenants",router:S}]}),{app:M,managementApp:$,...F}=O,P=new N.Hono;return P.onError((w,m)=>w instanceof v?w.getResponse():(console.error(w),m.json({message:"Internal Server Error"},500))),P.use("/api/v2/*",V()),P.route("/",M),{app:P,managementApp:$,...F,multiTenancyConfig:l,multiTenancyHooks:c}}Object.defineProperty(exports,"MANAGEMENT_API_SCOPES",{enumerable:!0,get:()=>b.MANAGEMENT_API_SCOPES});Object.defineProperty(exports,"fetchAll",{enumerable:!0,get:()=>b.fetchAll});Object.defineProperty(exports,"seed",{enumerable:!0,get:()=>b.seed});exports.createAccessControlHooks=U;exports.createAccessControlMiddleware=k;exports.createDatabaseHooks=K;exports.createDatabaseMiddleware=X;exports.createMultiTenancy=Y;exports.createMultiTenancyHooks=z;exports.createMultiTenancyMiddleware=q;exports.createMultiTenancyPlugin=se;exports.createProtectSyncedMiddleware=V;exports.createProvisioningHooks=B;exports.createResourceServerSyncHooks=W;exports.createRoleSyncHooks=L;exports.createSubdomainMiddleware=J;exports.createTenantResourceServerSyncHooks=G;exports.createTenantRoleSyncHooks=Q;exports.createTenantsOpenAPIRouter=D;exports.init=oe;exports.setupMultiTenancy=ie;exports.validateTenantAccess=E;
1
+ "use strict";var Z=Object.defineProperty;var H=(e,t,s)=>t in e?Z(e,t,{enumerable:!0,configurable:!0,writable:!0,value:s}):e[t]=s;var F=(e,t,s)=>H(e,typeof t!="symbol"?t+"":t,s);Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const N=require("hono"),T=require("authhero"),C=require("@hono/zod-openapi"),I=require("@authhero/adapter-interfaces");var v=class extends Error{constructor(t=500,s){super(s==null?void 0:s.message,{cause:s==null?void 0:s.cause});F(this,"res");F(this,"status");this.res=s==null?void 0:s.res,this.status=t}getResponse(){return this.res?new Response(this.res.body,{status:this.status,headers:this.res.headers}):new Response(this.message,{status:this.status})}};function U(e){const{controlPlaneTenantId:t,requireOrganizationMatch:s=!0}=e;return{async onTenantAccessValidation(a,i){if(i===t)return!0;if(s){const n=a.var.org_name,u=a.var.organization_id,l=n||u;return l?l===i:!1}return!0}}}function E(e,t,s,a){if(t===s)return!0;const i=a||e;return i?i===t:!1}function K(e){return{async resolveDataAdapters(t){try{return await e.getAdapters(t)}catch(s){console.error(`Failed to resolve data adapters for tenant ${t}:`,s);return}}}}function G(e){return{async beforeCreate(t,s){return!s.audience&&s.id?{...s,audience:T.getTenantAudience(s.id)}:s},async afterCreate(t,s){const{accessControl:a,databaseIsolation:i,settingsInheritance:n}=e;a&&t.ctx&&await x(t,s,a),i!=null&&i.onProvision&&await i.onProvision(s.id),(n==null?void 0:n.inheritFromControlPlane)!==!1&&t.ctx&&await ae(t,s,e)},async beforeDelete(t,s){const{accessControl:a,databaseIsolation:i}=e;if(a)try{const u=(await t.adapters.organizations.list(a.controlPlaneTenantId)).organizations.find(l=>l.name===s);u&&await t.adapters.organizations.remove(a.controlPlaneTenantId,u.id)}catch(n){console.warn(`Failed to remove organization for tenant ${s}:`,n)}if(i!=null&&i.onDeprovision)try{await i.onDeprovision(s)}catch(n){console.warn(`Failed to deprovision database for tenant ${s}:`,n)}}}}async function x(e,t,s){const{controlPlaneTenantId:a,defaultPermissions:i,defaultRoles:n,issuer:u,adminRoleName:l="Tenant Admin",adminRoleDescription:c="Full access to all tenant management operations",addCreatorToOrganization:r=!0}=s,f=await e.adapters.organizations.create(a,{name:t.id,display_name:t.friendly_name||t.id});let d;if(u&&(d=await te(e,a,l,c)),r&&e.ctx){const o=e.ctx.var.user;if(o!=null&&o.sub&&!await ee(e,a,o.sub))try{await e.adapters.userOrganizations.create(a,{user_id:o.sub,organization_id:f.id}),d&&await e.adapters.userRoles.create(a,o.sub,d,f.id)}catch(g){console.warn(`Failed to add creator ${o.sub} to organization ${f.id}:`,g)}}n&&n.length>0&&console.log(`Would assign roles ${n.join(", ")} to organization ${f.id}`),i&&i.length>0&&console.log(`Would grant permissions ${i.join(", ")} to organization ${f.id}`)}async function ee(e,t,s){const a=await e.adapters.userRoles.list(t,s,void 0,"");for(const i of a)if((await e.adapters.rolePermissions.list(t,i.id,{per_page:1e3})).some(l=>l.permission_name==="admin:organizations"))return!0;return!1}async function te(e,t,s,a){const n=(await e.adapters.roles.list(t,{})).roles.find(r=>r.name===s);if(n)return n.id;const u=await e.adapters.roles.create(t,{name:s,description:a}),l=T.MANAGEMENT_API_AUDIENCE,c=T.MANAGEMENT_API_SCOPES.map(r=>({role_id:u.id,resource_server_identifier:l,permission_name:r.value}));return await e.adapters.rolePermissions.assign(t,u.id,c),u.id}async function ae(e,t,s){const{accessControl:a,settingsInheritance:i}=s;if(!a)return;const n=await e.adapters.tenants.get(a.controlPlaneTenantId);if(!n)return;let u={...n};const l=["id","created_at","updated_at","friendly_name","audience","sender_email","sender_name"];for(const c of l)delete u[c];if(i!=null&&i.inheritedKeys){const c={};for(const r of i.inheritedKeys)r in n&&!l.includes(r)&&(c[r]=n[r]);u=c}if(i!=null&&i.excludedKeys)for(const c of i.excludedKeys)delete u[c];i!=null&&i.transformSettings&&(u=i.transformSettings(u,t.id)),Object.keys(u).length>0&&await e.adapters.tenants.update(t.id,u)}function B(e){const{controlPlaneTenantId:t,getChildTenantIds:s,getAdapters:a,shouldSync:i=()=>!0,transformForSync:n}=e;async function u(r,f,d){return(await r.resourceServers.list(f,{q:`identifier:${d}`,per_page:1})).resource_servers[0]??null}async function l(r,f){const d=await s();await Promise.all(d.map(async o=>{try{const p=await a(o),h={...n?n(r,o):{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(f==="create"){const A=await u(p,o,r.identifier);A&&A.id?await p.resourceServers.update(o,A.id,h):await p.resourceServers.create(o,h)}else{const A=await u(p,o,r.identifier);A&&A.id?await p.resourceServers.update(o,A.id,h):await p.resourceServers.create(o,h)}}catch(p){console.error(`Failed to sync resource server "${r.identifier}" to tenant "${o}":`,p)}}))}async function c(r){const f=await s();await Promise.all(f.map(async d=>{try{const o=await a(d),p=await u(o,d,r);p&&p.id&&await o.resourceServers.remove(d,p.id)}catch(o){console.error(`Failed to delete resource server "${r}" from tenant "${d}":`,o)}}))}return{afterCreate:async(r,f)=>{r.tenantId===t&&i(f)&&await l(f,"create")},afterUpdate:async(r,f,d)=>{r.tenantId===t&&i(d)&&await l(d,"update")},afterDelete:async(r,f)=>{r.tenantId===t&&await c(f)}}}function W(e){const{controlPlaneTenantId:t,getControlPlaneAdapters:s,getAdapters:a,shouldSync:i=()=>!0,transformForSync:n}=e;return{async afterCreate(u,l){if(l.id!==t)try{const c=await s(),r=await a(l.id),f=await T.fetchAll(d=>c.resourceServers.list(t,d),"resource_servers",{cursorField:"id",pageSize:100});await Promise.all(f.filter(d=>i(d)).map(async d=>{const o=d;try{const p=n?n(o,l.id):{name:o.name,identifier:o.identifier,scopes:o.scopes,signing_alg:o.signing_alg,signing_secret:o.signing_secret,token_lifetime:o.token_lifetime,token_lifetime_for_web:o.token_lifetime_for_web,skip_consent_for_verifiable_first_party_clients:o.skip_consent_for_verifiable_first_party_clients,allow_offline_access:o.allow_offline_access,verificationKey:o.verificationKey,options:o.options};await r.resourceServers.create(l.id,{...p,is_system:!0})}catch(p){console.error(`Failed to sync resource server "${o.identifier}" to new tenant "${l.id}":`,p)}}))}catch(c){console.error(`Failed to sync resource servers to new tenant "${l.id}":`,c)}}}}function L(e){const{controlPlaneTenantId:t,getChildTenantIds:s,getAdapters:a,shouldSync:i=()=>!0,transformForSync:n}=e;async function u(c,r,f){return(await c.roles.list(r,{q:`name:${f}`,per_page:1})).roles[0]??null}async function l(c,r){const f=await s();await Promise.all(f.map(async d=>{try{const o=await a(d),g={...n?n(c,d):{name:c.name,description:c.description},is_system:!0};if(r==="create"){const h=await u(o,d,c.name);h&&h.id?await o.roles.update(d,h.id,g):await o.roles.create(d,g)}else{const h=await u(o,d,c.name);h&&h.id?await o.roles.update(d,h.id,g):await o.roles.create(d,g)}}catch(o){console.error(`Failed to sync role "${c.name}" to tenant "${d}":`,o)}}))}return{afterCreate:async(c,r)=>{c.tenantId===t&&i(r)&&await l(r,"create")},afterUpdate:async(c,r,f)=>{c.tenantId===t&&i(f)&&await l(f,"update")},afterDelete:async(c,r)=>{c.tenantId===t&&console.warn(`Role ${r} was deleted from control plane. Child tenant roles with matching names should be deleted manually or implement role name tracking.`)}}}function Q(e){const{controlPlaneTenantId:t,getControlPlaneAdapters:s,getAdapters:a,shouldSync:i=()=>!0,transformForSync:n,syncPermissions:u=!0}=e;return{async afterCreate(l,c){if(c.id!==t)try{const r=await s(),f=await a(c.id),d=await T.fetchAll(p=>r.roles.list(t,p),"roles",{cursorField:"id",pageSize:100}),o=new Map;if(await Promise.all(d.filter(p=>i(p)).map(async p=>{const g=p;try{const h=n?n(g,c.id):{name:g.name,description:g.description},A=await f.roles.create(c.id,{...h,is_system:!0});o.set(g.id,A.id)}catch(h){console.error(`Failed to sync role "${g.name}" to new tenant "${c.id}":`,h)}})),u)for(const[p,g]of o)try{const h=await r.rolePermissions.list(t,p,{});h.length>0&&await f.rolePermissions.assign(c.id,g,h.map(A=>({role_id:g,resource_server_identifier:A.resource_server_identifier,permission_name:A.permission_name})))}catch(h){console.error(`Failed to sync permissions for role to new tenant "${c.id}":`,h)}}catch(r){console.error(`Failed to sync roles to new tenant "${c.id}":`,r)}}}}function O(e,t){const s=new C.OpenAPIHono;return s.openapi(C.createRoute({tags:["tenants"],method:"get",path:"/",request:{query:I.auth0QuerySchema},security:[{Bearer:[]}],responses:{200:{content:{"application/json":{schema:C.z.object({tenants:C.z.array(I.tenantSchema),start:C.z.number().optional(),limit:C.z.number().optional(),length:C.z.number().optional()})}},description:"List of tenants"}}}),async a=>{var p,g,h,A;const i=a.req.valid("query"),{page:n,per_page:u,include_totals:l,q:c}=i,r=a.var.user,f=((r==null?void 0:r.scope)||"").split(" "),d=f.includes("auth:read");if(console.log("User scopes:",f,"hasAuthRead:",d),d){const S=await a.env.data.tenants.list({page:n,per_page:u,include_totals:l,q:c});return l?a.json({tenants:S.tenants,start:((p=S.totals)==null?void 0:p.start)??0,limit:((g=S.totals)==null?void 0:g.limit)??u,length:S.tenants.length}):a.json({tenants:S.tenants})}if(e.accessControl&&(r!=null&&r.sub)){const S=e.accessControl.controlPlaneTenantId,R=(await T.fetchAll(M=>a.env.data.userOrganizations.listUserOrganizations(S,r.sub,M),"organizations")).map(M=>M.name);if(R.length===0)return l?a.json({tenants:[],start:0,limit:u??50,length:0}):a.json({tenants:[]});const $=R.length,D=n??0,P=u??50,w=D*P,m=R.slice(w,w+P);if(m.length===0)return l?a.json({tenants:[],start:w,limit:P,length:$}):a.json({tenants:[]});const y=m.map(M=>`id:${M}`).join(" OR "),_=c?`(${y}) AND (${c})`:y,b=await a.env.data.tenants.list({q:_,per_page:P,include_totals:!1});return l?a.json({tenants:b.tenants,start:w,limit:P,length:$}):a.json({tenants:b.tenants})}const o=await a.env.data.tenants.list({page:n,per_page:u,include_totals:l,q:c});return l?a.json({tenants:o.tenants,start:((h=o.totals)==null?void 0:h.start)??0,limit:((A=o.totals)==null?void 0:A.limit)??u,length:o.tenants.length}):a.json({tenants:o.tenants})}),s.openapi(C.createRoute({tags:["tenants"],method:"post",path:"/",request:{body:{content:{"application/json":{schema:I.tenantInsertSchema}}}},security:[{Bearer:[]}],responses:{201:{content:{"application/json":{schema:I.tenantSchema}},description:"Tenant created"},400:{description:"Validation error"},409:{description:"Tenant with this ID already exists"}}}),async a=>{var c,r;const i=a.var.user;if(!(i!=null&&i.sub))throw new v(401,{message:"Authentication required to create tenants"});let n=a.req.valid("json");const u={adapters:a.env.data,ctx:a};(c=t.tenants)!=null&&c.beforeCreate&&(n=await t.tenants.beforeCreate(u,n));const l=await a.env.data.tenants.create(n);return(r=t.tenants)!=null&&r.afterCreate&&await t.tenants.afterCreate(u,l),a.json(l,201)}),s.openapi(C.createRoute({tags:["tenants"],method:"delete",path:"/{id}",request:{params:C.z.object({id:C.z.string()})},security:[{Bearer:["delete:tenants"]}],responses:{204:{description:"Tenant deleted"},403:{description:"Access denied or cannot delete the control plane"},404:{description:"Tenant not found"}}}),async a=>{var l,c;const{id:i}=a.req.valid("param");if(e.accessControl){const r=a.var.user,f=e.accessControl.controlPlaneTenantId;if(!(r!=null&&r.sub))throw new v(401,{message:"Authentication required"});if(i===f)throw new v(403,{message:"Cannot delete the control plane"});if(!(await T.fetchAll(p=>a.env.data.userOrganizations.listUserOrganizations(f,r.sub,p),"organizations")).some(p=>p.name===i))throw new v(403,{message:"Access denied to this tenant"})}if(!await a.env.data.tenants.get(i))throw new v(404,{message:"Tenant not found"});const u={adapters:a.env.data,ctx:a};return(l=t.tenants)!=null&&l.beforeDelete&&await t.tenants.beforeDelete(u,i),await a.env.data.tenants.remove(i),(c=t.tenants)!=null&&c.afterDelete&&await t.tenants.afterDelete(u,i),a.body(null,204)}),s}function ne(e){const t=[{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:a}of t){const i=e.match(s);if(i&&i[1])return{type:a,id:i[1]}}return null}async function re(e,t,s){try{switch(s.type){case"resource_server":{const a=await e.resourceServers.get(t,s.id);return(a==null?void 0:a.is_system)===!0}case"role":{const a=await e.roles.get(t,s.id);return(a==null?void 0:a.is_system)===!0}case"connection":{const a=await e.connections.get(t,s.id);return(a==null?void 0:a.is_system)===!0}default:return!1}}catch{return!1}}function se(e){return{resource_server:"resource server",role:"role",connection:"connection"}[e]}function V(){return async(e,t)=>{if(!["PATCH","PUT","DELETE"].includes(e.req.method))return t();const s=ne(e.req.path);if(!s)return t();const a=e.var.tenant_id||e.req.header("x-tenant-id")||e.req.header("tenant-id");if(!a)return t();if(await re(e.env.data,a,s))throw new v(403,{message:`This ${se(s.type)} is a system resource and cannot be modified. Make changes in the control plane instead.`});return t()}}function k(e){return async(t,s)=>{if(!e.accessControl)return s();const a=t.var.tenant_id,i=t.var.organization_id;if(!a)throw new v(400,{message:"Tenant ID not found in request"});if(!E(i,a,e.accessControl.controlPlaneTenantId))throw new v(403,{message:`Access denied to tenant ${a}`});return s()}}function J(e){return async(t,s)=>{if(!e.subdomainRouting)return s();const{baseDomain:a,reservedSubdomains:i=[],resolveSubdomain:n}=e.subdomainRouting,u=t.req.header("host")||"";let l=null;if(u.endsWith(a)){const r=u.slice(0,-(a.length+1));r&&!r.includes(".")&&(l=r)}if(l&&i.includes(l)&&(l=null),!l)return e.accessControl&&t.set("tenant_id",e.accessControl.controlPlaneTenantId),s();let c=null;if(n)c=await n(l);else if(e.subdomainRouting.useOrganizations!==!1&&e.accessControl)try{const r=await t.env.data.organizations.get(e.accessControl.controlPlaneTenantId,l);r&&(c=r.id)}catch{}if(!c)throw new v(404,{message:`Tenant not found for subdomain: ${l}`});return t.set("tenant_id",c),s()}}function X(e){return async(t,s)=>{if(!e.databaseIsolation)return s();const a=t.var.tenant_id;if(!a)throw new v(400,{message:"Tenant ID not found in request"});try{const i=await e.databaseIsolation.getAdapters(a);t.env.data=i}catch(i){throw console.error(`Failed to resolve database for tenant ${a}:`,i),new v(500,{message:"Failed to resolve tenant database"})}return s()}}function j(e){const t=J(e),s=k(e),a=X(e);return async(i,n)=>(await t(i,async()=>{}),await s(i,async()=>{}),await a(i,async()=>{}),n())}function ie(e){const t=z(e);return{name:"multi-tenancy",middleware:j(e),hooks:t,routes:[{path:"/management",handler:O(e,t)}],onRegister:async()=>{console.log("Multi-tenancy plugin registered"),e.accessControl&&console.log(` - Access control enabled (control plane: ${e.accessControl.controlPlaneTenantId})`),e.subdomainRouting&&console.log(` - Subdomain routing enabled (base domain: ${e.subdomainRouting.baseDomain})`),e.databaseIsolation&&console.log(" - Database isolation enabled")}}}function z(e){const t=e.accessControl?U(e.accessControl):{},s=e.databaseIsolation?K(e.databaseIsolation):{},a=G(e);return{...t,...s,tenants:a}}function Y(e){const t=new N.Hono,s=z(e);return t.route("/tenants",O(e,s)),t}function oe(e){return{hooks:z(e),middleware:j(e),app:Y(e),config:e}}function ce(e){const{controlPlaneTenantId:t="control_plane",syncResourceServers:s=!0,syncRoles:a=!0,multiTenancy:i,entityHooks:n,...u}=e,l={...i,accessControl:{controlPlaneTenantId:t,requireOrganizationMatch:!1,defaultPermissions:["tenant:admin"],...i==null?void 0:i.accessControl}},c=z(l);let r,f;s&&(r=B({controlPlaneTenantId:t,getChildTenantIds:async()=>(await T.fetchAll(m=>e.dataAdapter.tenants.list(m),"tenants",{cursorField:"id",pageSize:100})).filter(m=>m.id!==t).map(m=>m.id),getAdapters:async w=>e.dataAdapter}),f=W({controlPlaneTenantId:t,getControlPlaneAdapters:async()=>e.dataAdapter,getAdapters:async w=>e.dataAdapter}));let d,o;a&&(d=L({controlPlaneTenantId:t,getChildTenantIds:async()=>(await T.fetchAll(m=>e.dataAdapter.tenants.list(m),"tenants",{cursorField:"id",pageSize:100})).filter(m=>m.id!==t).map(m=>m.id),getAdapters:async w=>e.dataAdapter}),o=Q({controlPlaneTenantId:t,getControlPlaneAdapters:async()=>e.dataAdapter,getAdapters:async w=>e.dataAdapter,syncPermissions:!0}));const p=async(w,m,...y)=>{const _=[];if(w)try{await w(...y)}catch(b){_.push(b instanceof Error?b:new Error(String(b)))}if(m)try{await m(...y)}catch(b){_.push(b instanceof Error?b:new Error(String(b)))}if(_.length===1)throw _[0];if(_.length>1)throw new AggregateError(_,`Multiple hook errors: ${_.map(b=>b.message).join("; ")}`)},g=async(w,...m)=>{const y=[];for(const _ of w)if(_)try{await _(...m)}catch(b){y.push(b instanceof Error?b:new Error(String(b)))}if(y.length===1)throw y[0];if(y.length>1)throw new AggregateError(y,`Multiple hook errors: ${y.map(_=>_.message).join("; ")}`)},h={...n,resourceServers:r?{...n==null?void 0:n.resourceServers,afterCreate:async(w,m)=>{var y;await p((y=n==null?void 0:n.resourceServers)==null?void 0:y.afterCreate,r==null?void 0:r.afterCreate,w,m)},afterUpdate:async(w,m,y)=>{var _;await p((_=n==null?void 0:n.resourceServers)==null?void 0:_.afterUpdate,r==null?void 0:r.afterUpdate,w,m,y)},afterDelete:async(w,m)=>{var y;await p((y=n==null?void 0:n.resourceServers)==null?void 0:y.afterDelete,r==null?void 0:r.afterDelete,w,m)}}:n==null?void 0:n.resourceServers,roles:d?{...n==null?void 0:n.roles,afterCreate:async(w,m)=>{var y;await p((y=n==null?void 0:n.roles)==null?void 0:y.afterCreate,d==null?void 0:d.afterCreate,w,m)},afterUpdate:async(w,m,y)=>{var _;await p((_=n==null?void 0:n.roles)==null?void 0:_.afterUpdate,d==null?void 0:d.afterUpdate,w,m,y)},afterDelete:async(w,m)=>{var y;await p((y=n==null?void 0:n.roles)==null?void 0:y.afterDelete,d==null?void 0:d.afterDelete,w,m)}}:n==null?void 0:n.roles,tenants:f||o?{...n==null?void 0:n.tenants,afterCreate:async(w,m)=>{var y;await g([(y=n==null?void 0:n.tenants)==null?void 0:y.afterCreate,f==null?void 0:f.afterCreate,o==null?void 0:o.afterCreate],w,m)}}:n==null?void 0:n.tenants},A={...c,tenants:f||o?{...c.tenants,afterCreate:async(w,m)=>{var y;(y=c.tenants)!=null&&y.afterCreate&&await c.tenants.afterCreate(w,m),await g([f==null?void 0:f.afterCreate,o==null?void 0:o.afterCreate],w,m)}}:c.tenants},S=O(l,A),q=T.init({...u,entityHooks:h,managementApiExtensions:[...u.managementApiExtensions||[],{path:"/tenants",router:S}]}),{app:R,managementApp:$,...D}=q,P=new N.Hono;return P.onError((w,m)=>w instanceof v?w.getResponse():(console.error(w),m.json({message:"Internal Server Error"},500))),P.use("/api/v2/*",V()),P.route("/",R),{app:P,managementApp:$,...D,multiTenancyConfig:l,multiTenancyHooks:c}}Object.defineProperty(exports,"MANAGEMENT_API_SCOPES",{enumerable:!0,get:()=>T.MANAGEMENT_API_SCOPES});Object.defineProperty(exports,"fetchAll",{enumerable:!0,get:()=>T.fetchAll});Object.defineProperty(exports,"seed",{enumerable:!0,get:()=>T.seed});exports.createAccessControlHooks=U;exports.createAccessControlMiddleware=k;exports.createDatabaseHooks=K;exports.createDatabaseMiddleware=X;exports.createMultiTenancy=Y;exports.createMultiTenancyHooks=z;exports.createMultiTenancyMiddleware=j;exports.createMultiTenancyPlugin=ie;exports.createProtectSyncedMiddleware=V;exports.createProvisioningHooks=G;exports.createResourceServerSyncHooks=B;exports.createRoleSyncHooks=L;exports.createSubdomainMiddleware=J;exports.createTenantResourceServerSyncHooks=W;exports.createTenantRoleSyncHooks=Q;exports.createTenantsOpenAPIRouter=O;exports.init=ce;exports.setupMultiTenancy=oe;exports.validateTenantAccess=E;
@@ -563,6 +563,7 @@ export interface Totals {
563
563
  start: number;
564
564
  limit: number;
565
565
  length: number;
566
+ total?: number;
566
567
  }
567
568
  declare const userInsertSchema: z.ZodObject<{
568
569
  email: z.ZodEffects<z.ZodOptional<z.ZodString>, string | undefined, string | undefined>;
@@ -11223,6 +11224,8 @@ export interface ListParams {
11223
11224
  sort_by: string;
11224
11225
  sort_order: "asc" | "desc";
11225
11226
  };
11227
+ from?: string;
11228
+ take?: number;
11226
11229
  }
11227
11230
  declare const loginSessionInsertSchema: z.ZodObject<{
11228
11231
  csrf_token: z.ZodString;
@@ -15817,6 +15820,7 @@ interface Totals$1 {
15817
15820
  start: number;
15818
15821
  limit: number;
15819
15822
  length: number;
15823
+ total?: number;
15820
15824
  }
15821
15825
  declare const userInsertSchema$1: z.ZodObject<{
15822
15826
  email: z.ZodEffects<z.ZodOptional<z.ZodString>, string | undefined, string | undefined>;
@@ -26477,6 +26481,8 @@ interface ListParams$1 {
26477
26481
  sort_by: string;
26478
26482
  sort_order: "asc" | "desc";
26479
26483
  };
26484
+ from?: string;
26485
+ take?: number;
26480
26486
  }
26481
26487
  declare const loginSessionInsertSchema$1: z.ZodObject<{
26482
26488
  csrf_token: z.ZodString;
@@ -33096,6 +33102,8 @@ export declare function init(config: MultiTenantAuthHeroConfig): {
33096
33102
  page?: string | undefined;
33097
33103
  per_page?: string | undefined;
33098
33104
  include_totals?: string | undefined;
33105
+ from?: string | undefined;
33106
+ take?: string | undefined;
33099
33107
  q?: string | undefined;
33100
33108
  };
33101
33109
  } & {
@@ -33166,6 +33174,7 @@ export declare function init(config: MultiTenantAuthHeroConfig): {
33166
33174
  is_signup_enabled: boolean;
33167
33175
  }[] | undefined;
33168
33176
  }[];
33177
+ total?: number | undefined;
33169
33178
  };
33170
33179
  outputFormat: "json";
33171
33180
  status: 200;
@@ -33389,6 +33398,8 @@ export declare function init(config: MultiTenantAuthHeroConfig): {
33389
33398
  page?: string | undefined;
33390
33399
  per_page?: string | undefined;
33391
33400
  include_totals?: string | undefined;
33401
+ from?: string | undefined;
33402
+ take?: string | undefined;
33392
33403
  q?: string | undefined;
33393
33404
  };
33394
33405
  } & {
@@ -33477,6 +33488,8 @@ export declare function init(config: MultiTenantAuthHeroConfig): {
33477
33488
  page?: string | undefined;
33478
33489
  per_page?: string | undefined;
33479
33490
  include_totals?: string | undefined;
33491
+ from?: string | undefined;
33492
+ take?: string | undefined;
33480
33493
  q?: string | undefined;
33481
33494
  };
33482
33495
  } & {
@@ -33553,6 +33566,8 @@ export declare function init(config: MultiTenantAuthHeroConfig): {
33553
33566
  page?: string | undefined;
33554
33567
  per_page?: string | undefined;
33555
33568
  include_totals?: string | undefined;
33569
+ from?: string | undefined;
33570
+ take?: string | undefined;
33556
33571
  q?: string | undefined;
33557
33572
  };
33558
33573
  } & {
@@ -33805,6 +33820,8 @@ export declare function init(config: MultiTenantAuthHeroConfig): {
33805
33820
  page?: string | undefined;
33806
33821
  per_page?: string | undefined;
33807
33822
  include_totals?: string | undefined;
33823
+ from?: string | undefined;
33824
+ take?: string | undefined;
33808
33825
  q?: string | undefined;
33809
33826
  };
33810
33827
  } & {
@@ -33875,6 +33892,7 @@ export declare function init(config: MultiTenantAuthHeroConfig): {
33875
33892
  allow_offline_access?: boolean | undefined | undefined;
33876
33893
  verificationKey?: string | undefined | undefined;
33877
33894
  }[];
33895
+ total?: number | undefined;
33878
33896
  };
33879
33897
  outputFormat: "json";
33880
33898
  status: 200;
@@ -34096,6 +34114,8 @@ export declare function init(config: MultiTenantAuthHeroConfig): {
34096
34114
  page?: string | undefined;
34097
34115
  per_page?: string | undefined;
34098
34116
  include_totals?: string | undefined;
34117
+ from?: string | undefined;
34118
+ take?: string | undefined;
34099
34119
  q?: string | undefined;
34100
34120
  };
34101
34121
  } & {
@@ -34122,6 +34142,7 @@ export declare function init(config: MultiTenantAuthHeroConfig): {
34122
34142
  description?: string | undefined | undefined;
34123
34143
  is_system?: boolean | undefined | undefined;
34124
34144
  }[];
34145
+ total?: number | undefined;
34125
34146
  };
34126
34147
  outputFormat: "json";
34127
34148
  status: 200;
@@ -34237,6 +34258,8 @@ export declare function init(config: MultiTenantAuthHeroConfig): {
34237
34258
  page?: string | undefined;
34238
34259
  per_page?: string | undefined;
34239
34260
  include_totals?: string | undefined;
34261
+ from?: string | undefined;
34262
+ take?: string | undefined;
34240
34263
  q?: string | undefined;
34241
34264
  };
34242
34265
  } & {
@@ -34311,6 +34334,8 @@ export declare function init(config: MultiTenantAuthHeroConfig): {
34311
34334
  page?: string | undefined;
34312
34335
  per_page?: string | undefined;
34313
34336
  include_totals?: string | undefined;
34337
+ from?: string | undefined;
34338
+ take?: string | undefined;
34314
34339
  q?: string | undefined;
34315
34340
  };
34316
34341
  } & {
@@ -34421,6 +34446,7 @@ export declare function init(config: MultiTenantAuthHeroConfig): {
34421
34446
  mask_output?: boolean | undefined | undefined;
34422
34447
  })[];
34423
34448
  }[];
34449
+ total?: number | undefined;
34424
34450
  };
34425
34451
  outputFormat: "json";
34426
34452
  status: 200;
@@ -34738,6 +34764,8 @@ export declare function init(config: MultiTenantAuthHeroConfig): {
34738
34764
  page?: string | undefined;
34739
34765
  per_page?: string | undefined;
34740
34766
  include_totals?: string | undefined;
34767
+ from?: string | undefined;
34768
+ take?: string | undefined;
34741
34769
  q?: string | undefined;
34742
34770
  };
34743
34771
  } & {
@@ -35638,6 +35666,7 @@ export declare function init(config: MultiTenantAuthHeroConfig): {
35638
35666
  [x: string]: any;
35639
35667
  } | undefined;
35640
35668
  }[];
35669
+ total?: number | undefined;
35641
35670
  };
35642
35671
  outputFormat: "json";
35643
35672
  status: 200;
@@ -38083,6 +38112,8 @@ export declare function init(config: MultiTenantAuthHeroConfig): {
38083
38112
  page?: string | undefined;
38084
38113
  per_page?: string | undefined;
38085
38114
  include_totals?: string | undefined;
38115
+ from?: string | undefined;
38116
+ take?: string | undefined;
38086
38117
  q?: string | undefined;
38087
38118
  };
38088
38119
  } & {
@@ -38169,6 +38200,7 @@ export declare function init(config: MultiTenantAuthHeroConfig): {
38169
38200
  [x: string]: any;
38170
38201
  } | undefined;
38171
38202
  }[];
38203
+ total?: number | undefined;
38172
38204
  };
38173
38205
  outputFormat: "json";
38174
38206
  status: 200;
@@ -38472,6 +38504,8 @@ export declare function init(config: MultiTenantAuthHeroConfig): {
38472
38504
  page?: string | undefined;
38473
38505
  per_page?: string | undefined;
38474
38506
  include_totals?: string | undefined;
38507
+ from?: string | undefined;
38508
+ take?: string | undefined;
38475
38509
  q?: string | undefined;
38476
38510
  };
38477
38511
  } & {
@@ -38520,6 +38554,7 @@ export declare function init(config: MultiTenantAuthHeroConfig): {
38520
38554
  form_id: string;
38521
38555
  priority?: number | undefined | undefined;
38522
38556
  })[];
38557
+ total?: number | undefined;
38523
38558
  };
38524
38559
  outputFormat: "json";
38525
38560
  status: 200;
@@ -38722,6 +38757,8 @@ export declare function init(config: MultiTenantAuthHeroConfig): {
38722
38757
  page?: string | undefined;
38723
38758
  per_page?: string | undefined;
38724
38759
  include_totals?: string | undefined;
38760
+ from?: string | undefined;
38761
+ take?: string | undefined;
38725
38762
  q?: string | undefined;
38726
38763
  };
38727
38764
  } & {
@@ -38804,6 +38841,7 @@ export declare function init(config: MultiTenantAuthHeroConfig): {
38804
38841
  continent_code: string;
38805
38842
  } | undefined;
38806
38843
  }[];
38844
+ total?: number | undefined;
38807
38845
  };
38808
38846
  outputFormat: "json";
38809
38847
  status: 200;
@@ -39247,6 +39285,7 @@ export declare function init(config: MultiTenantAuthHeroConfig): {
39247
39285
  subject_type?: "client" | "user" | undefined | undefined;
39248
39286
  authorization_details_types?: string[] | undefined | undefined;
39249
39287
  }[];
39288
+ total?: number | undefined;
39250
39289
  };
39251
39290
  outputFormat: "json";
39252
39291
  status: 200;
@@ -39383,6 +39422,8 @@ export declare function init(config: MultiTenantAuthHeroConfig): {
39383
39422
  page?: string | undefined;
39384
39423
  per_page?: string | undefined;
39385
39424
  include_totals?: string | undefined;
39425
+ from?: string | undefined;
39426
+ take?: string | undefined;
39386
39427
  q?: string | undefined;
39387
39428
  };
39388
39429
  } & {
@@ -39551,6 +39592,7 @@ export declare function init(config: MultiTenantAuthHeroConfig): {
39551
39592
  [x: string]: any;
39552
39593
  } | undefined;
39553
39594
  }[];
39595
+ total?: number | undefined;
39554
39596
  };
39555
39597
  outputFormat: "json";
39556
39598
  status: 200;
@@ -40190,6 +40232,8 @@ export declare function init(config: MultiTenantAuthHeroConfig): {
40190
40232
  page?: string | undefined;
40191
40233
  per_page?: string | undefined;
40192
40234
  include_totals?: string | undefined;
40235
+ from?: string | undefined;
40236
+ take?: string | undefined;
40193
40237
  q?: string | undefined;
40194
40238
  };
40195
40239
  } & {
@@ -40292,6 +40336,7 @@ export declare function init(config: MultiTenantAuthHeroConfig): {
40292
40336
  } | undefined;
40293
40337
  }[] | undefined;
40294
40338
  }[];
40339
+ total?: number | undefined;
40295
40340
  };
40296
40341
  outputFormat: "json";
40297
40342
  status: 200;
@@ -40608,6 +40653,8 @@ export declare function init(config: MultiTenantAuthHeroConfig): {
40608
40653
  page?: string | undefined;
40609
40654
  per_page?: string | undefined;
40610
40655
  include_totals?: string | undefined;
40656
+ from?: string | undefined;
40657
+ take?: string | undefined;
40611
40658
  q?: string | undefined;
40612
40659
  };
40613
40660
  } & {
@@ -40662,6 +40709,7 @@ export declare function init(config: MultiTenantAuthHeroConfig): {
40662
40709
  revoked_at?: string | undefined | undefined;
40663
40710
  idle_expires_at?: string | undefined | undefined;
40664
40711
  }[];
40712
+ total?: number | undefined;
40665
40713
  };
40666
40714
  outputFormat: "json";
40667
40715
  status: 200;
@@ -40680,6 +40728,8 @@ export declare function init(config: MultiTenantAuthHeroConfig): {
40680
40728
  page?: string | undefined;
40681
40729
  per_page?: string | undefined;
40682
40730
  include_totals?: string | undefined;
40731
+ from?: string | undefined;
40732
+ take?: string | undefined;
40683
40733
  q?: string | undefined;
40684
40734
  };
40685
40735
  } & {
@@ -40827,6 +40877,8 @@ export declare function init(config: MultiTenantAuthHeroConfig): {
40827
40877
  page?: string | undefined;
40828
40878
  per_page?: string | undefined;
40829
40879
  include_totals?: string | undefined;
40880
+ from?: string | undefined;
40881
+ take?: string | undefined;
40830
40882
  q?: string | undefined;
40831
40883
  };
40832
40884
  } & {
@@ -40897,6 +40949,7 @@ export declare function init(config: MultiTenantAuthHeroConfig): {
40897
40949
  is_signup_enabled: boolean;
40898
40950
  }[] | undefined;
40899
40951
  }[];
40952
+ total?: number | undefined;
40900
40953
  };
40901
40954
  outputFormat: "json";
40902
40955
  status: 200;
@@ -41044,6 +41097,8 @@ export declare function init(config: MultiTenantAuthHeroConfig): {
41044
41097
  page?: string | undefined;
41045
41098
  per_page?: string | undefined;
41046
41099
  include_totals?: string | undefined;
41100
+ from?: string | undefined;
41101
+ take?: string | undefined;
41047
41102
  q?: string | undefined;
41048
41103
  };
41049
41104
  } & {
@@ -2,11 +2,11 @@ var K = Object.defineProperty;
2
2
  var E = (e, t, s) => t in e ? K(e, t, { enumerable: !0, configurable: !0, writable: !0, value: s }) : e[t] = s;
3
3
  var D = (e, t, s) => E(e, typeof t != "symbol" ? t + "" : t, s);
4
4
  import { Hono as U } from "hono";
5
- import { getTenantAudience as B, MANAGEMENT_API_SCOPES as W, MANAGEMENT_API_AUDIENCE as G, fetchAll as S, init as L } from "authhero";
6
- import { MANAGEMENT_API_SCOPES as ve, fetchAll as be, seed as Pe } from "authhero";
5
+ import { getTenantAudience as G, MANAGEMENT_API_SCOPES as B, MANAGEMENT_API_AUDIENCE as W, fetchAll as S, init as L } from "authhero";
6
+ import { MANAGEMENT_API_SCOPES as Ce, fetchAll as Pe, seed as Se } from "authhero";
7
7
  import { OpenAPIHono as Q, createRoute as M, z as P } from "@hono/zod-openapi";
8
- import { auth0QuerySchema as V, tenantSchema as O, tenantInsertSchema as J } from "@authhero/adapter-interfaces";
9
- var C = class extends Error {
8
+ import { auth0QuerySchema as V, tenantSchema as q, tenantInsertSchema as J } from "@authhero/adapter-interfaces";
9
+ var T = class extends Error {
10
10
  /**
11
11
  * Creates an instance of `HTTPException`.
12
12
  * @param status - HTTP status code for the exception. Defaults to 500.
@@ -72,12 +72,12 @@ function k(e) {
72
72
  async beforeCreate(t, s) {
73
73
  return !s.audience && s.id ? {
74
74
  ...s,
75
- audience: B(s.id)
75
+ audience: G(s.id)
76
76
  } : s;
77
77
  },
78
78
  async afterCreate(t, s) {
79
79
  const { accessControl: a, databaseIsolation: i, settingsInheritance: n } = e;
80
- a && t.ctx && await H(t, s, a), i != null && i.onProvision && await i.onProvision(s.id), (n == null ? void 0 : n.inheritFromControlPlane) !== !1 && t.ctx && await ee(t, s, e);
80
+ a && t.ctx && await H(t, s, a), i != null && i.onProvision && await i.onProvision(s.id), (n == null ? void 0 : n.inheritFromControlPlane) !== !1 && t.ctx && await te(t, s, e);
81
81
  },
82
82
  async beforeDelete(t, s) {
83
83
  const { accessControl: a, databaseIsolation: i } = e;
@@ -125,14 +125,18 @@ async function H(e, t, s) {
125
125
  }
126
126
  );
127
127
  let d;
128
- if (u && (d = await x(
128
+ if (u && (d = await ee(
129
129
  e,
130
130
  a,
131
131
  l,
132
132
  c
133
133
  )), r && e.ctx) {
134
134
  const o = e.ctx.var.user;
135
- if (o != null && o.sub)
135
+ if (o != null && o.sub && !await x(
136
+ e,
137
+ a,
138
+ o.sub
139
+ ))
136
140
  try {
137
141
  await e.adapters.userOrganizations.create(a, {
138
142
  user_id: o.sub,
@@ -144,10 +148,10 @@ async function H(e, t, s) {
144
148
  f.id
145
149
  // organizationId
146
150
  );
147
- } catch (p) {
151
+ } catch (g) {
148
152
  console.warn(
149
153
  `Failed to add creator ${o.sub} to organization ${f.id}:`,
150
- p
154
+ g
151
155
  );
152
156
  }
153
157
  }
@@ -157,14 +161,33 @@ async function H(e, t, s) {
157
161
  `Would grant permissions ${i.join(", ")} to organization ${f.id}`
158
162
  );
159
163
  }
160
- async function x(e, t, s, a) {
164
+ async function x(e, t, s) {
165
+ const a = await e.adapters.userRoles.list(
166
+ t,
167
+ s,
168
+ void 0,
169
+ ""
170
+ // Empty string for global roles
171
+ );
172
+ for (const i of a)
173
+ if ((await e.adapters.rolePermissions.list(
174
+ t,
175
+ i.id,
176
+ { per_page: 1e3 }
177
+ )).some(
178
+ (l) => l.permission_name === "admin:organizations"
179
+ ))
180
+ return !0;
181
+ return !1;
182
+ }
183
+ async function ee(e, t, s, a) {
161
184
  const n = (await e.adapters.roles.list(t, {})).roles.find((r) => r.name === s);
162
185
  if (n)
163
186
  return n.id;
164
187
  const u = await e.adapters.roles.create(t, {
165
188
  name: s,
166
189
  description: a
167
- }), l = G, c = W.map((r) => ({
190
+ }), l = W, c = B.map((r) => ({
168
191
  role_id: u.id,
169
192
  resource_server_identifier: l,
170
193
  permission_name: r.value
@@ -175,7 +198,7 @@ async function x(e, t, s, a) {
175
198
  c
176
199
  ), u.id;
177
200
  }
178
- async function ee(e, t, s) {
201
+ async function te(e, t, s) {
179
202
  const { accessControl: a, settingsInheritance: i } = s;
180
203
  if (!a)
181
204
  return;
@@ -211,7 +234,7 @@ async function ee(e, t, s) {
211
234
  t.id
212
235
  )), Object.keys(u).length > 0 && await e.adapters.tenants.update(t.id, u);
213
236
  }
214
- function te(e) {
237
+ function ae(e) {
215
238
  const {
216
239
  controlPlaneTenantId: t,
217
240
  getChildTenantIds: s,
@@ -244,25 +267,25 @@ function te(e) {
244
267
  options: r.options
245
268
  }, is_system: !0 };
246
269
  if (f === "create") {
247
- const T = await u(
270
+ const A = await u(
248
271
  p,
249
272
  o,
250
273
  r.identifier
251
274
  );
252
- T && T.id ? await p.resourceServers.update(
275
+ A && A.id ? await p.resourceServers.update(
253
276
  o,
254
- T.id,
277
+ A.id,
255
278
  h
256
279
  ) : await p.resourceServers.create(o, h);
257
280
  } else {
258
- const T = await u(
281
+ const A = await u(
259
282
  p,
260
283
  o,
261
284
  r.identifier
262
285
  );
263
- T && T.id ? await p.resourceServers.update(
286
+ A && A.id ? await p.resourceServers.update(
264
287
  o,
265
- T.id,
288
+ A.id,
266
289
  h
267
290
  ) : await p.resourceServers.create(o, h);
268
291
  }
@@ -307,7 +330,7 @@ function te(e) {
307
330
  }
308
331
  };
309
332
  }
310
- function ae(e) {
333
+ function ne(e) {
311
334
  const {
312
335
  controlPlaneTenantId: t,
313
336
  getControlPlaneAdapters: s,
@@ -365,7 +388,7 @@ function ae(e) {
365
388
  }
366
389
  };
367
390
  }
368
- function ne(e) {
391
+ function re(e) {
369
392
  const {
370
393
  controlPlaneTenantId: t,
371
394
  getChildTenantIds: s,
@@ -426,7 +449,7 @@ function ne(e) {
426
449
  }
427
450
  };
428
451
  }
429
- function re(e) {
452
+ function se(e) {
430
453
  const {
431
454
  controlPlaneTenantId: t,
432
455
  getControlPlaneAdapters: s,
@@ -451,11 +474,11 @@ function re(e) {
451
474
  const h = n ? n(g, c.id) : {
452
475
  name: g.name,
453
476
  description: g.description
454
- }, T = await f.roles.create(c.id, {
477
+ }, A = await f.roles.create(c.id, {
455
478
  ...h,
456
479
  is_system: !0
457
480
  });
458
- o.set(g.id, T.id);
481
+ o.set(g.id, A.id);
459
482
  } catch (h) {
460
483
  console.error(
461
484
  `Failed to sync role "${g.name}" to new tenant "${c.id}":`,
@@ -474,10 +497,10 @@ function re(e) {
474
497
  h.length > 0 && await f.rolePermissions.assign(
475
498
  c.id,
476
499
  g,
477
- h.map((T) => ({
500
+ h.map((A) => ({
478
501
  role_id: g,
479
- resource_server_identifier: T.resource_server_identifier,
480
- permission_name: T.permission_name
502
+ resource_server_identifier: A.resource_server_identifier,
503
+ permission_name: A.permission_name
481
504
  }))
482
505
  );
483
506
  } catch (h) {
@@ -495,7 +518,7 @@ function re(e) {
495
518
  }
496
519
  };
497
520
  }
498
- function j(e, t) {
521
+ function O(e, t) {
499
522
  const s = new Q();
500
523
  return s.openapi(
501
524
  M({
@@ -515,7 +538,7 @@ function j(e, t) {
515
538
  content: {
516
539
  "application/json": {
517
540
  schema: P.object({
518
- tenants: P.array(O),
541
+ tenants: P.array(q),
519
542
  start: P.number().optional(),
520
543
  limit: P.number().optional(),
521
544
  length: P.number().optional()
@@ -527,26 +550,26 @@ function j(e, t) {
527
550
  }
528
551
  }),
529
552
  async (a) => {
530
- var p, g, h, T;
553
+ var p, g, h, A;
531
554
  const i = a.req.valid("query"), { page: n, per_page: u, include_totals: l, q: c } = i, r = a.var.user, f = ((r == null ? void 0 : r.scope) || "").split(" "), d = f.includes("auth:read");
532
555
  if (console.log("User scopes:", f, "hasAuthRead:", d), d) {
533
- const b = await a.env.data.tenants.list({
556
+ const C = await a.env.data.tenants.list({
534
557
  page: n,
535
558
  per_page: u,
536
559
  include_totals: l,
537
560
  q: c
538
561
  });
539
562
  return l ? a.json({
540
- tenants: b.tenants,
541
- start: ((p = b.totals) == null ? void 0 : p.start) ?? 0,
542
- limit: ((g = b.totals) == null ? void 0 : g.limit) ?? u,
543
- length: b.tenants.length
544
- }) : a.json({ tenants: b.tenants });
563
+ tenants: C.tenants,
564
+ start: ((p = C.totals) == null ? void 0 : p.start) ?? 0,
565
+ limit: ((g = C.totals) == null ? void 0 : g.limit) ?? u,
566
+ length: C.tenants.length
567
+ }) : a.json({ tenants: C.tenants });
545
568
  }
546
569
  if (e.accessControl && (r != null && r.sub)) {
547
- const b = e.accessControl.controlPlaneTenantId, $ = (await S(
570
+ const C = e.accessControl.controlPlaneTenantId, $ = (await S(
548
571
  (R) => a.env.data.userOrganizations.listUserOrganizations(
549
- b,
572
+ C,
550
573
  r.sub,
551
574
  R
552
575
  ),
@@ -567,18 +590,18 @@ function j(e, t) {
567
590
  limit: v,
568
591
  length: z
569
592
  }) : a.json({ tenants: [] });
570
- const y = m.map((R) => `id:${R}`).join(" OR "), _ = c ? `(${y}) AND (${c})` : y, A = await a.env.data.tenants.list({
593
+ const y = m.map((R) => `id:${R}`).join(" OR "), _ = c ? `(${y}) AND (${c})` : y, b = await a.env.data.tenants.list({
571
594
  q: _,
572
595
  per_page: v,
573
596
  include_totals: !1
574
597
  // We calculate totals from accessibleTenantIds
575
598
  });
576
599
  return l ? a.json({
577
- tenants: A.tenants,
600
+ tenants: b.tenants,
578
601
  start: w,
579
602
  limit: v,
580
603
  length: z
581
- }) : a.json({ tenants: A.tenants });
604
+ }) : a.json({ tenants: b.tenants });
582
605
  }
583
606
  const o = await a.env.data.tenants.list({
584
607
  page: n,
@@ -589,7 +612,7 @@ function j(e, t) {
589
612
  return l ? a.json({
590
613
  tenants: o.tenants,
591
614
  start: ((h = o.totals) == null ? void 0 : h.start) ?? 0,
592
- limit: ((T = o.totals) == null ? void 0 : T.limit) ?? u,
615
+ limit: ((A = o.totals) == null ? void 0 : A.limit) ?? u,
593
616
  length: o.tenants.length
594
617
  }) : a.json({ tenants: o.tenants });
595
618
  }
@@ -616,7 +639,7 @@ function j(e, t) {
616
639
  201: {
617
640
  content: {
618
641
  "application/json": {
619
- schema: O
642
+ schema: q
620
643
  }
621
644
  },
622
645
  description: "Tenant created"
@@ -633,7 +656,7 @@ function j(e, t) {
633
656
  var c, r;
634
657
  const i = a.var.user;
635
658
  if (!(i != null && i.sub))
636
- throw new C(401, {
659
+ throw new T(401, {
637
660
  message: "Authentication required to create tenants"
638
661
  });
639
662
  let n = a.req.valid("json");
@@ -678,11 +701,11 @@ function j(e, t) {
678
701
  if (e.accessControl) {
679
702
  const r = a.var.user, f = e.accessControl.controlPlaneTenantId;
680
703
  if (!(r != null && r.sub))
681
- throw new C(401, {
704
+ throw new T(401, {
682
705
  message: "Authentication required"
683
706
  });
684
707
  if (i === f)
685
- throw new C(403, {
708
+ throw new T(403, {
686
709
  message: "Cannot delete the control plane"
687
710
  });
688
711
  if (!(await S(
@@ -693,12 +716,12 @@ function j(e, t) {
693
716
  ),
694
717
  "organizations"
695
718
  )).some((p) => p.name === i))
696
- throw new C(403, {
719
+ throw new T(403, {
697
720
  message: "Access denied to this tenant"
698
721
  });
699
722
  }
700
723
  if (!await a.env.data.tenants.get(i))
701
- throw new C(404, {
724
+ throw new T(404, {
702
725
  message: "Tenant not found"
703
726
  });
704
727
  const u = {
@@ -709,7 +732,7 @@ function j(e, t) {
709
732
  }
710
733
  ), s;
711
734
  }
712
- function se(e) {
735
+ function ie(e) {
713
736
  const t = [
714
737
  {
715
738
  pattern: /\/api\/v2\/resource-servers\/([^/]+)$/,
@@ -725,7 +748,7 @@ function se(e) {
725
748
  }
726
749
  return null;
727
750
  }
728
- async function ie(e, t, s) {
751
+ async function oe(e, t, s) {
729
752
  try {
730
753
  switch (s.type) {
731
754
  case "resource_server": {
@@ -747,37 +770,37 @@ async function ie(e, t, s) {
747
770
  return !1;
748
771
  }
749
772
  }
750
- function oe(e) {
773
+ function ce(e) {
751
774
  return {
752
775
  resource_server: "resource server",
753
776
  role: "role",
754
777
  connection: "connection"
755
778
  }[e];
756
779
  }
757
- function ce() {
780
+ function le() {
758
781
  return async (e, t) => {
759
782
  if (!["PATCH", "PUT", "DELETE"].includes(e.req.method))
760
783
  return t();
761
- const s = se(e.req.path);
784
+ const s = ie(e.req.path);
762
785
  if (!s)
763
786
  return t();
764
787
  const a = e.var.tenant_id || e.req.header("x-tenant-id") || e.req.header("tenant-id");
765
788
  if (!a)
766
789
  return t();
767
- if (await ie(e.env.data, a, s))
768
- throw new C(403, {
769
- message: `This ${oe(s.type)} is a system resource and cannot be modified. Make changes in the control plane instead.`
790
+ if (await oe(e.env.data, a, s))
791
+ throw new T(403, {
792
+ message: `This ${ce(s.type)} is a system resource and cannot be modified. Make changes in the control plane instead.`
770
793
  });
771
794
  return t();
772
795
  };
773
796
  }
774
- function le(e) {
797
+ function de(e) {
775
798
  return async (t, s) => {
776
799
  if (!e.accessControl)
777
800
  return s();
778
801
  const a = t.var.tenant_id, i = t.var.organization_id;
779
802
  if (!a)
780
- throw new C(400, {
803
+ throw new T(400, {
781
804
  message: "Tenant ID not found in request"
782
805
  });
783
806
  if (!Y(
@@ -785,13 +808,13 @@ function le(e) {
785
808
  a,
786
809
  e.accessControl.controlPlaneTenantId
787
810
  ))
788
- throw new C(403, {
811
+ throw new T(403, {
789
812
  message: `Access denied to tenant ${a}`
790
813
  });
791
814
  return s();
792
815
  };
793
816
  }
794
- function de(e) {
817
+ function ue(e) {
795
818
  return async (t, s) => {
796
819
  if (!e.subdomainRouting)
797
820
  return s();
@@ -820,19 +843,19 @@ function de(e) {
820
843
  } catch {
821
844
  }
822
845
  if (!c)
823
- throw new C(404, {
846
+ throw new T(404, {
824
847
  message: `Tenant not found for subdomain: ${l}`
825
848
  });
826
849
  return t.set("tenant_id", c), s();
827
850
  };
828
851
  }
829
- function ue(e) {
852
+ function fe(e) {
830
853
  return async (t, s) => {
831
854
  if (!e.databaseIsolation)
832
855
  return s();
833
856
  const a = t.var.tenant_id;
834
857
  if (!a)
835
- throw new C(400, {
858
+ throw new T(400, {
836
859
  message: "Tenant ID not found in request"
837
860
  });
838
861
  try {
@@ -842,7 +865,7 @@ function ue(e) {
842
865
  throw console.error(
843
866
  `Failed to resolve database for tenant ${a}:`,
844
867
  i
845
- ), new C(500, {
868
+ ), new T(500, {
846
869
  message: "Failed to resolve tenant database"
847
870
  });
848
871
  }
@@ -850,13 +873,13 @@ function ue(e) {
850
873
  };
851
874
  }
852
875
  function N(e) {
853
- const t = de(e), s = le(e), a = ue(e);
876
+ const t = ue(e), s = de(e), a = fe(e);
854
877
  return async (i, n) => (await t(i, async () => {
855
878
  }), await s(i, async () => {
856
879
  }), await a(i, async () => {
857
880
  }), n());
858
881
  }
859
- function ge(e) {
882
+ function _e(e) {
860
883
  const t = I(e);
861
884
  return {
862
885
  name: "multi-tenancy",
@@ -868,7 +891,7 @@ function ge(e) {
868
891
  routes: [
869
892
  {
870
893
  path: "/management",
871
- handler: j(e, t)
894
+ handler: O(e, t)
872
895
  }
873
896
  ],
874
897
  // Called when plugin is registered
@@ -889,19 +912,19 @@ function I(e) {
889
912
  tenants: a
890
913
  };
891
914
  }
892
- function fe(e) {
915
+ function pe(e) {
893
916
  const t = new U(), s = I(e);
894
- return t.route("/tenants", j(e, s)), t;
917
+ return t.route("/tenants", O(e, s)), t;
895
918
  }
896
- function _e(e) {
919
+ function Ae(e) {
897
920
  return {
898
921
  hooks: I(e),
899
922
  middleware: N(e),
900
- app: fe(e),
923
+ app: pe(e),
901
924
  config: e
902
925
  };
903
926
  }
904
- function Te(e) {
927
+ function be(e) {
905
928
  const {
906
929
  controlPlaneTenantId: t = "control_plane",
907
930
  syncResourceServers: s = !0,
@@ -919,7 +942,7 @@ function Te(e) {
919
942
  }
920
943
  }, c = I(l);
921
944
  let r, f;
922
- s && (r = te({
945
+ s && (r = ae({
923
946
  controlPlaneTenantId: t,
924
947
  getChildTenantIds: async () => (await S(
925
948
  (m) => e.dataAdapter.tenants.list(m),
@@ -927,13 +950,13 @@ function Te(e) {
927
950
  { cursorField: "id", pageSize: 100 }
928
951
  )).filter((m) => m.id !== t).map((m) => m.id),
929
952
  getAdapters: async (w) => e.dataAdapter
930
- }), f = ae({
953
+ }), f = ne({
931
954
  controlPlaneTenantId: t,
932
955
  getControlPlaneAdapters: async () => e.dataAdapter,
933
956
  getAdapters: async (w) => e.dataAdapter
934
957
  }));
935
958
  let d, o;
936
- a && (d = ne({
959
+ a && (d = re({
937
960
  controlPlaneTenantId: t,
938
961
  getChildTenantIds: async () => (await S(
939
962
  (m) => e.dataAdapter.tenants.list(m),
@@ -941,7 +964,7 @@ function Te(e) {
941
964
  { cursorField: "id", pageSize: 100 }
942
965
  )).filter((m) => m.id !== t).map((m) => m.id),
943
966
  getAdapters: async (w) => e.dataAdapter
944
- }), o = re({
967
+ }), o = se({
945
968
  controlPlaneTenantId: t,
946
969
  getControlPlaneAdapters: async () => e.dataAdapter,
947
970
  getAdapters: async (w) => e.dataAdapter,
@@ -952,21 +975,21 @@ function Te(e) {
952
975
  if (w)
953
976
  try {
954
977
  await w(...y);
955
- } catch (A) {
956
- _.push(A instanceof Error ? A : new Error(String(A)));
978
+ } catch (b) {
979
+ _.push(b instanceof Error ? b : new Error(String(b)));
957
980
  }
958
981
  if (m)
959
982
  try {
960
983
  await m(...y);
961
- } catch (A) {
962
- _.push(A instanceof Error ? A : new Error(String(A)));
984
+ } catch (b) {
985
+ _.push(b instanceof Error ? b : new Error(String(b)));
963
986
  }
964
987
  if (_.length === 1)
965
988
  throw _[0];
966
989
  if (_.length > 1)
967
990
  throw new AggregateError(
968
991
  _,
969
- `Multiple hook errors: ${_.map((A) => A.message).join("; ")}`
992
+ `Multiple hook errors: ${_.map((b) => b.message).join("; ")}`
970
993
  );
971
994
  }, g = async (w, ...m) => {
972
995
  const y = [];
@@ -974,9 +997,9 @@ function Te(e) {
974
997
  if (_)
975
998
  try {
976
999
  await _(...m);
977
- } catch (A) {
1000
+ } catch (b) {
978
1001
  y.push(
979
- A instanceof Error ? A : new Error(String(A))
1002
+ b instanceof Error ? b : new Error(String(b))
980
1003
  );
981
1004
  }
982
1005
  if (y.length === 1)
@@ -1065,7 +1088,7 @@ function Te(e) {
1065
1088
  );
1066
1089
  }
1067
1090
  } : n == null ? void 0 : n.tenants
1068
- }, T = {
1091
+ }, A = {
1069
1092
  ...c,
1070
1093
  tenants: f || o ? {
1071
1094
  ...c.tenants,
@@ -1081,20 +1104,20 @@ function Te(e) {
1081
1104
  );
1082
1105
  }
1083
1106
  } : c.tenants
1084
- }, b = j(
1107
+ }, C = O(
1085
1108
  l,
1086
- T
1087
- ), q = L({
1109
+ A
1110
+ ), j = L({
1088
1111
  ...u,
1089
1112
  entityHooks: h,
1090
1113
  // Register tenant routes via the extension mechanism
1091
1114
  // This ensures they go through the full middleware chain (caching, tenant, auth, entity hooks)
1092
1115
  managementApiExtensions: [
1093
1116
  ...u.managementApiExtensions || [],
1094
- { path: "/tenants", router: b }
1117
+ { path: "/tenants", router: C }
1095
1118
  ]
1096
- }), { app: $, managementApp: z, ...F } = q, v = new U();
1097
- return v.onError((w, m) => w instanceof C ? w.getResponse() : (console.error(w), m.json({ message: "Internal Server Error" }, 500))), v.use("/api/v2/*", ce()), v.route("/", $), {
1119
+ }), { app: $, managementApp: z, ...F } = j, v = new U();
1120
+ return v.onError((w, m) => w instanceof T ? w.getResponse() : (console.error(w), m.json({ message: "Internal Server Error" }, 500))), v.use("/api/v2/*", le()), v.route("/", $), {
1098
1121
  app: v,
1099
1122
  managementApp: z,
1100
1123
  ...F,
@@ -1103,26 +1126,26 @@ function Te(e) {
1103
1126
  };
1104
1127
  }
1105
1128
  export {
1106
- ve as MANAGEMENT_API_SCOPES,
1129
+ Ce as MANAGEMENT_API_SCOPES,
1107
1130
  X as createAccessControlHooks,
1108
- le as createAccessControlMiddleware,
1131
+ de as createAccessControlMiddleware,
1109
1132
  Z as createDatabaseHooks,
1110
- ue as createDatabaseMiddleware,
1111
- fe as createMultiTenancy,
1133
+ fe as createDatabaseMiddleware,
1134
+ pe as createMultiTenancy,
1112
1135
  I as createMultiTenancyHooks,
1113
1136
  N as createMultiTenancyMiddleware,
1114
- ge as createMultiTenancyPlugin,
1115
- ce as createProtectSyncedMiddleware,
1137
+ _e as createMultiTenancyPlugin,
1138
+ le as createProtectSyncedMiddleware,
1116
1139
  k as createProvisioningHooks,
1117
- te as createResourceServerSyncHooks,
1118
- ne as createRoleSyncHooks,
1119
- de as createSubdomainMiddleware,
1120
- ae as createTenantResourceServerSyncHooks,
1121
- re as createTenantRoleSyncHooks,
1122
- j as createTenantsOpenAPIRouter,
1123
- be as fetchAll,
1124
- Te as init,
1125
- Pe as seed,
1126
- _e as setupMultiTenancy,
1140
+ ae as createResourceServerSyncHooks,
1141
+ re as createRoleSyncHooks,
1142
+ ue as createSubdomainMiddleware,
1143
+ ne as createTenantResourceServerSyncHooks,
1144
+ se as createTenantRoleSyncHooks,
1145
+ O as createTenantsOpenAPIRouter,
1146
+ Pe as fetchAll,
1147
+ be as init,
1148
+ Se as seed,
1149
+ Ae as setupMultiTenancy,
1127
1150
  Y as validateTenantAccess
1128
1151
  };
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.11.0",
14
+ "version": "13.12.1",
15
15
  "description": "Multi-tenancy support for AuthHero with organization-based access control and per-tenant database isolation",
16
16
  "files": [
17
17
  "dist"
@@ -37,12 +37,12 @@
37
37
  "typescript": "^5.6.0",
38
38
  "vite": "^6.0.0",
39
39
  "vitest": "^2.1.0",
40
- "@authhero/kysely-adapter": "10.74.0"
40
+ "@authhero/kysely-adapter": "10.75.0"
41
41
  },
42
42
  "dependencies": {
43
43
  "zod": "^3.24.0",
44
- "@authhero/adapter-interfaces": "0.114.0",
45
- "authhero": "1.1.0"
44
+ "@authhero/adapter-interfaces": "0.115.0",
45
+ "authhero": "1.3.0"
46
46
  },
47
47
  "peerDependencies": {
48
48
  "@hono/zod-openapi": "^0.19.10",