@authhero/multi-tenancy 13.10.1 → 13.12.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 +34 -8
- package/dist/multi-tenancy.mjs +681 -920
- package/package.json +4 -4
package/dist/multi-tenancy.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var X=Object.defineProperty;var H=(t,a,i)=>a in t?X(t,a,{enumerable:!0,configurable:!0,writable:!0,value:i}):t[a]=i;var M=(t,a,i)=>H(t,typeof a!="symbol"?a+"":a,i);Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const j=require("hono"),A=require("authhero"),k=require("zod"),z=require("@authhero/adapter-interfaces"),b=require("@hono/zod-openapi");var w=class extends Error{constructor(a=500,i){super(i==null?void 0:i.message,{cause:i==null?void 0:i.cause});M(this,"res");M(this,"status");this.res=i==null?void 0:i.res,this.status=a}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(t){const{controlPlaneTenantId:a,requireOrganizationMatch:i=!0}=t;return{async onTenantAccessValidation(e,n){if(n===a)return!0;if(i){const r=e.var.org_name,d=e.var.organization_id,o=r||d;return o?o===n:!1}return!0}}}function F(t,a,i,e){if(a===i)return!0;const n=e||t;return n?n===a:!1}function N(t){return{async resolveDataAdapters(a){try{return await t.getAdapters(a)}catch(i){console.error(`Failed to resolve data adapters for tenant ${a}:`,i);return}}}}function E(t){return{async beforeCreate(a,i){return!i.audience&&i.id?{...i,audience:A.getTenantAudience(i.id)}:i},async afterCreate(a,i){const{accessControl:e,databaseIsolation:n,settingsInheritance:r}=t;e&&a.ctx&&await x(a,i,e),n!=null&&n.onProvision&&await n.onProvision(i.id),(r==null?void 0:r.inheritFromControlPlane)!==!1&&a.ctx&&await te(a,i,t)},async beforeDelete(a,i){const{accessControl:e,databaseIsolation:n}=t;if(e)try{const d=(await a.adapters.organizations.list(e.controlPlaneTenantId)).organizations.find(o=>o.name===i);d&&await a.adapters.organizations.remove(e.controlPlaneTenantId,d.id)}catch(r){console.warn(`Failed to remove organization for tenant ${i}:`,r)}if(n!=null&&n.onDeprovision)try{await n.onDeprovision(i)}catch(r){console.warn(`Failed to deprovision database for tenant ${i}:`,r)}}}}async function x(t,a,i){const{controlPlaneTenantId:e,defaultPermissions:n,defaultRoles:r,issuer:d,adminRoleName:o="Tenant Admin",adminRoleDescription:c="Full access to all tenant management operations",addCreatorToOrganization:s=!0}=i,u=await t.adapters.organizations.create(e,{name:a.id,display_name:a.friendly_name||a.id});let f;if(d&&(f=await ee(t,e,o,c)),s&&t.ctx){const l=t.ctx.var.user;if(l!=null&&l.sub)try{await t.adapters.userOrganizations.create(e,{user_id:l.sub,organization_id:u.id}),f&&await t.adapters.userRoles.create(e,l.sub,f,u.id)}catch(p){console.warn(`Failed to add creator ${l.sub} to organization ${u.id}:`,p)}}r&&r.length>0&&console.log(`Would assign roles ${r.join(", ")} to organization ${u.id}`),n&&n.length>0&&console.log(`Would grant permissions ${n.join(", ")} to organization ${u.id}`)}async function ee(t,a,i,e){const r=(await t.adapters.roles.list(a,{})).roles.find(s=>s.name===i);if(r)return r.id;const d=await t.adapters.roles.create(a,{name:i,description:e}),o=A.MANAGEMENT_API_AUDIENCE,c=A.MANAGEMENT_API_SCOPES.map(s=>({role_id:d.id,resource_server_identifier:o,permission_name:s.value}));return await t.adapters.rolePermissions.assign(a,d.id,c),d.id}async function te(t,a,i){const{accessControl:e,settingsInheritance:n}=i;if(!e)return;const r=await t.adapters.tenants.get(e.controlPlaneTenantId);if(!r)return;let d={...r};const o=["id","created_at","updated_at","friendly_name","audience","sender_email","sender_name"];for(const c of o)delete d[c];if(n!=null&&n.inheritedKeys){const c={};for(const s of n.inheritedKeys)s in r&&!o.includes(s)&&(c[s]=r[s]);d=c}if(n!=null&&n.excludedKeys)for(const c of n.excludedKeys)delete d[c];n!=null&&n.transformSettings&&(d=n.transformSettings(d,a.id)),Object.keys(d).length>0&&await t.adapters.tenants.update(a.id,d)}function K(t){const{controlPlaneTenantId:a,getChildTenantIds:i,getAdapters:e,shouldSync:n=()=>!0,transformForSync:r}=t;async function d(s,u,f){return(await s.resourceServers.list(u,{q:`identifier:${f}`,per_page:1})).resource_servers[0]??null}async function o(s,u){const f=await i();await Promise.all(f.map(async l=>{try{const p=await e(l),y={...r?r(s,l):{name:s.name,identifier:s.identifier,scopes:s.scopes,signing_alg:s.signing_alg,signing_secret:s.signing_secret,token_lifetime:s.token_lifetime,token_lifetime_for_web:s.token_lifetime_for_web,skip_consent_for_verifiable_first_party_clients:s.skip_consent_for_verifiable_first_party_clients,allow_offline_access:s.allow_offline_access,verificationKey:s.verificationKey,options:s.options},is_system:!0};if(u==="create"){const T=await d(p,l,s.identifier);T&&T.id?await p.resourceServers.update(l,T.id,y):await p.resourceServers.create(l,y)}else{const T=await d(p,l,s.identifier);T&&T.id&&await p.resourceServers.update(l,T.id,y)}}catch(p){console.error(`Failed to sync resource server "${s.identifier}" to tenant "${l}":`,p)}}))}async function c(s){const u=await i();await Promise.all(u.map(async f=>{try{const l=await e(f),p=await d(l,f,s);p&&p.id&&await l.resourceServers.remove(f,p.id)}catch(l){console.error(`Failed to delete resource server "${s}" from tenant "${f}":`,l)}}))}return{afterCreate:async(s,u)=>{s.tenantId===a&&n(u)&&await o(u,"create")},afterUpdate:async(s,u,f)=>{s.tenantId===a&&n(f)&&await o(f,"update")},afterDelete:async(s,u)=>{s.tenantId===a&&await c(u)}}}function B(t){const{controlPlaneTenantId:a,getControlPlaneAdapters:i,getAdapters:e,shouldSync:n=()=>!0,transformForSync:r}=t;return{async afterCreate(d,o){if(o.id!==a)try{const c=await i(),s=await e(o.id),u=await A.fetchAll(f=>c.resourceServers.list(a,f),"resource_servers",{cursorField:"id",pageSize:100});await Promise.all(u.filter(f=>n(f)).map(async f=>{const l=f;try{const p=r?r(l,o.id):{name:l.name,identifier:l.identifier,scopes:l.scopes,signing_alg:l.signing_alg,signing_secret:l.signing_secret,token_lifetime:l.token_lifetime,token_lifetime_for_web:l.token_lifetime_for_web,skip_consent_for_verifiable_first_party_clients:l.skip_consent_for_verifiable_first_party_clients,allow_offline_access:l.allow_offline_access,verificationKey:l.verificationKey,options:l.options};await s.resourceServers.create(o.id,{...p,is_system:!0})}catch(p){console.error(`Failed to sync resource server "${l.identifier}" to new tenant "${o.id}":`,p)}}))}catch(c){console.error(`Failed to sync resource servers to new tenant "${o.id}":`,c)}}}}function W(t){const{controlPlaneTenantId:a,getChildTenantIds:i,getAdapters:e,shouldSync:n=()=>!0,transformForSync:r}=t;async function d(c,s,u){return(await c.roles.list(s,{q:`name:${u}`,per_page:1})).roles[0]??null}async function o(c,s){const u=await i();await Promise.all(u.map(async f=>{try{const l=await e(f),_={...r?r(c,f):{name:c.name,description:c.description},is_system:!0};if(s==="create"){const y=await d(l,f,c.name);y&&y.id?await l.roles.update(f,y.id,_):await l.roles.create(f,_)}else{const y=await d(l,f,c.name);y&&y.id&&await l.roles.update(f,y.id,_)}}catch(l){console.error(`Failed to sync role "${c.name}" to tenant "${f}":`,l)}}))}return{afterCreate:async(c,s)=>{c.tenantId===a&&n(s)&&await o(s,"create")},afterUpdate:async(c,s,u)=>{c.tenantId===a&&n(u)&&await o(u,"update")},afterDelete:async(c,s)=>{c.tenantId===a&&console.warn(`Role ${s} was deleted from control plane. Child tenant roles with matching names should be deleted manually or implement role name tracking.`)}}}function G(t){const{controlPlaneTenantId:a,getControlPlaneAdapters:i,getAdapters:e,shouldSync:n=()=>!0,transformForSync:r,syncPermissions:d=!0}=t;return{async afterCreate(o,c){if(c.id!==a)try{const s=await i(),u=await e(c.id),f=await A.fetchAll(p=>s.roles.list(a,p),"roles",{cursorField:"id",pageSize:100}),l=new Map;if(await Promise.all(f.filter(p=>n(p)).map(async p=>{const _=p;try{const y=r?r(_,c.id):{name:_.name,description:_.description},T=await u.roles.create(c.id,{...y,is_system:!0});l.set(_.id,T.id)}catch(y){console.error(`Failed to sync role "${_.name}" to new tenant "${c.id}":`,y)}})),d)for(const[p,_]of l)try{const y=await s.rolePermissions.list(a,p,{});y.length>0&&await u.rolePermissions.assign(c.id,_,y.map(T=>({role_id:_,resource_server_identifier:T.resource_server_identifier,permission_name:T.permission_name})))}catch(y){console.error(`Failed to sync permissions for role to new tenant "${c.id}":`,y)}}catch(s){console.error(`Failed to sync roles to new tenant "${c.id}":`,s)}}}}function $(t,a){const i=new j.Hono;return i.get("/",async e=>{var f,l;const n=z.auth0QuerySchema.parse(e.req.query()),{page:r,per_page:d,include_totals:o,q:c}=n,s=e.var.user;if(t.accessControl&&(s!=null&&s.sub)){const p=t.accessControl.controlPlaneTenantId,y=(await e.env.data.userOrganizations.listUserOrganizations(p,s.sub,{})).organizations.map(P=>P.name),T=await e.env.data.tenants.list({page:r,per_page:d,include_totals:o,q:c}),S=T.tenants.filter(P=>y.includes(P.id));return o?e.json({tenants:S,start:((f=T.totals)==null?void 0:f.start)??0,limit:((l=T.totals)==null?void 0:l.limit)??d,length:S.length}):e.json(S)}const u=await e.env.data.tenants.list({page:r,per_page:d,include_totals:o,q:c});return o?e.json(u):e.json(u.tenants)}),i.get("/:id",async e=>{const n=e.req.param("id");if(t.accessControl){const d=e.var.user,o=t.accessControl.controlPlaneTenantId;if(n!==o){if(!(d!=null&&d.sub))throw new w(401,{message:"Authentication required"});if(!(await e.env.data.userOrganizations.listUserOrganizations(o,d.sub,{})).organizations.some(u=>u.name===n))throw new w(403,{message:"Access denied to this tenant"})}}const r=await e.env.data.tenants.get(n);if(!r)throw new w(404,{message:"Tenant not found"});return e.json(r)}),i.post("/",async e=>{var n,r,d;try{const o=e.var.user;if(!(o!=null&&o.sub))throw new w(401,{message:"Authentication required to create tenants"});let c=z.tenantInsertSchema.parse(await e.req.json());const s={adapters:e.env.data,ctx:e};(n=a.tenants)!=null&&n.beforeCreate&&(c=await a.tenants.beforeCreate(s,c));const u=await e.env.data.tenants.create(c);return(r=a.tenants)!=null&&r.afterCreate&&await a.tenants.afterCreate(s,u),e.json(u,201)}catch(o){throw o instanceof k.z.ZodError?new w(400,{message:"Validation error",cause:o}):o instanceof Error&&("code"in o&&o.code==="SQLITE_CONSTRAINT_PRIMARYKEY"||(d=o.message)!=null&&d.includes("UNIQUE constraint failed"))?new w(409,{message:"Tenant with this ID already exists"}):o}}),i.patch("/:id",async e=>{var l,p;const n=e.req.param("id");if(t.accessControl){const _=e.var.user;if(!(_!=null&&_.sub))throw new w(401,{message:"Authentication required to update tenants"});const y=t.accessControl.controlPlaneTenantId;if(n!==y&&!(await e.env.data.userOrganizations.listUserOrganizations(y,_.sub,{})).organizations.some(P=>P.name===n))throw new w(403,{message:"Access denied to update this tenant"})}const r=z.tenantInsertSchema.partial().parse(await e.req.json()),{id:d,...o}=r;if(!await e.env.data.tenants.get(n))throw new w(404,{message:"Tenant not found"});const s={adapters:e.env.data,ctx:e};let u=o;(l=a.tenants)!=null&&l.beforeUpdate&&(u=await a.tenants.beforeUpdate(s,n,o)),await e.env.data.tenants.update(n,u);const f=await e.env.data.tenants.get(n);if(!f)throw new w(404,{message:"Tenant not found after update"});return(p=a.tenants)!=null&&p.afterUpdate&&await a.tenants.afterUpdate(s,f),e.json(f)}),i.delete("/:id",async e=>{var o,c;const n=e.req.param("id");if(t.accessControl&&n===t.accessControl.controlPlaneTenantId)throw new w(400,{message:"Cannot delete the control plane"});if(t.accessControl){const s=e.var.user;if(!(s!=null&&s.sub))throw new w(401,{message:"Authentication required to delete tenants"});const u=t.accessControl.controlPlaneTenantId;if(!(await e.env.data.userOrganizations.listUserOrganizations(u,s.sub,{})).organizations.some(p=>p.name===n))throw new w(403,{message:"Access denied to delete this tenant"})}if(!await e.env.data.tenants.get(n))throw new w(404,{message:"Tenant not found"});const d={adapters:e.env.data,ctx:e};return(o=a.tenants)!=null&&o.beforeDelete&&await a.tenants.beforeDelete(d,n),await e.env.data.tenants.remove(n),(c=a.tenants)!=null&&c.afterDelete&&await a.tenants.afterDelete(d,n),e.body(null,204)}),i}function ae(t,a){const i=new b.OpenAPIHono;return i.openapi(b.createRoute({tags:["tenants"],method:"get",path:"/",request:{query:z.auth0QuerySchema},security:[{Bearer:[]}],responses:{200:{content:{"application/json":{schema:b.z.object({tenants:b.z.array(z.tenantSchema),start:b.z.number().optional(),limit:b.z.number().optional(),length:b.z.number().optional()})}},description:"List of tenants"}}}),async e=>{var f,l,p,_;const n=e.req.valid("query"),{page:r,per_page:d,include_totals:o,q:c}=n,s=e.var.user;if(t.accessControl&&(s!=null&&s.sub)){const y=t.accessControl.controlPlaneTenantId,S=(await A.fetchAll(I=>e.env.data.userOrganizations.listUserOrganizations(y,s.sub,I),"organizations")).map(I=>I.name),P=await e.env.data.tenants.list({page:r,per_page:d,include_totals:o,q:c}),O=P.tenants.filter(I=>S.includes(I.id));return o?e.json({tenants:O,start:((f=P.totals)==null?void 0:f.start)??0,limit:((l=P.totals)==null?void 0:l.limit)??d,length:O.length}):e.json({tenants:O})}const u=await e.env.data.tenants.list({page:r,per_page:d,include_totals:o,q:c});return o?e.json({tenants:u.tenants,start:((p=u.totals)==null?void 0:p.start)??0,limit:((_=u.totals)==null?void 0:_.limit)??d,length:u.tenants.length}):e.json({tenants:u.tenants})}),i.openapi(b.createRoute({tags:["tenants"],method:"get",path:"/{id}",request:{params:b.z.object({id:b.z.string()})},security:[{Bearer:[]}],responses:{200:{content:{"application/json":{schema:z.tenantSchema}},description:"Tenant details"},404:{description:"Tenant not found"}}}),async e=>{const{id:n}=e.req.valid("param");if(t.accessControl){const d=e.var.user,o=t.accessControl.controlPlaneTenantId;if(n!==o){if(!(d!=null&&d.sub))throw new w(401,{message:"Authentication required"});if(!(await A.fetchAll(u=>e.env.data.userOrganizations.listUserOrganizations(o,d.sub,u),"organizations")).some(u=>u.name===n))throw new w(403,{message:"Access denied to this tenant"})}}const r=await e.env.data.tenants.get(n);if(!r)throw new w(404,{message:"Tenant not found"});return e.json(r)}),i.openapi(b.createRoute({tags:["tenants"],method:"post",path:"/",request:{body:{content:{"application/json":{schema:z.tenantInsertSchema}}}},security:[{Bearer:[]}],responses:{201:{content:{"application/json":{schema:z.tenantSchema}},description:"Tenant created"},400:{description:"Validation error"}}}),async e=>{var c,s;const n=e.var.user;if(!(n!=null&&n.sub))throw new w(401,{message:"Authentication required to create tenants"});let r=e.req.valid("json");const d={adapters:e.env.data,ctx:e};(c=a.tenants)!=null&&c.beforeCreate&&(r=await a.tenants.beforeCreate(d,r));const o=await e.env.data.tenants.create(r);return(s=a.tenants)!=null&&s.afterCreate&&await a.tenants.afterCreate(d,o),e.json(o,201)}),i.openapi(b.createRoute({tags:["tenants"],method:"patch",path:"/{id}",request:{params:b.z.object({id:b.z.string()}),body:{content:{"application/json":{schema:b.z.object(z.tenantInsertSchema.shape).partial()}}}},security:[{Bearer:["update:tenants"]}],responses:{200:{content:{"application/json":{schema:z.tenantSchema}},description:"Tenant updated"},403:{description:"Access denied"},404:{description:"Tenant not found"}}}),async e=>{var u,f;const{id:n}=e.req.valid("param");if(t.accessControl){const l=e.var.user,p=t.accessControl.controlPlaneTenantId;if(!(l!=null&&l.sub))throw new w(401,{message:"Authentication required"});if(n!==p&&!(await A.fetchAll(T=>e.env.data.userOrganizations.listUserOrganizations(p,l.sub,T),"organizations")).some(T=>T.name===n))throw new w(403,{message:"Access denied to this tenant"})}if(!await e.env.data.tenants.get(n))throw new w(404,{message:"Tenant not found"});const d=e.req.valid("json"),o={adapters:e.env.data,ctx:e};let c=d;(u=a.tenants)!=null&&u.beforeUpdate&&(c=await a.tenants.beforeUpdate(o,n,d)),await e.env.data.tenants.update(n,c);const s=await e.env.data.tenants.get(n);if(!s)throw new w(500,{message:"Failed to retrieve updated tenant"});return(f=a.tenants)!=null&&f.afterUpdate&&await a.tenants.afterUpdate(o,s),e.json(s)}),i.openapi(b.createRoute({tags:["tenants"],method:"delete",path:"/{id}",request:{params:b.z.object({id:b.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 e=>{var o,c;const{id:n}=e.req.valid("param");if(t.accessControl){const s=e.var.user,u=t.accessControl.controlPlaneTenantId;if(!(s!=null&&s.sub))throw new w(401,{message:"Authentication required"});if(n===u)throw new w(403,{message:"Cannot delete the control plane"});if(!(await A.fetchAll(p=>e.env.data.userOrganizations.listUserOrganizations(u,s.sub,p),"organizations")).some(p=>p.name===n))throw new w(403,{message:"Access denied to this tenant"})}if(!await e.env.data.tenants.get(n))throw new w(404,{message:"Tenant not found"});const d={adapters:e.env.data,ctx:e};return(o=a.tenants)!=null&&o.beforeDelete&&await a.tenants.beforeDelete(d,n),await e.env.data.tenants.remove(n),(c=a.tenants)!=null&&c.afterDelete&&await a.tenants.afterDelete(d,n),e.body(null,204)}),i}function ne(t){const a=[{pattern:/\/api\/v2\/resource-servers\/([^/]+)$/,type:"resource_server"},{pattern:/\/api\/v2\/roles\/([^/]+)$/,type:"role"},{pattern:/\/api\/v2\/connections\/([^/]+)$/,type:"connection"}];for(const{pattern:i,type:e}of a){const n=t.match(i);if(n&&n[1])return{type:e,id:n[1]}}return null}async function se(t,a,i){try{switch(i.type){case"resource_server":{const e=await t.resourceServers.get(a,i.id);return(e==null?void 0:e.is_system)===!0}case"role":{const e=await t.roles.get(a,i.id);return(e==null?void 0:e.is_system)===!0}case"connection":{const e=await t.connections.get(a,i.id);return(e==null?void 0:e.is_system)===!0}default:return!1}}catch{return!1}}function re(t){return{resource_server:"resource server",role:"role",connection:"connection"}[t]}function Q(){return async(t,a)=>{if(!["PATCH","PUT","DELETE"].includes(t.req.method))return a();const i=ne(t.req.path);if(!i)return a();const e=t.var.tenant_id||t.req.header("x-tenant-id")||t.req.header("tenant-id");if(!e)return a();if(await se(t.env.data,e,i))throw new w(403,{message:`This ${re(i.type)} is a system resource and cannot be modified. Make changes in the control plane instead.`});return a()}}function L(t){return async(a,i)=>{if(!t.accessControl)return i();const e=a.var.tenant_id,n=a.var.organization_id;if(!e)throw new w(400,{message:"Tenant ID not found in request"});if(!F(n,e,t.accessControl.controlPlaneTenantId))throw new w(403,{message:`Access denied to tenant ${e}`});return i()}}function V(t){return async(a,i)=>{if(!t.subdomainRouting)return i();const{baseDomain:e,reservedSubdomains:n=[],resolveSubdomain:r}=t.subdomainRouting,d=a.req.header("host")||"";let o=null;if(d.endsWith(e)){const s=d.slice(0,-(e.length+1));s&&!s.includes(".")&&(o=s)}if(o&&n.includes(o)&&(o=null),!o)return t.accessControl&&a.set("tenant_id",t.accessControl.controlPlaneTenantId),i();let c=null;if(r)c=await r(o);else if(t.subdomainRouting.useOrganizations!==!1&&t.accessControl)try{const s=await a.env.data.organizations.get(t.accessControl.controlPlaneTenantId,o);s&&(c=s.id)}catch{}if(!c)throw new w(404,{message:`Tenant not found for subdomain: ${o}`});return a.set("tenant_id",c),i()}}function Y(t){return async(a,i)=>{if(!t.databaseIsolation)return i();const e=a.var.tenant_id;if(!e)throw new w(400,{message:"Tenant ID not found in request"});try{const n=await t.databaseIsolation.getAdapters(e);a.env.data=n}catch(n){throw console.error(`Failed to resolve database for tenant ${e}:`,n),new w(500,{message:"Failed to resolve tenant database"})}return i()}}function D(t){const a=V(t),i=L(t),e=Y(t);return async(n,r)=>(await a(n,async()=>{}),await i(n,async()=>{}),await e(n,async()=>{}),r())}function ie(t){const a=q(t);return{name:"multi-tenancy",middleware:D(t),hooks:a,routes:[{path:"/management",handler:$(t,a)}],onRegister:async()=>{console.log("Multi-tenancy plugin registered"),t.accessControl&&console.log(` - Access control enabled (control plane: ${t.accessControl.controlPlaneTenantId})`),t.subdomainRouting&&console.log(` - Subdomain routing enabled (base domain: ${t.subdomainRouting.baseDomain})`),t.databaseIsolation&&console.log(" - Database isolation enabled")}}}function q(t){const a=t.accessControl?U(t.accessControl):{},i=t.databaseIsolation?N(t.databaseIsolation):{},e=E(t);return{...a,...i,tenants:e}}function Z(t){const a=new j.Hono,i=q(t);return a.route("/tenants",$(t,i)),a}function oe(t){return{hooks:q(t),middleware:D(t),app:Z(t),config:t}}function ce(t){const{controlPlaneTenantId:a="control_plane",syncResourceServers:i=!0,syncRoles:e=!0,multiTenancy:n,entityHooks:r,...d}=t,o={...n,accessControl:{controlPlaneTenantId:a,requireOrganizationMatch:!1,defaultPermissions:["tenant:admin"],...n==null?void 0:n.accessControl}},c=q(o);let s,u;i&&(s=K({controlPlaneTenantId:a,getChildTenantIds:async()=>(await A.fetchAll(m=>t.dataAdapter.tenants.list(m),"tenants",{cursorField:"id",pageSize:100})).filter(m=>m.id!==a).map(m=>m.id),getAdapters:async h=>t.dataAdapter}),u=B({controlPlaneTenantId:a,getControlPlaneAdapters:async()=>t.dataAdapter,getAdapters:async h=>t.dataAdapter}));let f,l;e&&(f=W({controlPlaneTenantId:a,getChildTenantIds:async()=>(await A.fetchAll(m=>t.dataAdapter.tenants.list(m),"tenants",{cursorField:"id",pageSize:100})).filter(m=>m.id!==a).map(m=>m.id),getAdapters:async h=>t.dataAdapter}),l=G({controlPlaneTenantId:a,getControlPlaneAdapters:async()=>t.dataAdapter,getAdapters:async h=>t.dataAdapter,syncPermissions:!0}));const p=async(h,m,...g)=>{const v=[];if(h)try{await h(...g)}catch(C){v.push(C instanceof Error?C:new Error(String(C)))}if(m)try{await m(...g)}catch(C){v.push(C instanceof Error?C:new Error(String(C)))}if(v.length===1)throw v[0];if(v.length>1)throw new AggregateError(v,`Multiple hook errors: ${v.map(C=>C.message).join("; ")}`)},_=async(h,...m)=>{const g=[];for(const v of h)if(v)try{await v(...m)}catch(C){g.push(C instanceof Error?C:new Error(String(C)))}if(g.length===1)throw g[0];if(g.length>1)throw new AggregateError(g,`Multiple hook errors: ${g.map(v=>v.message).join("; ")}`)},y={...r,resourceServers:s?{...r==null?void 0:r.resourceServers,afterCreate:async(h,m)=>{var g;await p((g=r==null?void 0:r.resourceServers)==null?void 0:g.afterCreate,s==null?void 0:s.afterCreate,h,m)},afterUpdate:async(h,m,g)=>{var v;await p((v=r==null?void 0:r.resourceServers)==null?void 0:v.afterUpdate,s==null?void 0:s.afterUpdate,h,m,g)},afterDelete:async(h,m)=>{var g;await p((g=r==null?void 0:r.resourceServers)==null?void 0:g.afterDelete,s==null?void 0:s.afterDelete,h,m)}}:r==null?void 0:r.resourceServers,roles:f?{...r==null?void 0:r.roles,afterCreate:async(h,m)=>{var g;await p((g=r==null?void 0:r.roles)==null?void 0:g.afterCreate,f==null?void 0:f.afterCreate,h,m)},afterUpdate:async(h,m,g)=>{var v;await p((v=r==null?void 0:r.roles)==null?void 0:v.afterUpdate,f==null?void 0:f.afterUpdate,h,m,g)},afterDelete:async(h,m)=>{var g;await p((g=r==null?void 0:r.roles)==null?void 0:g.afterDelete,f==null?void 0:f.afterDelete,h,m)}}:r==null?void 0:r.roles,tenants:u||l?{...r==null?void 0:r.tenants,afterCreate:async(h,m)=>{var g;await _([(g=r==null?void 0:r.tenants)==null?void 0:g.afterCreate,u==null?void 0:u.afterCreate,l==null?void 0:l.afterCreate],h,m)}}:r==null?void 0:r.tenants},T={...c,tenants:u||l?{...c.tenants,afterCreate:async(h,m)=>{var g;(g=c.tenants)!=null&&g.afterCreate&&await c.tenants.afterCreate(h,m),await _([u==null?void 0:u.afterCreate,l==null?void 0:l.afterCreate],h,m)}}:c.tenants},S=ae(o,T),P=A.init({...d,entityHooks:y,managementApiExtensions:[...d.managementApiExtensions||[],{path:"/tenants",router:S}]}),{app:O,managementApp:I,...J}=P,R=new j.Hono;return R.onError((h,m)=>h instanceof w?h.getResponse():(console.error(h),m.json({message:"Internal Server Error"},500))),R.use("/api/v2/*",Q()),R.route("/",O),{app:R,managementApp:I,...J,multiTenancyConfig:o,multiTenancyHooks:c}}Object.defineProperty(exports,"MANAGEMENT_API_SCOPES",{enumerable:!0,get:()=>A.MANAGEMENT_API_SCOPES});Object.defineProperty(exports,"fetchAll",{enumerable:!0,get:()=>A.fetchAll});Object.defineProperty(exports,"seed",{enumerable:!0,get:()=>A.seed});exports.createAccessControlHooks=U;exports.createAccessControlMiddleware=L;exports.createDatabaseHooks=N;exports.createDatabaseMiddleware=Y;exports.createMultiTenancy=Z;exports.createMultiTenancyHooks=q;exports.createMultiTenancyMiddleware=D;exports.createMultiTenancyPlugin=ie;exports.createProtectSyncedMiddleware=Q;exports.createProvisioningHooks=E;exports.createResourceServerSyncHooks=K;exports.createRoleSyncHooks=W;exports.createSubdomainMiddleware=V;exports.createTenantResourceServerSyncHooks=B;exports.createTenantRoleSyncHooks=G;exports.createTenantsRouter=$;exports.init=ce;exports.setupMultiTenancy=oe;exports.validateTenantAccess=F;
|
|
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
|
@@ -1458,6 +1458,7 @@ declare const legacyClientSchema: z.ZodObject<{
|
|
|
1458
1458
|
revoke_refresh_token_grant: z.ZodOptional<z.ZodBoolean>;
|
|
1459
1459
|
trust_azure_adfs_email_verified_connection_property: z.ZodOptional<z.ZodBoolean>;
|
|
1460
1460
|
use_scope_descriptions_for_consent: z.ZodOptional<z.ZodBoolean>;
|
|
1461
|
+
inherit_global_permissions_in_organizations: z.ZodOptional<z.ZodBoolean>;
|
|
1461
1462
|
}, "strip", z.ZodTypeAny, {
|
|
1462
1463
|
allow_changing_enable_sso?: boolean | undefined;
|
|
1463
1464
|
allow_legacy_delegation_grant_types?: boolean | undefined;
|
|
@@ -1491,6 +1492,7 @@ declare const legacyClientSchema: z.ZodObject<{
|
|
|
1491
1492
|
revoke_refresh_token_grant?: boolean | undefined;
|
|
1492
1493
|
trust_azure_adfs_email_verified_connection_property?: boolean | undefined;
|
|
1493
1494
|
use_scope_descriptions_for_consent?: boolean | undefined;
|
|
1495
|
+
inherit_global_permissions_in_organizations?: boolean | undefined;
|
|
1494
1496
|
}, {
|
|
1495
1497
|
allow_changing_enable_sso?: boolean | undefined;
|
|
1496
1498
|
allow_legacy_delegation_grant_types?: boolean | undefined;
|
|
@@ -1524,6 +1526,7 @@ declare const legacyClientSchema: z.ZodObject<{
|
|
|
1524
1526
|
revoke_refresh_token_grant?: boolean | undefined;
|
|
1525
1527
|
trust_azure_adfs_email_verified_connection_property?: boolean | undefined;
|
|
1526
1528
|
use_scope_descriptions_for_consent?: boolean | undefined;
|
|
1529
|
+
inherit_global_permissions_in_organizations?: boolean | undefined;
|
|
1527
1530
|
}>>;
|
|
1528
1531
|
sandbox_version: z.ZodOptional<z.ZodString>;
|
|
1529
1532
|
legacy_sandbox_version: z.ZodOptional<z.ZodString>;
|
|
@@ -1685,6 +1688,7 @@ declare const legacyClientSchema: z.ZodObject<{
|
|
|
1685
1688
|
revoke_refresh_token_grant?: boolean | undefined;
|
|
1686
1689
|
trust_azure_adfs_email_verified_connection_property?: boolean | undefined;
|
|
1687
1690
|
use_scope_descriptions_for_consent?: boolean | undefined;
|
|
1691
|
+
inherit_global_permissions_in_organizations?: boolean | undefined;
|
|
1688
1692
|
} | undefined;
|
|
1689
1693
|
sandbox_version?: string | undefined;
|
|
1690
1694
|
legacy_sandbox_version?: string | undefined;
|
|
@@ -1785,6 +1789,7 @@ declare const legacyClientSchema: z.ZodObject<{
|
|
|
1785
1789
|
revoke_refresh_token_grant?: boolean | undefined;
|
|
1786
1790
|
trust_azure_adfs_email_verified_connection_property?: boolean | undefined;
|
|
1787
1791
|
use_scope_descriptions_for_consent?: boolean | undefined;
|
|
1792
|
+
inherit_global_permissions_in_organizations?: boolean | undefined;
|
|
1788
1793
|
} | undefined;
|
|
1789
1794
|
sandbox_version?: string | undefined;
|
|
1790
1795
|
legacy_sandbox_version?: string | undefined;
|
|
@@ -2175,6 +2180,7 @@ declare const legacyClientSchema: z.ZodObject<{
|
|
|
2175
2180
|
revoke_refresh_token_grant?: boolean | undefined;
|
|
2176
2181
|
trust_azure_adfs_email_verified_connection_property?: boolean | undefined;
|
|
2177
2182
|
use_scope_descriptions_for_consent?: boolean | undefined;
|
|
2183
|
+
inherit_global_permissions_in_organizations?: boolean | undefined;
|
|
2178
2184
|
} | undefined;
|
|
2179
2185
|
sandbox_version?: string | undefined;
|
|
2180
2186
|
legacy_sandbox_version?: string | undefined;
|
|
@@ -2352,6 +2358,7 @@ declare const legacyClientSchema: z.ZodObject<{
|
|
|
2352
2358
|
revoke_refresh_token_grant?: boolean | undefined;
|
|
2353
2359
|
trust_azure_adfs_email_verified_connection_property?: boolean | undefined;
|
|
2354
2360
|
use_scope_descriptions_for_consent?: boolean | undefined;
|
|
2361
|
+
inherit_global_permissions_in_organizations?: boolean | undefined;
|
|
2355
2362
|
} | undefined;
|
|
2356
2363
|
sandbox_version?: string | undefined;
|
|
2357
2364
|
legacy_sandbox_version?: string | undefined;
|
|
@@ -12062,6 +12069,7 @@ declare const tenantSchema: z.ZodObject<{
|
|
|
12062
12069
|
revoke_refresh_token_grant: z.ZodOptional<z.ZodBoolean>;
|
|
12063
12070
|
trust_azure_adfs_email_verified_connection_property: z.ZodOptional<z.ZodBoolean>;
|
|
12064
12071
|
use_scope_descriptions_for_consent: z.ZodOptional<z.ZodBoolean>;
|
|
12072
|
+
inherit_global_permissions_in_organizations: z.ZodOptional<z.ZodBoolean>;
|
|
12065
12073
|
}, "strip", z.ZodTypeAny, {
|
|
12066
12074
|
allow_changing_enable_sso?: boolean | undefined;
|
|
12067
12075
|
allow_legacy_delegation_grant_types?: boolean | undefined;
|
|
@@ -12095,6 +12103,7 @@ declare const tenantSchema: z.ZodObject<{
|
|
|
12095
12103
|
revoke_refresh_token_grant?: boolean | undefined;
|
|
12096
12104
|
trust_azure_adfs_email_verified_connection_property?: boolean | undefined;
|
|
12097
12105
|
use_scope_descriptions_for_consent?: boolean | undefined;
|
|
12106
|
+
inherit_global_permissions_in_organizations?: boolean | undefined;
|
|
12098
12107
|
}, {
|
|
12099
12108
|
allow_changing_enable_sso?: boolean | undefined;
|
|
12100
12109
|
allow_legacy_delegation_grant_types?: boolean | undefined;
|
|
@@ -12128,6 +12137,7 @@ declare const tenantSchema: z.ZodObject<{
|
|
|
12128
12137
|
revoke_refresh_token_grant?: boolean | undefined;
|
|
12129
12138
|
trust_azure_adfs_email_verified_connection_property?: boolean | undefined;
|
|
12130
12139
|
use_scope_descriptions_for_consent?: boolean | undefined;
|
|
12140
|
+
inherit_global_permissions_in_organizations?: boolean | undefined;
|
|
12131
12141
|
}>>;
|
|
12132
12142
|
sandbox_version: z.ZodOptional<z.ZodString>;
|
|
12133
12143
|
legacy_sandbox_version: z.ZodOptional<z.ZodString>;
|
|
@@ -12289,6 +12299,7 @@ declare const tenantSchema: z.ZodObject<{
|
|
|
12289
12299
|
revoke_refresh_token_grant?: boolean | undefined;
|
|
12290
12300
|
trust_azure_adfs_email_verified_connection_property?: boolean | undefined;
|
|
12291
12301
|
use_scope_descriptions_for_consent?: boolean | undefined;
|
|
12302
|
+
inherit_global_permissions_in_organizations?: boolean | undefined;
|
|
12292
12303
|
} | undefined;
|
|
12293
12304
|
sandbox_version?: string | undefined;
|
|
12294
12305
|
legacy_sandbox_version?: string | undefined;
|
|
@@ -12389,6 +12400,7 @@ declare const tenantSchema: z.ZodObject<{
|
|
|
12389
12400
|
revoke_refresh_token_grant?: boolean | undefined;
|
|
12390
12401
|
trust_azure_adfs_email_verified_connection_property?: boolean | undefined;
|
|
12391
12402
|
use_scope_descriptions_for_consent?: boolean | undefined;
|
|
12403
|
+
inherit_global_permissions_in_organizations?: boolean | undefined;
|
|
12392
12404
|
} | undefined;
|
|
12393
12405
|
sandbox_version?: string | undefined;
|
|
12394
12406
|
legacy_sandbox_version?: string | undefined;
|
|
@@ -16700,6 +16712,7 @@ declare const legacyClientSchema$1: z.ZodObject<{
|
|
|
16700
16712
|
revoke_refresh_token_grant: z.ZodOptional<z.ZodBoolean>;
|
|
16701
16713
|
trust_azure_adfs_email_verified_connection_property: z.ZodOptional<z.ZodBoolean>;
|
|
16702
16714
|
use_scope_descriptions_for_consent: z.ZodOptional<z.ZodBoolean>;
|
|
16715
|
+
inherit_global_permissions_in_organizations: z.ZodOptional<z.ZodBoolean>;
|
|
16703
16716
|
}, "strip", z.ZodTypeAny, {
|
|
16704
16717
|
allow_changing_enable_sso?: boolean | undefined;
|
|
16705
16718
|
allow_legacy_delegation_grant_types?: boolean | undefined;
|
|
@@ -16733,6 +16746,7 @@ declare const legacyClientSchema$1: z.ZodObject<{
|
|
|
16733
16746
|
revoke_refresh_token_grant?: boolean | undefined;
|
|
16734
16747
|
trust_azure_adfs_email_verified_connection_property?: boolean | undefined;
|
|
16735
16748
|
use_scope_descriptions_for_consent?: boolean | undefined;
|
|
16749
|
+
inherit_global_permissions_in_organizations?: boolean | undefined;
|
|
16736
16750
|
}, {
|
|
16737
16751
|
allow_changing_enable_sso?: boolean | undefined;
|
|
16738
16752
|
allow_legacy_delegation_grant_types?: boolean | undefined;
|
|
@@ -16766,6 +16780,7 @@ declare const legacyClientSchema$1: z.ZodObject<{
|
|
|
16766
16780
|
revoke_refresh_token_grant?: boolean | undefined;
|
|
16767
16781
|
trust_azure_adfs_email_verified_connection_property?: boolean | undefined;
|
|
16768
16782
|
use_scope_descriptions_for_consent?: boolean | undefined;
|
|
16783
|
+
inherit_global_permissions_in_organizations?: boolean | undefined;
|
|
16769
16784
|
}>>;
|
|
16770
16785
|
sandbox_version: z.ZodOptional<z.ZodString>;
|
|
16771
16786
|
legacy_sandbox_version: z.ZodOptional<z.ZodString>;
|
|
@@ -16927,6 +16942,7 @@ declare const legacyClientSchema$1: z.ZodObject<{
|
|
|
16927
16942
|
revoke_refresh_token_grant?: boolean | undefined;
|
|
16928
16943
|
trust_azure_adfs_email_verified_connection_property?: boolean | undefined;
|
|
16929
16944
|
use_scope_descriptions_for_consent?: boolean | undefined;
|
|
16945
|
+
inherit_global_permissions_in_organizations?: boolean | undefined;
|
|
16930
16946
|
} | undefined;
|
|
16931
16947
|
sandbox_version?: string | undefined;
|
|
16932
16948
|
legacy_sandbox_version?: string | undefined;
|
|
@@ -17027,6 +17043,7 @@ declare const legacyClientSchema$1: z.ZodObject<{
|
|
|
17027
17043
|
revoke_refresh_token_grant?: boolean | undefined;
|
|
17028
17044
|
trust_azure_adfs_email_verified_connection_property?: boolean | undefined;
|
|
17029
17045
|
use_scope_descriptions_for_consent?: boolean | undefined;
|
|
17046
|
+
inherit_global_permissions_in_organizations?: boolean | undefined;
|
|
17030
17047
|
} | undefined;
|
|
17031
17048
|
sandbox_version?: string | undefined;
|
|
17032
17049
|
legacy_sandbox_version?: string | undefined;
|
|
@@ -17417,6 +17434,7 @@ declare const legacyClientSchema$1: z.ZodObject<{
|
|
|
17417
17434
|
revoke_refresh_token_grant?: boolean | undefined;
|
|
17418
17435
|
trust_azure_adfs_email_verified_connection_property?: boolean | undefined;
|
|
17419
17436
|
use_scope_descriptions_for_consent?: boolean | undefined;
|
|
17437
|
+
inherit_global_permissions_in_organizations?: boolean | undefined;
|
|
17420
17438
|
} | undefined;
|
|
17421
17439
|
sandbox_version?: string | undefined;
|
|
17422
17440
|
legacy_sandbox_version?: string | undefined;
|
|
@@ -17594,6 +17612,7 @@ declare const legacyClientSchema$1: z.ZodObject<{
|
|
|
17594
17612
|
revoke_refresh_token_grant?: boolean | undefined;
|
|
17595
17613
|
trust_azure_adfs_email_verified_connection_property?: boolean | undefined;
|
|
17596
17614
|
use_scope_descriptions_for_consent?: boolean | undefined;
|
|
17615
|
+
inherit_global_permissions_in_organizations?: boolean | undefined;
|
|
17597
17616
|
} | undefined;
|
|
17598
17617
|
sandbox_version?: string | undefined;
|
|
17599
17618
|
legacy_sandbox_version?: string | undefined;
|
|
@@ -27304,6 +27323,7 @@ declare const tenantSchema$1: z.ZodObject<{
|
|
|
27304
27323
|
revoke_refresh_token_grant: z.ZodOptional<z.ZodBoolean>;
|
|
27305
27324
|
trust_azure_adfs_email_verified_connection_property: z.ZodOptional<z.ZodBoolean>;
|
|
27306
27325
|
use_scope_descriptions_for_consent: z.ZodOptional<z.ZodBoolean>;
|
|
27326
|
+
inherit_global_permissions_in_organizations: z.ZodOptional<z.ZodBoolean>;
|
|
27307
27327
|
}, "strip", z.ZodTypeAny, {
|
|
27308
27328
|
allow_changing_enable_sso?: boolean | undefined;
|
|
27309
27329
|
allow_legacy_delegation_grant_types?: boolean | undefined;
|
|
@@ -27337,6 +27357,7 @@ declare const tenantSchema$1: z.ZodObject<{
|
|
|
27337
27357
|
revoke_refresh_token_grant?: boolean | undefined;
|
|
27338
27358
|
trust_azure_adfs_email_verified_connection_property?: boolean | undefined;
|
|
27339
27359
|
use_scope_descriptions_for_consent?: boolean | undefined;
|
|
27360
|
+
inherit_global_permissions_in_organizations?: boolean | undefined;
|
|
27340
27361
|
}, {
|
|
27341
27362
|
allow_changing_enable_sso?: boolean | undefined;
|
|
27342
27363
|
allow_legacy_delegation_grant_types?: boolean | undefined;
|
|
@@ -27370,6 +27391,7 @@ declare const tenantSchema$1: z.ZodObject<{
|
|
|
27370
27391
|
revoke_refresh_token_grant?: boolean | undefined;
|
|
27371
27392
|
trust_azure_adfs_email_verified_connection_property?: boolean | undefined;
|
|
27372
27393
|
use_scope_descriptions_for_consent?: boolean | undefined;
|
|
27394
|
+
inherit_global_permissions_in_organizations?: boolean | undefined;
|
|
27373
27395
|
}>>;
|
|
27374
27396
|
sandbox_version: z.ZodOptional<z.ZodString>;
|
|
27375
27397
|
legacy_sandbox_version: z.ZodOptional<z.ZodString>;
|
|
@@ -27531,6 +27553,7 @@ declare const tenantSchema$1: z.ZodObject<{
|
|
|
27531
27553
|
revoke_refresh_token_grant?: boolean | undefined;
|
|
27532
27554
|
trust_azure_adfs_email_verified_connection_property?: boolean | undefined;
|
|
27533
27555
|
use_scope_descriptions_for_consent?: boolean | undefined;
|
|
27556
|
+
inherit_global_permissions_in_organizations?: boolean | undefined;
|
|
27534
27557
|
} | undefined;
|
|
27535
27558
|
sandbox_version?: string | undefined;
|
|
27536
27559
|
legacy_sandbox_version?: string | undefined;
|
|
@@ -27631,6 +27654,7 @@ declare const tenantSchema$1: z.ZodObject<{
|
|
|
27631
27654
|
revoke_refresh_token_grant?: boolean | undefined;
|
|
27632
27655
|
trust_azure_adfs_email_verified_connection_property?: boolean | undefined;
|
|
27633
27656
|
use_scope_descriptions_for_consent?: boolean | undefined;
|
|
27657
|
+
inherit_global_permissions_in_organizations?: boolean | undefined;
|
|
27634
27658
|
} | undefined;
|
|
27635
27659
|
sandbox_version?: string | undefined;
|
|
27636
27660
|
legacy_sandbox_version?: string | undefined;
|
|
@@ -30532,21 +30556,20 @@ export interface TenantRoleSyncConfig {
|
|
|
30532
30556
|
*/
|
|
30533
30557
|
export declare function createTenantRoleSyncHooks(config: TenantRoleSyncConfig): TenantEntityHooks;
|
|
30534
30558
|
/**
|
|
30535
|
-
* Creates
|
|
30559
|
+
* Creates OpenAPI-based tenant management routes.
|
|
30536
30560
|
*
|
|
30537
|
-
* These routes handle CRUD operations for tenants and
|
|
30538
|
-
* on
|
|
30539
|
-
*
|
|
30540
|
-
* Access to these routes should be restricted to the control plane.
|
|
30561
|
+
* These routes handle CRUD operations for tenants and are designed to be
|
|
30562
|
+
* mounted on authhero's management API so they get the same authentication
|
|
30563
|
+
* middleware.
|
|
30541
30564
|
*
|
|
30542
30565
|
* @param config - Multi-tenancy configuration
|
|
30543
30566
|
* @param hooks - Multi-tenancy hooks for lifecycle events
|
|
30544
|
-
* @returns
|
|
30567
|
+
* @returns OpenAPIHono router with tenant routes
|
|
30545
30568
|
*/
|
|
30546
|
-
export declare function
|
|
30569
|
+
export declare function createTenantsOpenAPIRouter(config: MultiTenancyConfig, hooks: MultiTenancyHooks): OpenAPIHono<{
|
|
30547
30570
|
Bindings: MultiTenancyBindings;
|
|
30548
30571
|
Variables: MultiTenancyVariables;
|
|
30549
|
-
},
|
|
30572
|
+
}, {}, "/">;
|
|
30550
30573
|
/**
|
|
30551
30574
|
* Bindings for the protect system middleware
|
|
30552
30575
|
*/
|
|
@@ -38910,6 +38933,7 @@ export declare function init(config: MultiTenantAuthHeroConfig): {
|
|
|
38910
38933
|
revoke_refresh_token_grant?: boolean | undefined | undefined;
|
|
38911
38934
|
trust_azure_adfs_email_verified_connection_property?: boolean | undefined | undefined;
|
|
38912
38935
|
use_scope_descriptions_for_consent?: boolean | undefined | undefined;
|
|
38936
|
+
inherit_global_permissions_in_organizations?: boolean | undefined | undefined;
|
|
38913
38937
|
} | undefined;
|
|
38914
38938
|
sandbox_version?: string | undefined | undefined;
|
|
38915
38939
|
legacy_sandbox_version?: string | undefined | undefined;
|
|
@@ -39028,6 +39052,7 @@ export declare function init(config: MultiTenantAuthHeroConfig): {
|
|
|
39028
39052
|
revoke_refresh_token_grant?: boolean | undefined;
|
|
39029
39053
|
trust_azure_adfs_email_verified_connection_property?: boolean | undefined;
|
|
39030
39054
|
use_scope_descriptions_for_consent?: boolean | undefined;
|
|
39055
|
+
inherit_global_permissions_in_organizations?: boolean | undefined;
|
|
39031
39056
|
} | undefined;
|
|
39032
39057
|
sandbox_version?: string | undefined;
|
|
39033
39058
|
legacy_sandbox_version?: string | undefined;
|
|
@@ -39127,6 +39152,7 @@ export declare function init(config: MultiTenantAuthHeroConfig): {
|
|
|
39127
39152
|
revoke_refresh_token_grant?: boolean | undefined | undefined;
|
|
39128
39153
|
trust_azure_adfs_email_verified_connection_property?: boolean | undefined | undefined;
|
|
39129
39154
|
use_scope_descriptions_for_consent?: boolean | undefined | undefined;
|
|
39155
|
+
inherit_global_permissions_in_organizations?: boolean | undefined | undefined;
|
|
39130
39156
|
} | undefined;
|
|
39131
39157
|
sandbox_version?: string | undefined | undefined;
|
|
39132
39158
|
legacy_sandbox_version?: string | undefined | undefined;
|