@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.
- package/dist/multi-tenancy.cjs +1 -1
- package/dist/multi-tenancy.d.ts +55 -0
- package/dist/multi-tenancy.mjs +130 -107
- package/package.json +4 -4
package/dist/multi-tenancy.cjs
CHANGED
|
@@ -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;
|
package/dist/multi-tenancy.d.ts
CHANGED
|
@@ -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
|
} & {
|
package/dist/multi-tenancy.mjs
CHANGED
|
@@ -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
|
|
6
|
-
import { MANAGEMENT_API_SCOPES as
|
|
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
|
|
9
|
-
var
|
|
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:
|
|
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
|
|
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
|
|
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 (
|
|
151
|
+
} catch (g) {
|
|
148
152
|
console.warn(
|
|
149
153
|
`Failed to add creator ${o.sub} to organization ${f.id}:`,
|
|
150
|
-
|
|
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
|
|
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 =
|
|
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
|
|
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
|
|
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
|
|
270
|
+
const A = await u(
|
|
248
271
|
p,
|
|
249
272
|
o,
|
|
250
273
|
r.identifier
|
|
251
274
|
);
|
|
252
|
-
|
|
275
|
+
A && A.id ? await p.resourceServers.update(
|
|
253
276
|
o,
|
|
254
|
-
|
|
277
|
+
A.id,
|
|
255
278
|
h
|
|
256
279
|
) : await p.resourceServers.create(o, h);
|
|
257
280
|
} else {
|
|
258
|
-
const
|
|
281
|
+
const A = await u(
|
|
259
282
|
p,
|
|
260
283
|
o,
|
|
261
284
|
r.identifier
|
|
262
285
|
);
|
|
263
|
-
|
|
286
|
+
A && A.id ? await p.resourceServers.update(
|
|
264
287
|
o,
|
|
265
|
-
|
|
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
|
|
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
|
|
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
|
|
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
|
-
},
|
|
477
|
+
}, A = await f.roles.create(c.id, {
|
|
455
478
|
...h,
|
|
456
479
|
is_system: !0
|
|
457
480
|
});
|
|
458
|
-
o.set(g.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((
|
|
500
|
+
h.map((A) => ({
|
|
478
501
|
role_id: g,
|
|
479
|
-
resource_server_identifier:
|
|
480
|
-
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
|
|
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(
|
|
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,
|
|
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
|
|
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:
|
|
541
|
-
start: ((p =
|
|
542
|
-
limit: ((g =
|
|
543
|
-
length:
|
|
544
|
-
}) : a.json({ 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
|
|
570
|
+
const C = e.accessControl.controlPlaneTenantId, $ = (await S(
|
|
548
571
|
(R) => a.env.data.userOrganizations.listUserOrganizations(
|
|
549
|
-
|
|
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,
|
|
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:
|
|
600
|
+
tenants: b.tenants,
|
|
578
601
|
start: w,
|
|
579
602
|
limit: v,
|
|
580
603
|
length: z
|
|
581
|
-
}) : a.json({ 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: ((
|
|
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:
|
|
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
|
|
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
|
|
704
|
+
throw new T(401, {
|
|
682
705
|
message: "Authentication required"
|
|
683
706
|
});
|
|
684
707
|
if (i === f)
|
|
685
|
-
throw new
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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 =
|
|
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
|
|
768
|
-
throw new
|
|
769
|
-
message: `This ${
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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 =
|
|
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
|
|
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:
|
|
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
|
|
915
|
+
function pe(e) {
|
|
893
916
|
const t = new U(), s = I(e);
|
|
894
|
-
return t.route("/tenants",
|
|
917
|
+
return t.route("/tenants", O(e, s)), t;
|
|
895
918
|
}
|
|
896
|
-
function
|
|
919
|
+
function Ae(e) {
|
|
897
920
|
return {
|
|
898
921
|
hooks: I(e),
|
|
899
922
|
middleware: N(e),
|
|
900
|
-
app:
|
|
923
|
+
app: pe(e),
|
|
901
924
|
config: e
|
|
902
925
|
};
|
|
903
926
|
}
|
|
904
|
-
function
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 (
|
|
956
|
-
_.push(
|
|
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 (
|
|
962
|
-
_.push(
|
|
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((
|
|
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 (
|
|
1000
|
+
} catch (b) {
|
|
978
1001
|
y.push(
|
|
979
|
-
|
|
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
|
-
},
|
|
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
|
-
},
|
|
1107
|
+
}, C = O(
|
|
1085
1108
|
l,
|
|
1086
|
-
|
|
1087
|
-
),
|
|
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:
|
|
1117
|
+
{ path: "/tenants", router: C }
|
|
1095
1118
|
]
|
|
1096
|
-
}), { app: $, managementApp: z, ...F } =
|
|
1097
|
-
return v.onError((w, m) => w instanceof
|
|
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
|
-
|
|
1129
|
+
Ce as MANAGEMENT_API_SCOPES,
|
|
1107
1130
|
X as createAccessControlHooks,
|
|
1108
|
-
|
|
1131
|
+
de as createAccessControlMiddleware,
|
|
1109
1132
|
Z as createDatabaseHooks,
|
|
1110
|
-
|
|
1111
|
-
|
|
1133
|
+
fe as createDatabaseMiddleware,
|
|
1134
|
+
pe as createMultiTenancy,
|
|
1112
1135
|
I as createMultiTenancyHooks,
|
|
1113
1136
|
N as createMultiTenancyMiddleware,
|
|
1114
|
-
|
|
1115
|
-
|
|
1137
|
+
_e as createMultiTenancyPlugin,
|
|
1138
|
+
le as createProtectSyncedMiddleware,
|
|
1116
1139
|
k as createProvisioningHooks,
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
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.
|
|
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.
|
|
40
|
+
"@authhero/kysely-adapter": "10.75.0"
|
|
41
41
|
},
|
|
42
42
|
"dependencies": {
|
|
43
43
|
"zod": "^3.24.0",
|
|
44
|
-
"@authhero/adapter-interfaces": "0.
|
|
45
|
-
"authhero": "1.
|
|
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",
|