@authhero/multi-tenancy 13.12.0 → 13.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/multi-tenancy.cjs +1 -1
- package/dist/multi-tenancy.d.ts +55 -0
- package/dist/multi-tenancy.mjs +156 -156
- 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 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;
|
|
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 D=(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});D(this,"res");D(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,d=a.var.organization_id,l=n||d;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 d=(await t.adapters.organizations.list(a.controlPlaneTenantId)).organizations.find(l=>l.name===s);d&&await t.adapters.organizations.remove(a.controlPlaneTenantId,d.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:d,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 u;if(d&&(u=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}),u&&await e.adapters.userRoles.create(a,o.sub,u,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 d=await e.adapters.roles.create(t,{name:s,description:a}),l=T.MANAGEMENT_API_AUDIENCE,c=T.MANAGEMENT_API_SCOPES.map(r=>({role_id:d.id,resource_server_identifier:l,permission_name:r.value}));return await e.adapters.rolePermissions.assign(t,d.id,c),d.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 d={...n};const l=["id","created_at","updated_at","friendly_name","audience","sender_email","sender_name"];for(const c of l)delete d[c];if(i!=null&&i.inheritedKeys){const c={};for(const r of i.inheritedKeys)r in n&&!l.includes(r)&&(c[r]=n[r]);d=c}if(i!=null&&i.excludedKeys)for(const c of i.excludedKeys)delete d[c];i!=null&&i.transformSettings&&(d=i.transformSettings(d,t.id)),Object.keys(d).length>0&&await e.adapters.tenants.update(t.id,d)}function B(e){const{controlPlaneTenantId:t,getChildTenantIds:s,getAdapters:a,shouldSync:i=()=>!0,transformForSync:n}=e;async function d(r,f,u){return(await r.resourceServers.list(f,{q:`identifier:${u}`,per_page:1})).resource_servers[0]??null}async function l(r,f){const u=await s();await Promise.all(u.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 d(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 d(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 u=>{try{const o=await a(u),p=await d(o,u,r);p&&p.id&&await o.resourceServers.remove(u,p.id)}catch(o){console.error(`Failed to delete resource server "${r}" from tenant "${u}":`,o)}}))}return{afterCreate:async(r,f)=>{r.tenantId===t&&i(f)&&await l(f,"create")},afterUpdate:async(r,f,u)=>{r.tenantId===t&&i(u)&&await l(u,"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(d,l){if(l.id!==t)try{const c=await s(),r=await a(l.id),f=await T.fetchAll(u=>c.resourceServers.list(t,u),"resource_servers",{cursorField:"id",pageSize:100});await Promise.all(f.filter(u=>i(u)).map(async u=>{const o=u;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 d(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 u=>{try{const o=await a(u),g={...n?n(c,u):{name:c.name,description:c.description},is_system:!0};if(r==="create"){const h=await d(o,u,c.name);h&&h.id?await o.roles.update(u,h.id,g):await o.roles.create(u,g)}else{const h=await d(o,u,c.name);h&&h.id?await o.roles.update(u,h.id,g):await o.roles.create(u,g)}}catch(o){console.error(`Failed to sync role "${c.name}" to tenant "${u}":`,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:d=!0}=e;return{async afterCreate(l,c){if(c.id!==t)try{const r=await s(),f=await a(c.id),u=await T.fetchAll(p=>r.roles.list(t,p),"roles",{cursorField:"id",pageSize:100}),o=new Map;if(await Promise.all(u.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)}})),d)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:d,include_totals:l,q:c}=i,r=a.var.user,f=(r==null?void 0:r.permissions)||[];if(f.includes("auth:read")||f.includes("admin:organizations")){const S=await a.env.data.tenants.list({page:n,per_page:d,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)??d,length:S.tenants.length}):a.json({tenants:S.tenants})}if(e.accessControl&&(r!=null&&r.sub)){const S=e.accessControl.controlPlaneTenantId,z=(await T.fetchAll(M=>a.env.data.userOrganizations.listUserOrganizations(S,r.sub,M),"organizations")).map(M=>M.name);if(z.length===0)return l?a.json({tenants:[],start:0,limit:d??50,length:0}):a.json({tenants:[]});const $=z.length,F=n??0,P=d??50,w=F*P,m=z.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:d,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)??d,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 d={adapters:a.env.data,ctx:a};(c=t.tenants)!=null&&c.beforeCreate&&(n=await t.tenants.beforeCreate(d,n));const l=await a.env.data.tenants.create(n);return(r=t.tenants)!=null&&r.afterCreate&&await t.tenants.afterCreate(d,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 d={adapters:a.env.data,ctx:a};return(l=t.tenants)!=null&&l.beforeDelete&&await t.tenants.beforeDelete(d,i),await a.env.data.tenants.remove(i),(c=t.tenants)!=null&&c.afterDelete&&await t.tenants.afterDelete(d,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,d=t.req.header("host")||"";let l=null;if(d.endsWith(a)){const r=d.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=R(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 R(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=R(e);return t.route("/tenants",O(e,s)),t}function oe(e){return{hooks:R(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,...d}=e,l={...i,accessControl:{controlPlaneTenantId:t,requireOrganizationMatch:!1,defaultPermissions:["tenant:admin"],...i==null?void 0:i.accessControl}},c=R(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 u,o;a&&(u=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:u?{...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,u==null?void 0:u.afterCreate,w,m)},afterUpdate:async(w,m,y)=>{var _;await p((_=n==null?void 0:n.roles)==null?void 0:_.afterUpdate,u==null?void 0:u.afterUpdate,w,m,y)},afterDelete:async(w,m)=>{var y;await p((y=n==null?void 0:n.roles)==null?void 0:y.afterDelete,u==null?void 0:u.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({...d,entityHooks:h,managementApiExtensions:[...d.managementApiExtensions||[],{path:"/tenants",router:S}]}),{app:z,managementApp:$,...F}=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("/",z),{app:P,managementApp:$,...F,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=R;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
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
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
|
-
import { Hono as
|
|
4
|
+
import { Hono as N } from "hono";
|
|
5
5
|
import { getTenantAudience as G, MANAGEMENT_API_SCOPES as B, MANAGEMENT_API_AUDIENCE as W, fetchAll as S, init as L } from "authhero";
|
|
6
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";
|
|
@@ -39,7 +39,7 @@ function X(e) {
|
|
|
39
39
|
if (i === t)
|
|
40
40
|
return !0;
|
|
41
41
|
if (s) {
|
|
42
|
-
const n = a.var.org_name,
|
|
42
|
+
const n = a.var.org_name, d = a.var.organization_id, l = n || d;
|
|
43
43
|
return l ? l === i : !1;
|
|
44
44
|
}
|
|
45
45
|
return !0;
|
|
@@ -83,12 +83,12 @@ function k(e) {
|
|
|
83
83
|
const { accessControl: a, databaseIsolation: i } = e;
|
|
84
84
|
if (a)
|
|
85
85
|
try {
|
|
86
|
-
const
|
|
86
|
+
const d = (await t.adapters.organizations.list(
|
|
87
87
|
a.controlPlaneTenantId
|
|
88
88
|
)).organizations.find((l) => l.name === s);
|
|
89
|
-
|
|
89
|
+
d && await t.adapters.organizations.remove(
|
|
90
90
|
a.controlPlaneTenantId,
|
|
91
|
-
|
|
91
|
+
d.id
|
|
92
92
|
);
|
|
93
93
|
} catch (n) {
|
|
94
94
|
console.warn(
|
|
@@ -113,7 +113,7 @@ async function H(e, t, s) {
|
|
|
113
113
|
controlPlaneTenantId: a,
|
|
114
114
|
defaultPermissions: i,
|
|
115
115
|
defaultRoles: n,
|
|
116
|
-
issuer:
|
|
116
|
+
issuer: d,
|
|
117
117
|
adminRoleName: l = "Tenant Admin",
|
|
118
118
|
adminRoleDescription: c = "Full access to all tenant management operations",
|
|
119
119
|
addCreatorToOrganization: r = !0
|
|
@@ -124,8 +124,8 @@ async function H(e, t, s) {
|
|
|
124
124
|
display_name: t.friendly_name || t.id
|
|
125
125
|
}
|
|
126
126
|
);
|
|
127
|
-
let
|
|
128
|
-
if (
|
|
127
|
+
let u;
|
|
128
|
+
if (d && (u = await ee(
|
|
129
129
|
e,
|
|
130
130
|
a,
|
|
131
131
|
l,
|
|
@@ -141,10 +141,10 @@ async function H(e, t, s) {
|
|
|
141
141
|
await e.adapters.userOrganizations.create(a, {
|
|
142
142
|
user_id: o.sub,
|
|
143
143
|
organization_id: f.id
|
|
144
|
-
}),
|
|
144
|
+
}), u && await e.adapters.userRoles.create(
|
|
145
145
|
a,
|
|
146
146
|
o.sub,
|
|
147
|
-
|
|
147
|
+
u,
|
|
148
148
|
f.id
|
|
149
149
|
// organizationId
|
|
150
150
|
);
|
|
@@ -184,19 +184,19 @@ async function ee(e, t, s, a) {
|
|
|
184
184
|
const n = (await e.adapters.roles.list(t, {})).roles.find((r) => r.name === s);
|
|
185
185
|
if (n)
|
|
186
186
|
return n.id;
|
|
187
|
-
const
|
|
187
|
+
const d = await e.adapters.roles.create(t, {
|
|
188
188
|
name: s,
|
|
189
189
|
description: a
|
|
190
190
|
}), l = W, c = B.map((r) => ({
|
|
191
|
-
role_id:
|
|
191
|
+
role_id: d.id,
|
|
192
192
|
resource_server_identifier: l,
|
|
193
193
|
permission_name: r.value
|
|
194
194
|
}));
|
|
195
195
|
return await e.adapters.rolePermissions.assign(
|
|
196
196
|
t,
|
|
197
|
-
|
|
197
|
+
d.id,
|
|
198
198
|
c
|
|
199
|
-
),
|
|
199
|
+
), d.id;
|
|
200
200
|
}
|
|
201
201
|
async function te(e, t, s) {
|
|
202
202
|
const { accessControl: a, settingsInheritance: i } = s;
|
|
@@ -207,7 +207,7 @@ async function te(e, t, s) {
|
|
|
207
207
|
);
|
|
208
208
|
if (!n)
|
|
209
209
|
return;
|
|
210
|
-
let
|
|
210
|
+
let d = { ...n };
|
|
211
211
|
const l = [
|
|
212
212
|
"id",
|
|
213
213
|
"created_at",
|
|
@@ -219,20 +219,20 @@ async function te(e, t, s) {
|
|
|
219
219
|
"sender_name"
|
|
220
220
|
];
|
|
221
221
|
for (const c of l)
|
|
222
|
-
delete
|
|
222
|
+
delete d[c];
|
|
223
223
|
if (i != null && i.inheritedKeys) {
|
|
224
224
|
const c = {};
|
|
225
225
|
for (const r of i.inheritedKeys)
|
|
226
226
|
r in n && !l.includes(r) && (c[r] = n[r]);
|
|
227
|
-
|
|
227
|
+
d = c;
|
|
228
228
|
}
|
|
229
229
|
if (i != null && i.excludedKeys)
|
|
230
230
|
for (const c of i.excludedKeys)
|
|
231
|
-
delete
|
|
232
|
-
i != null && i.transformSettings && (
|
|
233
|
-
|
|
231
|
+
delete d[c];
|
|
232
|
+
i != null && i.transformSettings && (d = i.transformSettings(
|
|
233
|
+
d,
|
|
234
234
|
t.id
|
|
235
|
-
)), Object.keys(
|
|
235
|
+
)), Object.keys(d).length > 0 && await e.adapters.tenants.update(t.id, d);
|
|
236
236
|
}
|
|
237
237
|
function ae(e) {
|
|
238
238
|
const {
|
|
@@ -242,18 +242,18 @@ function ae(e) {
|
|
|
242
242
|
shouldSync: i = () => !0,
|
|
243
243
|
transformForSync: n
|
|
244
244
|
} = e;
|
|
245
|
-
async function
|
|
245
|
+
async function d(r, f, u) {
|
|
246
246
|
return (await r.resourceServers.list(f, {
|
|
247
|
-
q: `identifier:${
|
|
247
|
+
q: `identifier:${u}`,
|
|
248
248
|
per_page: 1
|
|
249
249
|
})).resource_servers[0] ?? null;
|
|
250
250
|
}
|
|
251
251
|
async function l(r, f) {
|
|
252
|
-
const
|
|
252
|
+
const u = await s();
|
|
253
253
|
await Promise.all(
|
|
254
|
-
|
|
254
|
+
u.map(async (o) => {
|
|
255
255
|
try {
|
|
256
|
-
const
|
|
256
|
+
const m = await a(o), h = { ...n ? n(r, o) : {
|
|
257
257
|
name: r.name,
|
|
258
258
|
identifier: r.identifier,
|
|
259
259
|
scopes: r.scopes,
|
|
@@ -267,32 +267,32 @@ function ae(e) {
|
|
|
267
267
|
options: r.options
|
|
268
268
|
}, is_system: !0 };
|
|
269
269
|
if (f === "create") {
|
|
270
|
-
const A = await
|
|
271
|
-
|
|
270
|
+
const A = await d(
|
|
271
|
+
m,
|
|
272
272
|
o,
|
|
273
273
|
r.identifier
|
|
274
274
|
);
|
|
275
|
-
A && A.id ? await
|
|
275
|
+
A && A.id ? await m.resourceServers.update(
|
|
276
276
|
o,
|
|
277
277
|
A.id,
|
|
278
278
|
h
|
|
279
|
-
) : await
|
|
279
|
+
) : await m.resourceServers.create(o, h);
|
|
280
280
|
} else {
|
|
281
|
-
const A = await
|
|
282
|
-
|
|
281
|
+
const A = await d(
|
|
282
|
+
m,
|
|
283
283
|
o,
|
|
284
284
|
r.identifier
|
|
285
285
|
);
|
|
286
|
-
A && A.id ? await
|
|
286
|
+
A && A.id ? await m.resourceServers.update(
|
|
287
287
|
o,
|
|
288
288
|
A.id,
|
|
289
289
|
h
|
|
290
|
-
) : await
|
|
290
|
+
) : await m.resourceServers.create(o, h);
|
|
291
291
|
}
|
|
292
|
-
} catch (
|
|
292
|
+
} catch (m) {
|
|
293
293
|
console.error(
|
|
294
294
|
`Failed to sync resource server "${r.identifier}" to tenant "${o}":`,
|
|
295
|
-
|
|
295
|
+
m
|
|
296
296
|
);
|
|
297
297
|
}
|
|
298
298
|
})
|
|
@@ -301,17 +301,17 @@ function ae(e) {
|
|
|
301
301
|
async function c(r) {
|
|
302
302
|
const f = await s();
|
|
303
303
|
await Promise.all(
|
|
304
|
-
f.map(async (
|
|
304
|
+
f.map(async (u) => {
|
|
305
305
|
try {
|
|
306
|
-
const o = await a(
|
|
306
|
+
const o = await a(u), m = await d(
|
|
307
307
|
o,
|
|
308
|
-
|
|
308
|
+
u,
|
|
309
309
|
r
|
|
310
310
|
);
|
|
311
|
-
|
|
311
|
+
m && m.id && await o.resourceServers.remove(u, m.id);
|
|
312
312
|
} catch (o) {
|
|
313
313
|
console.error(
|
|
314
|
-
`Failed to delete resource server "${r}" from tenant "${
|
|
314
|
+
`Failed to delete resource server "${r}" from tenant "${u}":`,
|
|
315
315
|
o
|
|
316
316
|
);
|
|
317
317
|
}
|
|
@@ -322,8 +322,8 @@ function ae(e) {
|
|
|
322
322
|
afterCreate: async (r, f) => {
|
|
323
323
|
r.tenantId === t && i(f) && await l(f, "create");
|
|
324
324
|
},
|
|
325
|
-
afterUpdate: async (r, f,
|
|
326
|
-
r.tenantId === t && i(
|
|
325
|
+
afterUpdate: async (r, f, u) => {
|
|
326
|
+
r.tenantId === t && i(u) && await l(u, "update");
|
|
327
327
|
},
|
|
328
328
|
afterDelete: async (r, f) => {
|
|
329
329
|
r.tenantId === t && await c(f);
|
|
@@ -339,22 +339,22 @@ function ne(e) {
|
|
|
339
339
|
transformForSync: n
|
|
340
340
|
} = e;
|
|
341
341
|
return {
|
|
342
|
-
async afterCreate(
|
|
342
|
+
async afterCreate(d, l) {
|
|
343
343
|
if (l.id !== t)
|
|
344
344
|
try {
|
|
345
345
|
const c = await s(), r = await a(l.id), f = await S(
|
|
346
|
-
(
|
|
346
|
+
(u) => c.resourceServers.list(
|
|
347
347
|
t,
|
|
348
|
-
|
|
348
|
+
u
|
|
349
349
|
),
|
|
350
350
|
"resource_servers",
|
|
351
351
|
{ cursorField: "id", pageSize: 100 }
|
|
352
352
|
);
|
|
353
353
|
await Promise.all(
|
|
354
|
-
f.filter((
|
|
355
|
-
const o =
|
|
354
|
+
f.filter((u) => i(u)).map(async (u) => {
|
|
355
|
+
const o = u;
|
|
356
356
|
try {
|
|
357
|
-
const
|
|
357
|
+
const m = n ? n(o, l.id) : {
|
|
358
358
|
name: o.name,
|
|
359
359
|
identifier: o.identifier,
|
|
360
360
|
scopes: o.scopes,
|
|
@@ -368,13 +368,13 @@ function ne(e) {
|
|
|
368
368
|
options: o.options
|
|
369
369
|
};
|
|
370
370
|
await r.resourceServers.create(l.id, {
|
|
371
|
-
...
|
|
371
|
+
...m,
|
|
372
372
|
is_system: !0
|
|
373
373
|
});
|
|
374
|
-
} catch (
|
|
374
|
+
} catch (m) {
|
|
375
375
|
console.error(
|
|
376
376
|
`Failed to sync resource server "${o.identifier}" to new tenant "${l.id}":`,
|
|
377
|
-
|
|
377
|
+
m
|
|
378
378
|
);
|
|
379
379
|
}
|
|
380
380
|
})
|
|
@@ -396,7 +396,7 @@ function re(e) {
|
|
|
396
396
|
shouldSync: i = () => !0,
|
|
397
397
|
transformForSync: n
|
|
398
398
|
} = e;
|
|
399
|
-
async function
|
|
399
|
+
async function d(c, r, f) {
|
|
400
400
|
return (await c.roles.list(r, {
|
|
401
401
|
q: `name:${f}`,
|
|
402
402
|
per_page: 1
|
|
@@ -405,30 +405,30 @@ function re(e) {
|
|
|
405
405
|
async function l(c, r) {
|
|
406
406
|
const f = await s();
|
|
407
407
|
await Promise.all(
|
|
408
|
-
f.map(async (
|
|
408
|
+
f.map(async (u) => {
|
|
409
409
|
try {
|
|
410
|
-
const o = await a(
|
|
410
|
+
const o = await a(u), g = { ...n ? n(c, u) : {
|
|
411
411
|
name: c.name,
|
|
412
412
|
description: c.description
|
|
413
413
|
}, is_system: !0 };
|
|
414
414
|
if (r === "create") {
|
|
415
|
-
const h = await
|
|
415
|
+
const h = await d(o, u, c.name);
|
|
416
416
|
h && h.id ? await o.roles.update(
|
|
417
|
-
|
|
417
|
+
u,
|
|
418
418
|
h.id,
|
|
419
419
|
g
|
|
420
|
-
) : await o.roles.create(
|
|
420
|
+
) : await o.roles.create(u, g);
|
|
421
421
|
} else {
|
|
422
|
-
const h = await
|
|
422
|
+
const h = await d(o, u, c.name);
|
|
423
423
|
h && h.id ? await o.roles.update(
|
|
424
|
-
|
|
424
|
+
u,
|
|
425
425
|
h.id,
|
|
426
426
|
g
|
|
427
|
-
) : await o.roles.create(
|
|
427
|
+
) : await o.roles.create(u, g);
|
|
428
428
|
}
|
|
429
429
|
} catch (o) {
|
|
430
430
|
console.error(
|
|
431
|
-
`Failed to sync role "${c.name}" to tenant "${
|
|
431
|
+
`Failed to sync role "${c.name}" to tenant "${u}":`,
|
|
432
432
|
o
|
|
433
433
|
);
|
|
434
434
|
}
|
|
@@ -456,20 +456,20 @@ function se(e) {
|
|
|
456
456
|
getAdapters: a,
|
|
457
457
|
shouldSync: i = () => !0,
|
|
458
458
|
transformForSync: n,
|
|
459
|
-
syncPermissions:
|
|
459
|
+
syncPermissions: d = !0
|
|
460
460
|
} = e;
|
|
461
461
|
return {
|
|
462
462
|
async afterCreate(l, c) {
|
|
463
463
|
if (c.id !== t)
|
|
464
464
|
try {
|
|
465
|
-
const r = await s(), f = await a(c.id),
|
|
466
|
-
(
|
|
465
|
+
const r = await s(), f = await a(c.id), u = await S(
|
|
466
|
+
(m) => r.roles.list(t, m),
|
|
467
467
|
"roles",
|
|
468
468
|
{ cursorField: "id", pageSize: 100 }
|
|
469
469
|
), o = /* @__PURE__ */ new Map();
|
|
470
470
|
if (await Promise.all(
|
|
471
|
-
|
|
472
|
-
const g =
|
|
471
|
+
u.filter((m) => i(m)).map(async (m) => {
|
|
472
|
+
const g = m;
|
|
473
473
|
try {
|
|
474
474
|
const h = n ? n(g, c.id) : {
|
|
475
475
|
name: g.name,
|
|
@@ -486,12 +486,12 @@ function se(e) {
|
|
|
486
486
|
);
|
|
487
487
|
}
|
|
488
488
|
})
|
|
489
|
-
),
|
|
490
|
-
for (const [
|
|
489
|
+
), d)
|
|
490
|
+
for (const [m, g] of o)
|
|
491
491
|
try {
|
|
492
492
|
const h = await r.rolePermissions.list(
|
|
493
493
|
t,
|
|
494
|
-
|
|
494
|
+
m,
|
|
495
495
|
{}
|
|
496
496
|
);
|
|
497
497
|
h.length > 0 && await f.rolePermissions.assign(
|
|
@@ -550,47 +550,47 @@ function O(e, t) {
|
|
|
550
550
|
}
|
|
551
551
|
}),
|
|
552
552
|
async (a) => {
|
|
553
|
-
var
|
|
554
|
-
const i = a.req.valid("query"), { page: n, per_page:
|
|
555
|
-
if (
|
|
553
|
+
var m, g, h, A;
|
|
554
|
+
const i = a.req.valid("query"), { page: n, per_page: d, include_totals: l, q: c } = i, r = a.var.user, f = (r == null ? void 0 : r.permissions) || [];
|
|
555
|
+
if (f.includes("auth:read") || f.includes("admin:organizations")) {
|
|
556
556
|
const C = await a.env.data.tenants.list({
|
|
557
557
|
page: n,
|
|
558
|
-
per_page:
|
|
558
|
+
per_page: d,
|
|
559
559
|
include_totals: l,
|
|
560
560
|
q: c
|
|
561
561
|
});
|
|
562
562
|
return l ? a.json({
|
|
563
563
|
tenants: C.tenants,
|
|
564
|
-
start: ((
|
|
565
|
-
limit: ((g = C.totals) == null ? void 0 : g.limit) ??
|
|
564
|
+
start: ((m = C.totals) == null ? void 0 : m.start) ?? 0,
|
|
565
|
+
limit: ((g = C.totals) == null ? void 0 : g.limit) ?? d,
|
|
566
566
|
length: C.tenants.length
|
|
567
567
|
}) : a.json({ tenants: C.tenants });
|
|
568
568
|
}
|
|
569
569
|
if (e.accessControl && (r != null && r.sub)) {
|
|
570
570
|
const C = e.accessControl.controlPlaneTenantId, $ = (await S(
|
|
571
|
-
(
|
|
571
|
+
(z) => a.env.data.userOrganizations.listUserOrganizations(
|
|
572
572
|
C,
|
|
573
573
|
r.sub,
|
|
574
|
-
|
|
574
|
+
z
|
|
575
575
|
),
|
|
576
576
|
"organizations"
|
|
577
|
-
)).map((
|
|
577
|
+
)).map((z) => z.name);
|
|
578
578
|
if ($.length === 0)
|
|
579
579
|
return l ? a.json({
|
|
580
580
|
tenants: [],
|
|
581
581
|
start: 0,
|
|
582
|
-
limit:
|
|
582
|
+
limit: d ?? 50,
|
|
583
583
|
length: 0
|
|
584
584
|
}) : a.json({ tenants: [] });
|
|
585
|
-
const
|
|
586
|
-
if (
|
|
585
|
+
const R = $.length, I = n ?? 0, v = d ?? 50, w = I * v, p = $.slice(w, w + v);
|
|
586
|
+
if (p.length === 0)
|
|
587
587
|
return l ? a.json({
|
|
588
588
|
tenants: [],
|
|
589
589
|
start: w,
|
|
590
590
|
limit: v,
|
|
591
|
-
length:
|
|
591
|
+
length: R
|
|
592
592
|
}) : a.json({ tenants: [] });
|
|
593
|
-
const y =
|
|
593
|
+
const y = p.map((z) => `id:${z}`).join(" OR "), _ = c ? `(${y}) AND (${c})` : y, b = await a.env.data.tenants.list({
|
|
594
594
|
q: _,
|
|
595
595
|
per_page: v,
|
|
596
596
|
include_totals: !1
|
|
@@ -600,19 +600,19 @@ function O(e, t) {
|
|
|
600
600
|
tenants: b.tenants,
|
|
601
601
|
start: w,
|
|
602
602
|
limit: v,
|
|
603
|
-
length:
|
|
603
|
+
length: R
|
|
604
604
|
}) : a.json({ tenants: b.tenants });
|
|
605
605
|
}
|
|
606
606
|
const o = await a.env.data.tenants.list({
|
|
607
607
|
page: n,
|
|
608
|
-
per_page:
|
|
608
|
+
per_page: d,
|
|
609
609
|
include_totals: l,
|
|
610
610
|
q: c
|
|
611
611
|
});
|
|
612
612
|
return l ? a.json({
|
|
613
613
|
tenants: o.tenants,
|
|
614
614
|
start: ((h = o.totals) == null ? void 0 : h.start) ?? 0,
|
|
615
|
-
limit: ((A = o.totals) == null ? void 0 : A.limit) ??
|
|
615
|
+
limit: ((A = o.totals) == null ? void 0 : A.limit) ?? d,
|
|
616
616
|
length: o.tenants.length
|
|
617
617
|
}) : a.json({ tenants: o.tenants });
|
|
618
618
|
}
|
|
@@ -660,13 +660,13 @@ function O(e, t) {
|
|
|
660
660
|
message: "Authentication required to create tenants"
|
|
661
661
|
});
|
|
662
662
|
let n = a.req.valid("json");
|
|
663
|
-
const
|
|
663
|
+
const d = {
|
|
664
664
|
adapters: a.env.data,
|
|
665
665
|
ctx: a
|
|
666
666
|
};
|
|
667
|
-
(c = t.tenants) != null && c.beforeCreate && (n = await t.tenants.beforeCreate(
|
|
667
|
+
(c = t.tenants) != null && c.beforeCreate && (n = await t.tenants.beforeCreate(d, n));
|
|
668
668
|
const l = await a.env.data.tenants.create(n);
|
|
669
|
-
return (r = t.tenants) != null && r.afterCreate && await t.tenants.afterCreate(
|
|
669
|
+
return (r = t.tenants) != null && r.afterCreate && await t.tenants.afterCreate(d, l), a.json(l, 201);
|
|
670
670
|
}
|
|
671
671
|
), s.openapi(
|
|
672
672
|
M({
|
|
@@ -709,13 +709,13 @@ function O(e, t) {
|
|
|
709
709
|
message: "Cannot delete the control plane"
|
|
710
710
|
});
|
|
711
711
|
if (!(await S(
|
|
712
|
-
(
|
|
712
|
+
(m) => a.env.data.userOrganizations.listUserOrganizations(
|
|
713
713
|
f,
|
|
714
714
|
r.sub,
|
|
715
|
-
|
|
715
|
+
m
|
|
716
716
|
),
|
|
717
717
|
"organizations"
|
|
718
|
-
)).some((
|
|
718
|
+
)).some((m) => m.name === i))
|
|
719
719
|
throw new T(403, {
|
|
720
720
|
message: "Access denied to this tenant"
|
|
721
721
|
});
|
|
@@ -724,11 +724,11 @@ function O(e, t) {
|
|
|
724
724
|
throw new T(404, {
|
|
725
725
|
message: "Tenant not found"
|
|
726
726
|
});
|
|
727
|
-
const
|
|
727
|
+
const d = {
|
|
728
728
|
adapters: a.env.data,
|
|
729
729
|
ctx: a
|
|
730
730
|
};
|
|
731
|
-
return (l = t.tenants) != null && l.beforeDelete && await t.tenants.beforeDelete(
|
|
731
|
+
return (l = t.tenants) != null && l.beforeDelete && await t.tenants.beforeDelete(d, i), await a.env.data.tenants.remove(i), (c = t.tenants) != null && c.afterDelete && await t.tenants.afterDelete(d, i), a.body(null, 204);
|
|
732
732
|
}
|
|
733
733
|
), s;
|
|
734
734
|
}
|
|
@@ -822,10 +822,10 @@ function ue(e) {
|
|
|
822
822
|
baseDomain: a,
|
|
823
823
|
reservedSubdomains: i = [],
|
|
824
824
|
resolveSubdomain: n
|
|
825
|
-
} = e.subdomainRouting,
|
|
825
|
+
} = e.subdomainRouting, d = t.req.header("host") || "";
|
|
826
826
|
let l = null;
|
|
827
|
-
if (
|
|
828
|
-
const r =
|
|
827
|
+
if (d.endsWith(a)) {
|
|
828
|
+
const r = d.slice(0, -(a.length + 1));
|
|
829
829
|
r && !r.includes(".") && (l = r);
|
|
830
830
|
}
|
|
831
831
|
if (l && i.includes(l) && (l = null), !l)
|
|
@@ -872,7 +872,7 @@ function fe(e) {
|
|
|
872
872
|
return s();
|
|
873
873
|
};
|
|
874
874
|
}
|
|
875
|
-
function
|
|
875
|
+
function U(e) {
|
|
876
876
|
const t = ue(e), s = de(e), a = fe(e);
|
|
877
877
|
return async (i, n) => (await t(i, async () => {
|
|
878
878
|
}), await s(i, async () => {
|
|
@@ -880,11 +880,11 @@ function N(e) {
|
|
|
880
880
|
}), n());
|
|
881
881
|
}
|
|
882
882
|
function _e(e) {
|
|
883
|
-
const t =
|
|
883
|
+
const t = F(e);
|
|
884
884
|
return {
|
|
885
885
|
name: "multi-tenancy",
|
|
886
886
|
// Apply multi-tenancy middleware for subdomain routing, database resolution, etc.
|
|
887
|
-
middleware:
|
|
887
|
+
middleware: U(e),
|
|
888
888
|
// Provide lifecycle hooks
|
|
889
889
|
hooks: t,
|
|
890
890
|
// Mount tenant management routes
|
|
@@ -904,7 +904,7 @@ function _e(e) {
|
|
|
904
904
|
}
|
|
905
905
|
};
|
|
906
906
|
}
|
|
907
|
-
function
|
|
907
|
+
function F(e) {
|
|
908
908
|
const t = e.accessControl ? X(e.accessControl) : {}, s = e.databaseIsolation ? Z(e.databaseIsolation) : {}, a = k(e);
|
|
909
909
|
return {
|
|
910
910
|
...t,
|
|
@@ -912,15 +912,15 @@ function I(e) {
|
|
|
912
912
|
tenants: a
|
|
913
913
|
};
|
|
914
914
|
}
|
|
915
|
-
function
|
|
916
|
-
const t = new
|
|
915
|
+
function me(e) {
|
|
916
|
+
const t = new N(), s = F(e);
|
|
917
917
|
return t.route("/tenants", O(e, s)), t;
|
|
918
918
|
}
|
|
919
919
|
function Ae(e) {
|
|
920
920
|
return {
|
|
921
|
-
hooks:
|
|
922
|
-
middleware:
|
|
923
|
-
app:
|
|
921
|
+
hooks: F(e),
|
|
922
|
+
middleware: U(e),
|
|
923
|
+
app: me(e),
|
|
924
924
|
config: e
|
|
925
925
|
};
|
|
926
926
|
}
|
|
@@ -931,7 +931,7 @@ function be(e) {
|
|
|
931
931
|
syncRoles: a = !0,
|
|
932
932
|
multiTenancy: i,
|
|
933
933
|
entityHooks: n,
|
|
934
|
-
...
|
|
934
|
+
...d
|
|
935
935
|
} = e, l = {
|
|
936
936
|
...i,
|
|
937
937
|
accessControl: {
|
|
@@ -940,29 +940,29 @@ function be(e) {
|
|
|
940
940
|
defaultPermissions: ["tenant:admin"],
|
|
941
941
|
...i == null ? void 0 : i.accessControl
|
|
942
942
|
}
|
|
943
|
-
}, c =
|
|
943
|
+
}, c = F(l);
|
|
944
944
|
let r, f;
|
|
945
945
|
s && (r = ae({
|
|
946
946
|
controlPlaneTenantId: t,
|
|
947
947
|
getChildTenantIds: async () => (await S(
|
|
948
|
-
(
|
|
948
|
+
(p) => e.dataAdapter.tenants.list(p),
|
|
949
949
|
"tenants",
|
|
950
950
|
{ cursorField: "id", pageSize: 100 }
|
|
951
|
-
)).filter((
|
|
951
|
+
)).filter((p) => p.id !== t).map((p) => p.id),
|
|
952
952
|
getAdapters: async (w) => e.dataAdapter
|
|
953
953
|
}), f = ne({
|
|
954
954
|
controlPlaneTenantId: t,
|
|
955
955
|
getControlPlaneAdapters: async () => e.dataAdapter,
|
|
956
956
|
getAdapters: async (w) => e.dataAdapter
|
|
957
957
|
}));
|
|
958
|
-
let
|
|
959
|
-
a && (
|
|
958
|
+
let u, o;
|
|
959
|
+
a && (u = re({
|
|
960
960
|
controlPlaneTenantId: t,
|
|
961
961
|
getChildTenantIds: async () => (await S(
|
|
962
|
-
(
|
|
962
|
+
(p) => e.dataAdapter.tenants.list(p),
|
|
963
963
|
"tenants",
|
|
964
964
|
{ cursorField: "id", pageSize: 100 }
|
|
965
|
-
)).filter((
|
|
965
|
+
)).filter((p) => p.id !== t).map((p) => p.id),
|
|
966
966
|
getAdapters: async (w) => e.dataAdapter
|
|
967
967
|
}), o = se({
|
|
968
968
|
controlPlaneTenantId: t,
|
|
@@ -970,7 +970,7 @@ function be(e) {
|
|
|
970
970
|
getAdapters: async (w) => e.dataAdapter,
|
|
971
971
|
syncPermissions: !0
|
|
972
972
|
}));
|
|
973
|
-
const
|
|
973
|
+
const m = async (w, p, ...y) => {
|
|
974
974
|
const _ = [];
|
|
975
975
|
if (w)
|
|
976
976
|
try {
|
|
@@ -978,9 +978,9 @@ function be(e) {
|
|
|
978
978
|
} catch (b) {
|
|
979
979
|
_.push(b instanceof Error ? b : new Error(String(b)));
|
|
980
980
|
}
|
|
981
|
-
if (
|
|
981
|
+
if (p)
|
|
982
982
|
try {
|
|
983
|
-
await
|
|
983
|
+
await p(...y);
|
|
984
984
|
} catch (b) {
|
|
985
985
|
_.push(b instanceof Error ? b : new Error(String(b)));
|
|
986
986
|
}
|
|
@@ -991,12 +991,12 @@ function be(e) {
|
|
|
991
991
|
_,
|
|
992
992
|
`Multiple hook errors: ${_.map((b) => b.message).join("; ")}`
|
|
993
993
|
);
|
|
994
|
-
}, g = async (w, ...
|
|
994
|
+
}, g = async (w, ...p) => {
|
|
995
995
|
const y = [];
|
|
996
996
|
for (const _ of w)
|
|
997
997
|
if (_)
|
|
998
998
|
try {
|
|
999
|
-
await _(...
|
|
999
|
+
await _(...p);
|
|
1000
1000
|
} catch (b) {
|
|
1001
1001
|
y.push(
|
|
1002
1002
|
b instanceof Error ? b : new Error(String(b))
|
|
@@ -1013,69 +1013,69 @@ function be(e) {
|
|
|
1013
1013
|
...n,
|
|
1014
1014
|
resourceServers: r ? {
|
|
1015
1015
|
...n == null ? void 0 : n.resourceServers,
|
|
1016
|
-
afterCreate: async (w,
|
|
1016
|
+
afterCreate: async (w, p) => {
|
|
1017
1017
|
var y;
|
|
1018
|
-
await
|
|
1018
|
+
await m(
|
|
1019
1019
|
(y = n == null ? void 0 : n.resourceServers) == null ? void 0 : y.afterCreate,
|
|
1020
1020
|
r == null ? void 0 : r.afterCreate,
|
|
1021
1021
|
w,
|
|
1022
|
-
|
|
1022
|
+
p
|
|
1023
1023
|
);
|
|
1024
1024
|
},
|
|
1025
|
-
afterUpdate: async (w,
|
|
1025
|
+
afterUpdate: async (w, p, y) => {
|
|
1026
1026
|
var _;
|
|
1027
|
-
await
|
|
1027
|
+
await m(
|
|
1028
1028
|
(_ = n == null ? void 0 : n.resourceServers) == null ? void 0 : _.afterUpdate,
|
|
1029
1029
|
r == null ? void 0 : r.afterUpdate,
|
|
1030
1030
|
w,
|
|
1031
|
-
|
|
1031
|
+
p,
|
|
1032
1032
|
y
|
|
1033
1033
|
);
|
|
1034
1034
|
},
|
|
1035
|
-
afterDelete: async (w,
|
|
1035
|
+
afterDelete: async (w, p) => {
|
|
1036
1036
|
var y;
|
|
1037
|
-
await
|
|
1037
|
+
await m(
|
|
1038
1038
|
(y = n == null ? void 0 : n.resourceServers) == null ? void 0 : y.afterDelete,
|
|
1039
1039
|
r == null ? void 0 : r.afterDelete,
|
|
1040
1040
|
w,
|
|
1041
|
-
|
|
1041
|
+
p
|
|
1042
1042
|
);
|
|
1043
1043
|
}
|
|
1044
1044
|
} : n == null ? void 0 : n.resourceServers,
|
|
1045
|
-
roles:
|
|
1045
|
+
roles: u ? {
|
|
1046
1046
|
...n == null ? void 0 : n.roles,
|
|
1047
|
-
afterCreate: async (w,
|
|
1047
|
+
afterCreate: async (w, p) => {
|
|
1048
1048
|
var y;
|
|
1049
|
-
await
|
|
1049
|
+
await m(
|
|
1050
1050
|
(y = n == null ? void 0 : n.roles) == null ? void 0 : y.afterCreate,
|
|
1051
|
-
|
|
1051
|
+
u == null ? void 0 : u.afterCreate,
|
|
1052
1052
|
w,
|
|
1053
|
-
|
|
1053
|
+
p
|
|
1054
1054
|
);
|
|
1055
1055
|
},
|
|
1056
|
-
afterUpdate: async (w,
|
|
1056
|
+
afterUpdate: async (w, p, y) => {
|
|
1057
1057
|
var _;
|
|
1058
|
-
await
|
|
1058
|
+
await m(
|
|
1059
1059
|
(_ = n == null ? void 0 : n.roles) == null ? void 0 : _.afterUpdate,
|
|
1060
|
-
|
|
1060
|
+
u == null ? void 0 : u.afterUpdate,
|
|
1061
1061
|
w,
|
|
1062
|
-
|
|
1062
|
+
p,
|
|
1063
1063
|
y
|
|
1064
1064
|
);
|
|
1065
1065
|
},
|
|
1066
|
-
afterDelete: async (w,
|
|
1066
|
+
afterDelete: async (w, p) => {
|
|
1067
1067
|
var y;
|
|
1068
|
-
await
|
|
1068
|
+
await m(
|
|
1069
1069
|
(y = n == null ? void 0 : n.roles) == null ? void 0 : y.afterDelete,
|
|
1070
|
-
|
|
1070
|
+
u == null ? void 0 : u.afterDelete,
|
|
1071
1071
|
w,
|
|
1072
|
-
|
|
1072
|
+
p
|
|
1073
1073
|
);
|
|
1074
1074
|
}
|
|
1075
1075
|
} : n == null ? void 0 : n.roles,
|
|
1076
1076
|
tenants: f || o ? {
|
|
1077
1077
|
...n == null ? void 0 : n.tenants,
|
|
1078
|
-
afterCreate: async (w,
|
|
1078
|
+
afterCreate: async (w, p) => {
|
|
1079
1079
|
var y;
|
|
1080
1080
|
await g(
|
|
1081
1081
|
[
|
|
@@ -1084,7 +1084,7 @@ function be(e) {
|
|
|
1084
1084
|
o == null ? void 0 : o.afterCreate
|
|
1085
1085
|
],
|
|
1086
1086
|
w,
|
|
1087
|
-
|
|
1087
|
+
p
|
|
1088
1088
|
);
|
|
1089
1089
|
}
|
|
1090
1090
|
} : n == null ? void 0 : n.tenants
|
|
@@ -1092,15 +1092,15 @@ function be(e) {
|
|
|
1092
1092
|
...c,
|
|
1093
1093
|
tenants: f || o ? {
|
|
1094
1094
|
...c.tenants,
|
|
1095
|
-
afterCreate: async (w,
|
|
1095
|
+
afterCreate: async (w, p) => {
|
|
1096
1096
|
var y;
|
|
1097
|
-
(y = c.tenants) != null && y.afterCreate && await c.tenants.afterCreate(w,
|
|
1097
|
+
(y = c.tenants) != null && y.afterCreate && await c.tenants.afterCreate(w, p), await g(
|
|
1098
1098
|
[
|
|
1099
1099
|
f == null ? void 0 : f.afterCreate,
|
|
1100
1100
|
o == null ? void 0 : o.afterCreate
|
|
1101
1101
|
],
|
|
1102
1102
|
w,
|
|
1103
|
-
|
|
1103
|
+
p
|
|
1104
1104
|
);
|
|
1105
1105
|
}
|
|
1106
1106
|
} : c.tenants
|
|
@@ -1108,19 +1108,19 @@ function be(e) {
|
|
|
1108
1108
|
l,
|
|
1109
1109
|
A
|
|
1110
1110
|
), j = L({
|
|
1111
|
-
...
|
|
1111
|
+
...d,
|
|
1112
1112
|
entityHooks: h,
|
|
1113
1113
|
// Register tenant routes via the extension mechanism
|
|
1114
1114
|
// This ensures they go through the full middleware chain (caching, tenant, auth, entity hooks)
|
|
1115
1115
|
managementApiExtensions: [
|
|
1116
|
-
...
|
|
1116
|
+
...d.managementApiExtensions || [],
|
|
1117
1117
|
{ path: "/tenants", router: C }
|
|
1118
1118
|
]
|
|
1119
|
-
}), { app: $, managementApp:
|
|
1120
|
-
return v.onError((w,
|
|
1119
|
+
}), { app: $, managementApp: R, ...I } = j, v = new N();
|
|
1120
|
+
return v.onError((w, p) => w instanceof T ? w.getResponse() : (console.error(w), p.json({ message: "Internal Server Error" }, 500))), v.use("/api/v2/*", le()), v.route("/", $), {
|
|
1121
1121
|
app: v,
|
|
1122
|
-
managementApp:
|
|
1123
|
-
...
|
|
1122
|
+
managementApp: R,
|
|
1123
|
+
...I,
|
|
1124
1124
|
multiTenancyConfig: l,
|
|
1125
1125
|
multiTenancyHooks: c
|
|
1126
1126
|
};
|
|
@@ -1131,9 +1131,9 @@ export {
|
|
|
1131
1131
|
de as createAccessControlMiddleware,
|
|
1132
1132
|
Z as createDatabaseHooks,
|
|
1133
1133
|
fe as createDatabaseMiddleware,
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1134
|
+
me as createMultiTenancy,
|
|
1135
|
+
F as createMultiTenancyHooks,
|
|
1136
|
+
U as createMultiTenancyMiddleware,
|
|
1137
1137
|
_e as createMultiTenancyPlugin,
|
|
1138
1138
|
le as createProtectSyncedMiddleware,
|
|
1139
1139
|
k as createProvisioningHooks,
|
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.13.0",
|
|
15
15
|
"description": "Multi-tenancy support for AuthHero with organization-based access control and per-tenant database isolation",
|
|
16
16
|
"files": [
|
|
17
17
|
"dist"
|
|
@@ -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",
|