@authhero/multi-tenancy 15.0.2 → 15.1.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.mjs +121 -113
- package/dist/types/middleware/index.d.ts.map +1 -1
- package/dist/types/middleware/protect-synced.d.ts +1 -0
- package/dist/types/middleware/protect-synced.d.ts.map +1 -1
- package/dist/types/middleware/request-data.d.ts +15 -0
- package/dist/types/middleware/request-data.d.ts.map +1 -0
- package/dist/types/routes/tenants.d.ts.map +1 -1
- package/dist/types/types.d.ts +7 -0
- package/dist/types/types.d.ts.map +1 -1
- package/package.json +4 -4
package/dist/multi-tenancy.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});let e=require("hono"),t=require("authhero"),n=require("@hono/zod-openapi"),r=require("hono/http-exception");function i(e){let{controlPlaneTenantId:t,requireOrganizationMatch:n=!0}=e;return{async onTenantAccessValidation(e,r){if(r===t)return!0;if(n){let t=e.var.org_name,n=e.var.organization_id,i=t||n;return i?i.toLowerCase()===r.toLowerCase():!1}return!0}}}function a(e,t,n,r){if(t===n)return!0;let i=r||e;return i?i.toLowerCase()===t.toLowerCase():!1}function o(e){return{async resolveDataAdapters(t){try{return await e.getAdapters(t)}catch(e){console.error(`Failed to resolve data adapters for tenant ${t}:`,e);return}}}}var s=64;function c(e){return e.replace(/[^a-zA-Z0-9_-]/g,`-`)}function l(e){let t=c(e.id),n=Math.max(0,s-(5+t.length)),r=c(e.kind).slice(0,n),i=3+r.length+2+t.length,a=Math.max(0,s-i);return`op-${r}-${c(e.tenant_id??`fleet`).slice(0,a)}-${t}`.slice(0,s)}var u=2048;function d(e){let t;if(e instanceof Error)t=e.message;else try{t=String(e??`unknown error`)}catch{t=Object.prototype.toString.call(e)}return t.slice(0,u)}function f(e){let{tenantOperations:t,tenantOperationEvents:n}=e;return{async markRunning(e,n){await t.update(e,{status:`running`,...n===void 0?{}:{current_step:n}})},async setCurrentStep(e,n){await t.update(e,{current_step:n})},async appendEvent(e,t){await n.create({operation_id:e,step:t.step,outcome:t.outcome,detail:t.detail,attempt:t.attempt??1})},async markSucceeded(e){await t.update(e,{status:`succeeded`,error:null,finished_at:new Date().toISOString()})},async markFailed(e,n){await t.update(e,{status:`failed`,error:d(n),finished_at:new Date().toISOString()})}}}function p(e){return e===`succeeded`||e===`failed`||e===`cancelled`}var m={async do(e,t,n){let r=typeof t==`function`?t:n;if(!r)throw Error(`StepRunner.do called without a function`);return r()}};function h(e){let t=f(e.stores);return{engine:`inline`,async start(n){let r=e.definitions[n.kind];if(!r){let e=Error(`No inline operation definition for kind "${n.kind}"`);throw await t.markFailed(n.id,e),e}let i=r(n);await t.markRunning(n.id,i[0]?.name);for(let e of i){await t.setCurrentStep(n.id,e.name),await t.appendEvent(n.id,{step:e.name,outcome:`started`});try{let r=await e.run({operation:n,step:m});await t.appendEvent(n.id,{step:e.name,outcome:`succeeded`,detail:r??void 0})}catch(r){throw await t.appendEvent(n.id,{step:e.name,outcome:`failed`,detail:{message:d(r)}}),await t.markFailed(n.id,r),r}}await t.markSucceeded(n.id)}}}async function g(e,t,n){let r=await e.tenantOperations.create({tenant_id:t.tenant_id,rollout_id:t.rollout_id,kind:t.kind,engine:n,initiated_by:t.initiated_by,target_worker_version:t.target_worker_version,target_database_version:t.target_database_version}),i=l(r);try{await e.tenantOperations.update(r.id,{engine_instance_id:i})}catch(t){try{await f(e).markFailed(r.id,t)}catch{}throw t}return{...r,engine_instance_id:i}}async function _(e,t,n){let r=f(e),i=await g(e,n,t.engine);try{await t.start(i)}catch(t){try{let n=await e.tenantOperations.get(i.id);n&&!p(n.status)&&await r.markFailed(i.id,t)}catch(e){console.warn(`Failed to record tenant operation failure:`,e)}throw t}try{return await e.tenantOperations.get(i.id)??i}catch(e){return console.warn(`Failed to re-fetch tenant operation after start:`,e),i}}function v(e){if(e.tenantOperations&&e.tenantOperationEvents)return{tenantOperations:e.tenantOperations,tenantOperationEvents:e.tenantOperationEvents}}async function y(e,t,n){let r=v(e);if(!r){await n(void 0);return}let i=f(r),a=async e=>{try{await e()}catch(e){console.warn(`Failed to record tenant operation progress:`,e)}},o;if(await a(async()=>{let e=await g(r,t,`inline`);o=e.id,await i.markRunning(e.id)}),!o){await n(void 0);return}let s=o,c=!1,l=async(e,t,n)=>{c=!0,await a(async()=>{t===`started`&&await i.setCurrentStep(s,e),await i.appendEvent(s,{step:e,outcome:t,detail:n})})};try{await n(l)}catch(e){throw await a(async()=>{c||await i.appendEvent(s,{step:t.kind,outcome:`failed`,detail:{message:d(e)}}),await i.markFailed(s,e)}),e}await a(async()=>{c||await i.appendEvent(s,{step:t.kind,outcome:`succeeded`}),await i.markSucceeded(s)})}function b(e){return`urn:authhero:tenant:${e.toLowerCase()}`}function x(e){return{async beforeCreate(e,t){return!t.audience&&t.id?{...t,audience:b(t.id)}:t},async afterCreate(n,r){let{accessControl:i,databaseIsolation:a}=e;if(i&&n.ctx&&await S(n,r,i),a?.onProvision){let e=a.onProvision;a.recordProvisionOperations===!1?await e(r.id):await y(n.adapters,{kind:`provision`,tenant_id:r.id,initiated_by:n.ctx?.var.user?.sub},t=>e(r.id,t))}else try{await(0,t.provisionDefaultClients)(n.adapters,r.id,{managementApiIdentifier:t.MANAGEMENT_API_AUDIENCE,managementApiScopes:t.MANAGEMENT_API_SCOPES})}catch(e){throw console.warn(`Failed to provision default clients for tenant ${r.id}:`,e),e}},async beforeDelete(t,n){let{accessControl:r,databaseIsolation:i}=e;if(r)try{let e=(await t.adapters.organizations.list(r.controlPlaneTenantId)).organizations.find(e=>e.name===n);e&&await t.adapters.organizations.remove(r.controlPlaneTenantId,e.id)}catch(e){console.warn(`Failed to remove organization for tenant ${n}:`,e)}if(i?.onDeprovision)try{await i.onDeprovision(n)}catch(e){console.warn(`Failed to deprovision database for tenant ${n}:`,e)}}}}async function S(e,t,n){let{controlPlaneTenantId:r,defaultPermissions:i,defaultRoles:a,issuer:o,adminRoleName:s=`Tenant Admin`,adminRoleDescription:c=`Full access to all tenant management operations`,addCreatorToOrganization:l=!0}=n,u=await e.adapters.organizations.create(r,{name:t.id,display_name:t.friendly_name||t.id}),d;if(o&&(d=await w(e,r,s,c)),l&&e.ctx){let t=e.ctx.var.user;if(t?.sub&&!await C(e,r,t.sub))try{await e.adapters.userOrganizations.create(r,{user_id:t.sub,organization_id:u.id}),d&&await e.adapters.userRoles.create(r,t.sub,d,u.id)}catch(e){console.warn(`Failed to add creator ${t.sub} to organization ${u.id}:`,e)}}a&&a.length>0&&console.log(`Would assign roles ${a.join(`, `)} to organization ${u.id}`),i&&i.length>0&&console.log(`Would grant permissions ${i.join(`, `)} to organization ${u.id}`)}async function C(e,n,r){let i=await e.adapters.userRoles.list(n,r,void 0,``);for(let r of i)if((await e.adapters.rolePermissions.list(n,r.id,{per_page:1e3})).some(e=>e.permission_name===`admin:organizations`&&e.resource_server_identifier===t.MANAGEMENT_API_AUDIENCE))return!0;return!1}async function w(e,n,r,i){let a=(await e.adapters.roles.list(n,{})).roles.find(e=>e.name===r);if(a)return a.id;let o=await e.adapters.roles.create(n,{name:r,description:i}),s=t.MANAGEMENT_API_AUDIENCE,c=t.MANAGEMENT_API_SCOPES.map(e=>({role_id:o.id,resource_server_identifier:s,permission_name:e.value}));return await e.adapters.rolePermissions.assign(n,o.id,c),o.id}function T(e,n,r=()=>!0){let{controlPlaneTenantId:i,getChildTenantIds:a,getAdapters:o}=e,s=new Map;async function c(e,r,i){return(await n(e).list(r,{q:`name:${(0,t.escapeLuceneValue)(i)}`,per_page:1}))[0]??null}async function l(e){let t=await a(),r=n(await o(i));await Promise.all(t.map(async t=>{try{let i=await o(t),a=n(i),s={...r.transform(e),is_system:!0},l=await c(i,t,e.name),u=l?a.getId(l):void 0;if(l&&u){let e=a.preserveOnUpdate?a.preserveOnUpdate(l,s):s;await a.update(t,u,e)}else await a.create(t,s)}catch(n){console.error(`Failed to sync ${r.listKey} "${e.name}" to tenant "${t}":`,n)}}))}async function u(e){let t=await a();await Promise.all(t.map(async t=>{try{let r=await o(t),i=n(r),a=await c(r,t,e),s=a?i.getId(a):void 0;a&&s&&await i.remove(t,s)}catch(n){console.error(`Failed to delete entity "${e}" from tenant "${t}":`,n)}}))}return{afterCreate:async(e,t)=>{e.tenantId===i&&r(t)&&await l(t)},afterUpdate:async(e,t,n)=>{e.tenantId===i&&r(n)&&await l(n)},beforeDelete:async(e,t)=>{if(e.tenantId!==i)return;let a=await n(e.adapters).get(e.tenantId,t);a&&r(a)&&s.set(t,a)},afterDelete:async(e,t)=>{if(e.tenantId!==i)return;let n=s.get(t);n&&(s.delete(t),await u(n.name))}}}function E(e,n,r=()=>!0){let{controlPlaneTenantId:i,getControlPlaneAdapters:a,getAdapters:o}=e;return{async afterCreate(e,s){if(s.id!==i)try{let e=await a(),c=await o(s.id),l=n(e),u=n(c),d=await(0,t.fetchAll)(e=>l.listPaginated(i,e),l.listKey,{cursorField:`id`,pageSize:100});await Promise.all(d.filter(e=>r(e)).map(async e=>{try{let t=l.transform(e);await u.create(s.id,{...t,is_system:!0})}catch(e){console.error(`Failed to sync entity to new tenant "${s.id}":`,e)}}))}catch(e){console.error(`Failed to sync entities to new tenant "${s.id}":`,e)}}}}var D=e=>({list:async(t,n)=>(await e.resourceServers.list(t,n)).resource_servers,listPaginated:(t,n)=>e.resourceServers.list(t,n),get:(t,n)=>e.resourceServers.get(t,n),create:(t,n)=>e.resourceServers.create(t,n),update:(t,n,r)=>e.resourceServers.update(t,n,r),remove:(t,n)=>e.resourceServers.remove(t,n),listKey:`resource_servers`,getId:e=>e.id,transform:e=>({id:e.id,name:e.name,identifier:e.identifier,scopes:e.scopes,signing_alg:e.signing_alg,token_lifetime:e.token_lifetime,token_lifetime_for_web:e.token_lifetime_for_web})}),O=e=>({list:async(t,n)=>(await e.roles.list(t,n)).roles,listPaginated:(t,n)=>e.roles.list(t,n),get:(t,n)=>e.roles.get(t,n),create:(t,n)=>e.roles.create(t,n),update:(t,n,r)=>e.roles.update(t,n,r),remove:(t,n)=>e.roles.remove(t,n),listKey:`roles`,getId:e=>e.id,transform:e=>({id:e.id,name:e.name,description:e.description})});function k(e){return e.metadata?.sync!==!1}function A(e){let{sync:n={},filters:r={}}=e,i=n.resourceServers??!0,a=n.roles??!0,o=e=>k(e)?r.resourceServers?r.resourceServers(e):!0:!1,s=e=>k(e)?r.roles?r.roles(e):!0:!1,c=i?T(e,D,o):void 0,l=a?T(e,O,s):void 0,u=i?E(e,D,o):void 0,d=a?E(e,O,s):void 0,f=a?{async afterCreate(n,i){if(i.id!==e.controlPlaneTenantId){await d?.afterCreate?.(n,i);try{let n=await e.getControlPlaneAdapters(),a=await e.getAdapters(i.id),o=await(0,t.fetchAll)(t=>n.roles.list(e.controlPlaneTenantId,t),`roles`,{cursorField:`id`,pageSize:100}),s=new Map;for(let e of o.filter(e=>r.roles?.(e)??!0)){let t=await p(a,i.id,e.name);t&&s.set(e.name,t.id)}for(let t of o.filter(e=>r.roles?.(e)??!0)){let r=s.get(t.name);if(r)try{let o=await n.rolePermissions.list(e.controlPlaneTenantId,t.id,{});o.length>0&&await a.rolePermissions.assign(i.id,r,o.map(e=>({role_id:r,resource_server_identifier:e.resource_server_identifier,permission_name:e.permission_name})))}catch(e){console.error(`Failed to sync permissions for role "${t.name}" to tenant "${i.id}":`,e)}}}catch(e){console.error(`Failed to sync role permissions to tenant "${i.id}":`,e)}}}}:void 0;async function p(e,n,r){return(await e.roles.list(n,{q:`name:${(0,t.escapeLuceneValue)(r)}`,per_page:1})).roles[0]??null}return{entityHooks:{resourceServers:c,roles:l},tenantHooks:{async afterCreate(e,t){let n=[u?.afterCreate,f?.afterCreate??d?.afterCreate],r=[];for(let i of n)if(i)try{await i(e,t)}catch(e){r.push(e instanceof Error?e:Error(String(e)))}if(r.length===1)throw r[0];if(r.length>1)throw AggregateError(r,r.map(e=>e.message).join(`; `))}}}}var ee=n.z.object({sub:n.z.string(),tenant_id:n.z.string().optional(),org_id:n.z.string().optional(),scope:n.z.string().optional(),permissions:n.z.array(n.z.string()).optional()}).passthrough();function te(e){let t=ee.safeParse(e);return t.success?t.data:void 0}function ne(e){let t=e.permissions??[],n=e.scope?e.scope.split(` `).filter(Boolean):[],r=new Set([...t,...n]);return r.has(`delete:tenants`)||r.has(`admin:organizations`)}function j(e,i){let a=new n.OpenAPIHono;return a.openapi((0,n.createRoute)({tags:[`tenants`],method:`get`,path:`/`,request:{query:t.auth0QuerySchema},security:[{Bearer:[]}],responses:{200:{content:{"application/json":{schema:n.z.object({tenants:n.z.array(t.tenantSchema),start:n.z.number().optional(),limit:n.z.number().optional(),length:n.z.number().optional()})}},description:`List of tenants`}}}),async n=>{let{page:i,per_page:a,include_totals:o,q:s}=n.req.valid(`query`),c=n.var.user,l=c?.permissions||[];if(!(c?.org_id??n.var.organization_id)&&l.includes(`admin:organizations`)){let e=await n.env.data.tenants.list({page:i,per_page:a,include_totals:o,q:s});return o?n.json({tenants:e.tenants,start:e.totals?.start??0,limit:e.totals?.limit??a,length:e.tenants.length}):n.json({tenants:e.tenants})}let u=e.accessControl?.controlPlaneTenantId??n.env.data.multiTenancyConfig?.controlPlaneTenantId;if(u&&!c?.sub)throw new r.HTTPException(403,{message:`Access denied: token has no subject`});if(u&&c?.sub){let e=(await(0,t.fetchAll)(e=>n.env.data.userOrganizations.listUserOrganizations(u,c.sub,e),`organizations`)).map(e=>e.name);if(e.length===0)return o?n.json({tenants:[],start:0,limit:a??50,length:0}):n.json({tenants:[]});let r=e.length,l=i??0,d=a??50,f=l*d,p=e.slice(f,f+d);if(p.length===0)return o?n.json({tenants:[],start:f,limit:d,length:r}):n.json({tenants:[]});let m=p.map(e=>`id:${e}`).join(` OR `),h=s?`(${m}) AND (${s})`:m,g=await n.env.data.tenants.list({q:h,per_page:d,include_totals:!1});return o?n.json({tenants:g.tenants,start:f,limit:d,length:r}):n.json({tenants:g.tenants})}let d=await n.env.data.tenants.list({page:i,per_page:a,include_totals:o,q:s});return o?n.json({tenants:d.tenants,start:d.totals?.start??0,limit:d.totals?.limit??a,length:d.tenants.length}):n.json({tenants:d.tenants})}),a.openapi((0,n.createRoute)({tags:[`tenants`],method:`post`,path:`/`,request:{body:{content:{"application/json":{schema:t.tenantInsertSchema}}}},security:[{Bearer:[]}],responses:{201:{content:{"application/json":{schema:t.tenantSchema}},description:`Tenant created`},400:{description:`Validation error`},409:{description:`Tenant with this ID already exists`}}}),async e=>{if(!e.var.user?.sub)throw new r.HTTPException(401,{message:`Authentication required to create tenants`});let t=e.req.valid(`json`),n={adapters:e.env.data,ctx:e};i.tenants?.beforeCreate&&(t=await i.tenants.beforeCreate(n,t));let a=await e.env.data.tenants.create(t);return i.tenants?.afterCreate&&await i.tenants.afterCreate(n,a),e.json(a,201)}),a.openapi((0,n.createRoute)({tags:[`tenants`],method:`delete`,path:`/{id}`,request:{params:n.z.object({id:n.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 n=>{let{id:a}=n.req.valid(`param`),o=e.accessControl?.controlPlaneTenantId??n.env.data.multiTenancyConfig?.controlPlaneTenantId;if(o){let e=te(n.var.user);if(!e?.sub)throw new r.HTTPException(401,{message:`Authentication required`});if(a===o)throw new r.HTTPException(403,{message:`Cannot delete the control plane`});let i=n.var.org_name,s=a.toLowerCase(),c=!!i&&i.toLowerCase()===s;if(!c){let t=!!(e.org_id??n.var.organization_id??i),r=!e.tenant_id||e.tenant_id===o;!t&&r&&ne(e)&&(c=!0)}if(c||=(await(0,t.fetchAll)(t=>n.env.data.userOrganizations.listUserOrganizations(o,e.sub,t),`organizations`)).some(e=>e.name?.toLowerCase()===s),!c)throw new r.HTTPException(403,{message:`Access denied to this tenant`})}if(!await n.env.data.tenants.get(a))throw new r.HTTPException(404,{message:`Tenant not found`});let s={adapters:n.env.data,ctx:n};return i.tenants?.beforeDelete&&await i.tenants.beforeDelete(s,a),await n.env.data.tenants.remove(a),i.tenants?.afterDelete&&await i.tenants.afterDelete(s,a),n.body(null,204)}),a.openapi((0,n.createRoute)({tags:[`tenants`,`settings`],method:`get`,path:`/settings`,request:{headers:n.z.object({"tenant-id":n.z.string().optional()})},security:[{Bearer:[`read:tenants`]}],responses:{200:{content:{"application/json":{schema:t.tenantSchema}},description:`Current tenant settings`}}}),async e=>{let t=await e.env.data.tenants.get(e.var.tenant_id);if(!t)throw new r.HTTPException(404,{message:`Tenant not found`});return e.json(t)}),a.openapi((0,n.createRoute)({tags:[`tenants`,`settings`],method:`patch`,path:`/settings`,request:{headers:n.z.object({"tenant-id":n.z.string().optional()}),body:{content:{"application/json":{schema:n.z.object(t.tenantInsertSchema.shape).partial()}}}},security:[{Bearer:[`update:tenants`]}],responses:{200:{content:{"application/json":{schema:t.tenantSchema}},description:`Updated tenant settings`}}}),async e=>{let{id:n,...i}=e.req.valid(`json`),a=await e.env.data.tenants.get(e.var.tenant_id);if(!a)throw new r.HTTPException(404,{message:`Tenant not found`});if(`default_client_id`in i){let n=i.default_client_id;if(typeof n==`string`&&n.length>0){let i=await e.env.data.clients.get(e.var.tenant_id,n);if(!i)throw new r.HTTPException(400,{message:`Client with id '${n}' not found`});if(!(0,t.isInteractiveClient)(i))throw new r.HTTPException(400,{message:`Client '${n}' is not an interactive client and cannot be used as the default client`})}}let o=(0,t.deepMergePatch)(a,i);await e.env.data.tenants.update(e.var.tenant_id,o);let s=await e.env.data.tenants.get(e.var.tenant_id);if(!s)throw new r.HTTPException(500,{message:`Failed to retrieve updated tenant`});return e.json(s)}),a}function re(e){for(let{pattern:t,type:n}of[{pattern:/\/api\/v2\/resource-servers\/([^/]+)$/,type:`resource_server`},{pattern:/\/api\/v2\/roles\/([^/]+)$/,type:`role`},{pattern:/\/api\/v2\/connections\/([^/]+)$/,type:`connection`}]){let r=e.match(t);if(r&&r[1])return{type:n,id:r[1]}}return null}async function ie(e,t,n){try{switch(n.type){case`resource_server`:return(await e.resourceServers.get(t,n.id))?.is_system===!0;case`role`:return(await e.roles.get(t,n.id))?.is_system===!0;case`connection`:return(await e.connections.get(t,n.id))?.is_system===!0;default:return!1}}catch{return!1}}function ae(e){return{resource_server:`resource server`,role:`role`,connection:`connection`}[e]}function M(){return async(e,t)=>{if(![`PATCH`,`PUT`,`DELETE`].includes(e.req.method))return t();let n=re(e.req.path);if(!n)return t();let i=e.var.tenant_id||e.req.header(`x-tenant-id`)||e.req.header(`tenant-id`);if(!i)return t();if(await ie(e.env.data,i,n))throw new r.HTTPException(403,{message:`This ${ae(n.type)} is a system resource and cannot be modified. Make changes in the control plane instead.`});return t()}}function N(e,n){let r=n.find(t=>t.strategy===e.strategy);if(!r?.options)return e;let i=t.connectionSchema.passthrough().parse({...r,...e});return i.options=t.connectionOptionsSchema.passthrough().parse({...r.options||{},...e.options}),i}function P(e,t){let n=[...t||[],...e||[]];return[...new Set(n)]}function oe(e,t){if(!t?.length)return e||[];if(!e?.length)return t;let n=new Map;for(let e of t)n.set(e.value,e);for(let t of e)n.set(t.value,t);return Array.from(n.values())}function F(e,t){return t?{...e,scopes:oe(e.scopes,t.scopes)}:e}function se(e,t){return t?{...e,callbacks:P(e.callbacks,t.callbacks),web_origins:P(e.web_origins,t.web_origins),allowed_logout_urls:P(e.allowed_logout_urls,t.allowed_logout_urls),allowed_origins:P(e.allowed_origins,t.allowed_origins)}:e}function I(e){let{controlPlaneTenantId:t,controlPlaneClientId:n,resolveControlPlane:r}=e;if(r)return async e=>r({tenant_id:e});if(!t)return async()=>void 0;let i={tenantId:t,clientId:n};return async()=>i}function ce(e,t){return{...e.resourceServers,get:async(n,r)=>{let i=await e.resourceServers.get(n,r);if(!i)return i;let a=await t(n);return!a||n===a.tenantId||!i.is_system?i:F(i,await e.resourceServers.get(a.tenantId,r))},list:async(n,r)=>{let i=await e.resourceServers.list(n,r),a=await t(n);if(!a||n===a.tenantId)return i;let o=a.tenantId,s=i.resource_servers.filter(e=>!!(e.is_system&&e.id)).map(e=>e.id);if(s.length===0)return i;let c=new Map;await Promise.all(s.map(async t=>{let n=await e.resourceServers.get(o,t);n&&c.set(t,n)}));let l=i.resource_servers.map(e=>e.is_system&&e.id?F(e,c.get(e.id)??null):e);return{...i,resource_servers:l}}}}function le(e,t){let n=I({controlPlaneTenantId:t.controlPlaneTenantId,resolveControlPlane:t.resolveControlPlane});return{...e,resourceServers:ce(e,n)}}function L(e,t){let{controlPlaneTenantId:n,controlPlaneClientId:r,resolveControlPlane:i}=t,a=I({controlPlaneTenantId:n,controlPlaneClientId:r,resolveControlPlane:i});return{...e,multiTenancyConfig:{controlPlaneTenantId:n,controlPlaneClientId:r,resolveControlPlane:i},connections:{...e.connections,get:async(t,n)=>{let r=await e.connections.get(t,n);if(!r)return r;let i=await a(t);return!i||t===i.tenantId?r:N(r,(await e.connections.list(i.tenantId)).connections||[])},list:async(t,n)=>{let r=await e.connections.list(t,n),i=await a(t);if(!i||t===i.tenantId)return r;let o=await e.connections.list(i.tenantId),s=r.connections.map(e=>N(e,o.connections||[]));return{...r,connections:s}}},clientConnections:{...e.clientConnections,listByClient:async(t,n)=>{let r=await e.clientConnections.listByClient(t,n);r.length===0&&(r=(await e.connections.list(t)).connections||[]);let i=await a(t);if(!i||t===i.tenantId)return r;let o=await e.connections.list(i.tenantId);return r.map(e=>N(e,o.connections||[]))}},emailProviders:{...e.emailProviders,get:async t=>{let n=await e.emailProviders.get(t);if(n)return n;let r=await a(t);return!r||t===r.tenantId?null:e.emailProviders.get(r.tenantId)}},resourceServers:ce(e,a),hooks:ue(e,a)}}function R(e){if(!e||typeof e!=`object`)return!1;let t=e.metadata;return!t||typeof t!=`object`?!1:t.inheritable===!0}function ue(e,t){return{...e.hooks,list:async(n,r)=>{let i=await e.hooks.list(n,r),a=await t(n);if(!a||n===a.tenantId)return i;let o=((await e.hooks.list(a.tenantId,r)).hooks||[]).filter(R);if(o.length===0)return i;let s=new Set((i.hooks||[]).map(e=>e.hook_id)),c=o.filter(e=>!s.has(e.hook_id));return{...i,hooks:[...i.hooks||[],...c],length:typeof i.length==`number`?i.length+c.length:i.length}},get:async(n,r)=>{let i=await e.hooks.get(n,r);if(i)return i;let a=await t(n);if(!a||n===a.tenantId)return i;let o=await e.hooks.get(a.tenantId,r);return o&&R(o)?o:null}}}function z(e,t){return L(e,t)}function B(e){return async(t,n)=>{let r=t.var.user;return r?.tenant_id===e&&r.org_name&&t.set(`tenant_id`,r.org_name),n()}}function V(e){return async(n,i)=>{if(!e.accessControl)return i();let{controlPlaneTenantId:o}=e.accessControl,s=n.var.org_name,c=n.var.organization_id,l=s||c,u=n.var.tenant_id,d=n.var.user,f=(d?.aud?Array.isArray(d.aud)?d.aud:[d.aud]:[]).includes(t.MANAGEMENT_API_AUDIENCE);if(!u&&l&&f&&(n.set(`tenant_id`,l),u=l),!u)throw new r.HTTPException(400,{message:`Tenant ID not found in request`});if(!a(c,u,o,s))throw new r.HTTPException(403,{message:`Access denied to tenant ${u}`});return i()}}function H(e){return async(t,n)=>{if(!e.subdomainRouting)return n();let{baseDomain:i,reservedSubdomains:a=[],resolveSubdomain:o}=e.subdomainRouting,s=t.req.header(`x-forwarded-host`)||t.req.header(`host`)||``,c=null;if(s.endsWith(i)){let e=s.slice(0,-(i.length+1));e&&!e.includes(`.`)&&(c=e)}if(c&&a.includes(c)&&(c=null),!c)return e.accessControl&&t.set(`tenant_id`,e.accessControl.controlPlaneTenantId),n();let l=null;if(o)l=await o(c);else if(e.subdomainRouting.useOrganizations!==!1&&e.accessControl)try{let n=await t.env.data.organizations.get(e.accessControl.controlPlaneTenantId,c);n&&(l=n.id)}catch{}if(!l)throw new r.HTTPException(404,{message:`Tenant not found for subdomain: ${c}`});return t.set(`tenant_id`,l),n()}}function U(e){return async(t,n)=>{if(!e.databaseIsolation)return n();let i=t.var.tenant_id;if(!i)throw new r.HTTPException(400,{message:`Tenant ID not found in request`});try{let n=await e.databaseIsolation.getAdapters(i);t.env.data=n}catch(e){throw console.error(`Failed to resolve database for tenant ${i}:`,e),new r.HTTPException(500,{message:`Failed to resolve tenant database`})}return n()}}function W(e){let t=H(e),n=V(e),r=U(e);return async(e,i)=>(await t(e,async()=>{}),await n(e,async()=>{}),await r(e,async()=>{}),i())}function de(e){let{dataAdapter:n,controlPlane:r,controlPlane:{tenantId:i=`control_plane`,clientId:a}={},resolveControlPlane:o,sync:s={resourceServers:!0,roles:!0},defaultPermissions:c=[`tenant:admin`],requireOrganizationMatch:l=!1,managementApiExtensions:u=[],entityHooks:d,getChildTenantIds:f,getAdapters:p,...m}=e;if(o&&!r)throw Error("initMultiTenant: `resolveControlPlane` requires `controlPlane` to be set. The static `controlPlane.tenantId` is used for access control, sync direction, and tenant management routing; the resolver only overrides per-tenant runtime inheritance lookups on top of it.");let g=n,v=n;r&&(g=z(n,{controlPlaneTenantId:i,controlPlaneClientId:a,resolveControlPlane:o}),v={...le(n,{controlPlaneTenantId:i,resolveControlPlane:o}),multiTenancyConfig:{controlPlaneTenantId:i,controlPlaneClientId:a,resolveControlPlane:o}});let y=m.tenantOperationExecutor;if(!y&&n.tenantOperations&&n.tenantOperationEvents&&m.tenantUpgrade){let e={tenantOperations:n.tenantOperations,tenantOperationEvents:n.tenantOperationEvents},t=m.tenantUpgrade,r=h({stores:e,definitions:{upgrade:e=>[{name:`upgrade`,async run(){if(!e.tenant_id)throw Error(`upgrade operations require a tenant_id`);await t(e.tenant_id)}}]}});y={engine:r.engine,enqueue:t=>_(e,r,{...t,tenant_id:t.tenant_id})}}let b=s!==!1,S=b?{resourceServers:s.resourceServers??!0,roles:s.roles??!0}:{resourceServers:!1,roles:!1},{entityHooks:C,tenantHooks:w}=A({controlPlaneTenantId:i,getChildTenantIds:f??(async()=>(await(0,t.fetchAll)(e=>g.tenants.list(e),`tenants`,{cursorField:`id`,pageSize:100})).filter(e=>e.id!==i).map(e=>e.id)),getAdapters:p??(async()=>g),getControlPlaneAdapters:async()=>g,sync:S}),T={resourceServers:[C.resourceServers,...d?.resourceServers??[]],roles:[C.roles,...d?.roles??[]],connections:d?.connections??[],tenants:d?.tenants??[],rolePermissions:d?.rolePermissions??[]},E=x({accessControl:{controlPlaneTenantId:i,requireOrganizationMatch:l,defaultPermissions:c}}),D=j({accessControl:{controlPlaneTenantId:i,requireOrganizationMatch:l,defaultPermissions:c}},{tenants:{async beforeCreate(e,t){return E.beforeCreate&&(t=await E.beforeCreate(e,t)),w.beforeCreate&&(t=await w.beforeCreate(e,t)),t},async afterCreate(e,t){await E.afterCreate?.(e,t),await w.afterCreate?.(e,t)},async beforeDelete(e,t){await E.beforeDelete?.(e,t),await w.beforeDelete?.(e,t)}}}),{app:O}=(0,t.init)({dataAdapter:g,managementDataAdapter:v,...m,tenantOperationExecutor:y,entityHooks:T,managementApiExtensions:[...u,{path:`/tenants`,router:D}]});return O.use(`/api/v2/*`,B(i)),b&&O.use(`/api/v2/*`,M()),{app:O,controlPlaneTenantId:i}}function G(e={}){return{connections:e.connections??!0,resourceServers:e.resourceServers??!0,hooks:e.hooks??!0,emailProvider:e.emailProvider??!0,branding:e.branding??!0,promptSettings:e.promptSettings??!0}}function K(){return{upserted:0,errors:[]}}function q(e){return{tenantId:e,connections:K(),resourceServers:K(),hooks:K(),emailProvider:K(),branding:K(),promptSettings:K()}}function J(e){let t=e.metadata;return!!(t&&t.inheritable===!0)}async function Y(e,t,n,r){try{await r()}catch(r){let i=`${t}: ${r instanceof Error?r.message:String(r)}`;if(!n)throw Error(i,{cause:r});e.errors.push(i)}}async function X(e,n,r){return{connections:r.connections?await(0,t.fetchAll)(t=>e.connections.list(n,t),`connections`,{cursorField:`id`,pageSize:100}):[],resourceServers:r.resourceServers?await(0,t.fetchAll)(t=>e.resourceServers.list(n,t),`resource_servers`,{cursorField:`id`,pageSize:100}):[],hooks:r.hooks?await(0,t.fetchAll)(t=>e.hooks.list(n,t),`hooks`,{cursorField:`hook_id`,pageSize:100}):[],emailProvider:r.emailProvider?await e.emailProviders.get(n)??null:null,branding:r.branding?await e.branding.get(n)??null:null,promptSettings:r.promptSettings?await e.promptSettings.get(n)??null:null}}async function Z(e,n,r,i,a,o){if(i.connections)for(let i of e.connections){let e=i.id;e&&await Y(o.connections,`connection ${e}`,a,async()=>{let a=t.connectionInsertSchema.parse(i);await n.connections.get(r,e)?await n.connections.update(r,e,a):await n.connections.create(r,a),o.connections.upserted+=1})}if(i.resourceServers)for(let i of e.resourceServers)!i.is_system||!i.id||await Y(o.resourceServers,`resource_server ${i.id}`,a,async()=>{let e=t.resourceServerInsertSchema.parse(i);await n.resourceServers.get(r,i.id)?await n.resourceServers.update(r,i.id,e):await n.resourceServers.create(r,e),o.resourceServers.upserted+=1});if(i.hooks)for(let i of e.hooks)!J(i)||!i.hook_id||await Y(o.hooks,`hook ${i.hook_id}`,a,async()=>{let e=t.hookInsertSchema.parse(i);await n.hooks.get(r,i.hook_id)?await n.hooks.update(r,i.hook_id,e):await n.hooks.create(r,e),o.hooks.upserted+=1});i.emailProvider&&e.emailProvider&&await Y(o.emailProvider,`email_provider`,a,async()=>{let t=e.emailProvider;await n.emailProviders.get(r)?await n.emailProviders.update(r,t):await n.emailProviders.create(r,t),o.emailProvider.upserted+=1}),i.branding&&e.branding&&await Y(o.branding,`branding`,a,async()=>{await n.branding.set(r,e.branding),o.branding.upserted+=1}),i.promptSettings&&e.promptSettings&&await Y(o.promptSettings,`prompt_settings`,a,async()=>{await n.promptSettings.set(r,e.promptSettings),o.promptSettings.upserted+=1})}async function Q(e,t){let{controlPlaneTenantId:n,getControlPlaneAdapters:r,getAdapters:i,entities:a,continueOnError:o=!1}=e,s=G(a),c=await X(await r(),n,s),l=await i(t),u=q(t);return await Z(c,l,n,s,o,u),u}function fe(e){let{pkcs7:t,tenant_id:n,...r}=e;return r}async function pe(e,n,r={},i){let a=G(r),o=r.signingKeys??!0,s=r.tenants??!0,c=await X(e,n,a),l=o?(await(0,t.listControlPlaneKeys)(e.keys)).map(fe):[],u=s?await me(e,n,i):[];return{connections:c.connections,resourceServers:c.resourceServers.filter(e=>e.is_system),hooks:c.hooks.filter(J),emailProvider:c.emailProvider,branding:c.branding,promptSettings:c.promptSettings,signingKeys:l,tenants:u}}async function me(e,t,n){let r=n&&n!==t?[t,n]:[t],i=[];for(let t of r){let n=await e.tenants.get(t);i.push({id:t,friendly_name:n?.friendly_name||t})}return i}async function he(e,n,r){let i=K();if(e.length===0)return i;let a=await(0,t.listControlPlaneKeys)(n.keys),o=new Set(a.map(e=>e.kid));for(let t of e)await Y(i,`signing_key ${t.kid}`,r,async()=>{let e=fe(t);o.has(e.kid)||(await n.keys.create(e),o.add(e.kid),i.upserted+=1)});return i}async function ge(e,t,n){let r=K();for(let i of e)await Y(r,`tenant ${i.id}`,n,async()=>{await t.tenants.get(i.id)||(await t.tenants.create({id:i.id,friendly_name:i.friendly_name}),r.upserted+=1)});return r}async function _e(e,n,r,i={}){let a=i.continueOnError??!1,o=G(i.entities),s=i.entities?.signingKeys??!0,c=i.entities?.tenants??!0,l={connections:e.connections,resourceServers:e.resourceServers,hooks:e.hooks,emailProvider:e.emailProvider?t.emailProviderSchema.parse(e.emailProvider):null,branding:e.branding?t.brandingSchema.parse(e.branding):null,promptSettings:e.promptSettings?t.promptSettingSchema.parse(e.promptSettings):null},u=c?await ge(e.tenants??[],n,a):K(),d=q(r);await Z(l,n,r,o,a,d);let f=s?await he(e.signingKeys,n,a):K();return{...d,signingKeys:f,tenants:u}}function ve(e){return{syncDefaults:t=>Q(e,t),syncDefaultsToTenants:async t=>{let n=[];for(let r of t)n.push(await Q(e,r));return n}}}function ye(e){let t=$(e);return{name:`multi-tenancy`,middleware:W(e),hooks:t,routes:[{path:`/management`,handler:j(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 $(e){let t=e.accessControl?i(e.accessControl):{},n=e.databaseIsolation?o(e.databaseIsolation):{},r=x(e);return{...t,...n,tenants:r}}function be(t){let n=new e.Hono,r=$(t);return n.route(`/tenants`,j(t,r)),n}function xe(e){return{hooks:$(e),middleware:W(e),app:be(e),config:e,wrapAdapters:(t,n)=>z(t,{controlPlaneTenantId:e.accessControl?.controlPlaneTenantId,controlPlaneClientId:n?.controlPlaneClientId})}}exports.applyControlPlaneDefaultsPayload=_e,exports.buildControlPlaneDefaultsPayload=pe,exports.buildEngineInstanceId=l,exports.createAccessControlHooks=i,exports.createAccessControlMiddleware=V,exports.createControlPlaneTenantMiddleware=B,exports.createDatabaseHooks=o,exports.createDatabaseMiddleware=U,exports.createDirectRolloutAdapter=ve,exports.createInlineExecutor=h,exports.createMultiTenancy=be,exports.createMultiTenancyHooks=$,exports.createMultiTenancyMiddleware=W,exports.createMultiTenancyPlugin=ye,exports.createOperationRecorder=f,exports.createProtectSyncedMiddleware=M,exports.createProvisioningHooks=x,exports.createRuntimeFallbackAdapter=L,exports.createSubdomainMiddleware=H,exports.createSyncHooks=A,exports.createTenantsOpenAPIRouter=j,exports.enqueueTenantOperation=_,exports.errorToMessage=d,exports.initMultiTenant=de,exports.inlineStepRunner=m,exports.isTerminalStatus=p,exports.mergeClientWithFallback=se,exports.projectControlPlaneDefaults=Q,exports.runRecordedTenantOperation=y,exports.setupMultiTenancy=xe,exports.validateTenantAccess=a,exports.withRuntimeFallback=z,exports.withSystemResourceServerInheritance=le;
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});let e=require("hono"),t=require("authhero"),n=require("@hono/zod-openapi"),r=require("hono/http-exception");function i(e){let{controlPlaneTenantId:t,requireOrganizationMatch:n=!0}=e;return{async onTenantAccessValidation(e,r){if(r===t)return!0;if(n){let t=e.var.org_name,n=e.var.organization_id,i=t||n;return i?i.toLowerCase()===r.toLowerCase():!1}return!0}}}function a(e,t,n,r){if(t===n)return!0;let i=r||e;return i?i.toLowerCase()===t.toLowerCase():!1}function o(e){return{async resolveDataAdapters(t){try{return await e.getAdapters(t)}catch(e){console.error(`Failed to resolve data adapters for tenant ${t}:`,e);return}}}}var s=64;function c(e){return e.replace(/[^a-zA-Z0-9_-]/g,`-`)}function l(e){let t=c(e.id),n=Math.max(0,s-(5+t.length)),r=c(e.kind).slice(0,n),i=3+r.length+2+t.length,a=Math.max(0,s-i);return`op-${r}-${c(e.tenant_id??`fleet`).slice(0,a)}-${t}`.slice(0,s)}var u=2048;function d(e){let t;if(e instanceof Error)t=e.message;else try{t=String(e??`unknown error`)}catch{t=Object.prototype.toString.call(e)}return t.slice(0,u)}function f(e){let{tenantOperations:t,tenantOperationEvents:n}=e;return{async markRunning(e,n){await t.update(e,{status:`running`,...n===void 0?{}:{current_step:n}})},async setCurrentStep(e,n){await t.update(e,{current_step:n})},async appendEvent(e,t){await n.create({operation_id:e,step:t.step,outcome:t.outcome,detail:t.detail,attempt:t.attempt??1})},async markSucceeded(e){await t.update(e,{status:`succeeded`,error:null,finished_at:new Date().toISOString()})},async markFailed(e,n){await t.update(e,{status:`failed`,error:d(n),finished_at:new Date().toISOString()})}}}function p(e){return e===`succeeded`||e===`failed`||e===`cancelled`}var m={async do(e,t,n){let r=typeof t==`function`?t:n;if(!r)throw Error(`StepRunner.do called without a function`);return r()}};function h(e){let t=f(e.stores);return{engine:`inline`,async start(n){let r=e.definitions[n.kind];if(!r){let e=Error(`No inline operation definition for kind "${n.kind}"`);throw await t.markFailed(n.id,e),e}let i=r(n);await t.markRunning(n.id,i[0]?.name);for(let e of i){await t.setCurrentStep(n.id,e.name),await t.appendEvent(n.id,{step:e.name,outcome:`started`});try{let r=await e.run({operation:n,step:m});await t.appendEvent(n.id,{step:e.name,outcome:`succeeded`,detail:r??void 0})}catch(r){throw await t.appendEvent(n.id,{step:e.name,outcome:`failed`,detail:{message:d(r)}}),await t.markFailed(n.id,r),r}}await t.markSucceeded(n.id)}}}async function g(e,t,n){let r=await e.tenantOperations.create({tenant_id:t.tenant_id,rollout_id:t.rollout_id,kind:t.kind,engine:n,initiated_by:t.initiated_by,target_worker_version:t.target_worker_version,target_database_version:t.target_database_version}),i=l(r);try{await e.tenantOperations.update(r.id,{engine_instance_id:i})}catch(t){try{await f(e).markFailed(r.id,t)}catch{}throw t}return{...r,engine_instance_id:i}}async function _(e,t,n){let r=f(e),i=await g(e,n,t.engine);try{await t.start(i)}catch(t){try{let n=await e.tenantOperations.get(i.id);n&&!p(n.status)&&await r.markFailed(i.id,t)}catch(e){console.warn(`Failed to record tenant operation failure:`,e)}throw t}try{return await e.tenantOperations.get(i.id)??i}catch(e){return console.warn(`Failed to re-fetch tenant operation after start:`,e),i}}function v(e){if(e.tenantOperations&&e.tenantOperationEvents)return{tenantOperations:e.tenantOperations,tenantOperationEvents:e.tenantOperationEvents}}async function y(e,t,n){let r=v(e);if(!r){await n(void 0);return}let i=f(r),a=async e=>{try{await e()}catch(e){console.warn(`Failed to record tenant operation progress:`,e)}},o;if(await a(async()=>{let e=await g(r,t,`inline`);o=e.id,await i.markRunning(e.id)}),!o){await n(void 0);return}let s=o,c=!1,l=async(e,t,n)=>{c=!0,await a(async()=>{t===`started`&&await i.setCurrentStep(s,e),await i.appendEvent(s,{step:e,outcome:t,detail:n})})};try{await n(l)}catch(e){throw await a(async()=>{c||await i.appendEvent(s,{step:t.kind,outcome:`failed`,detail:{message:d(e)}}),await i.markFailed(s,e)}),e}await a(async()=>{c||await i.appendEvent(s,{step:t.kind,outcome:`succeeded`}),await i.markSucceeded(s)})}function b(e){return`urn:authhero:tenant:${e.toLowerCase()}`}function x(e){return{async beforeCreate(e,t){return!t.audience&&t.id?{...t,audience:b(t.id)}:t},async afterCreate(n,r){let{accessControl:i,databaseIsolation:a}=e;if(i&&n.ctx&&await S(n,r,i),a?.onProvision){let e=a.onProvision;a.recordProvisionOperations===!1?await e(r.id):await y(n.adapters,{kind:`provision`,tenant_id:r.id,initiated_by:n.ctx?.var.user?.sub},t=>e(r.id,t))}else try{await(0,t.provisionDefaultClients)(n.adapters,r.id,{managementApiIdentifier:t.MANAGEMENT_API_AUDIENCE,managementApiScopes:t.MANAGEMENT_API_SCOPES})}catch(e){throw console.warn(`Failed to provision default clients for tenant ${r.id}:`,e),e}},async beforeDelete(t,n){let{accessControl:r,databaseIsolation:i}=e;if(r)try{let e=(await t.adapters.organizations.list(r.controlPlaneTenantId)).organizations.find(e=>e.name===n);e&&await t.adapters.organizations.remove(r.controlPlaneTenantId,e.id)}catch(e){console.warn(`Failed to remove organization for tenant ${n}:`,e)}if(i?.onDeprovision)try{await i.onDeprovision(n)}catch(e){console.warn(`Failed to deprovision database for tenant ${n}:`,e)}}}}async function S(e,t,n){let{controlPlaneTenantId:r,defaultPermissions:i,defaultRoles:a,issuer:o,adminRoleName:s=`Tenant Admin`,adminRoleDescription:c=`Full access to all tenant management operations`,addCreatorToOrganization:l=!0}=n,u=await e.adapters.organizations.create(r,{name:t.id,display_name:t.friendly_name||t.id}),d;if(o&&(d=await w(e,r,s,c)),l&&e.ctx){let t=e.ctx.var.user;if(t?.sub&&!await C(e,r,t.sub))try{await e.adapters.userOrganizations.create(r,{user_id:t.sub,organization_id:u.id}),d&&await e.adapters.userRoles.create(r,t.sub,d,u.id)}catch(e){console.warn(`Failed to add creator ${t.sub} to organization ${u.id}:`,e)}}a&&a.length>0&&console.log(`Would assign roles ${a.join(`, `)} to organization ${u.id}`),i&&i.length>0&&console.log(`Would grant permissions ${i.join(`, `)} to organization ${u.id}`)}async function C(e,n,r){let i=await e.adapters.userRoles.list(n,r,void 0,``);for(let r of i)if((await e.adapters.rolePermissions.list(n,r.id,{per_page:1e3})).some(e=>e.permission_name===`admin:organizations`&&e.resource_server_identifier===t.MANAGEMENT_API_AUDIENCE))return!0;return!1}async function w(e,n,r,i){let a=(await e.adapters.roles.list(n,{})).roles.find(e=>e.name===r);if(a)return a.id;let o=await e.adapters.roles.create(n,{name:r,description:i}),s=t.MANAGEMENT_API_AUDIENCE,c=t.MANAGEMENT_API_SCOPES.map(e=>({role_id:o.id,resource_server_identifier:s,permission_name:e.value}));return await e.adapters.rolePermissions.assign(n,o.id,c),o.id}function T(e,n,r=()=>!0){let{controlPlaneTenantId:i,getChildTenantIds:a,getAdapters:o}=e,s=new Map;async function c(e,r,i){return(await n(e).list(r,{q:`name:${(0,t.escapeLuceneValue)(i)}`,per_page:1}))[0]??null}async function l(e){let t=await a(),r=n(await o(i));await Promise.all(t.map(async t=>{try{let i=await o(t),a=n(i),s={...r.transform(e),is_system:!0},l=await c(i,t,e.name),u=l?a.getId(l):void 0;if(l&&u){let e=a.preserveOnUpdate?a.preserveOnUpdate(l,s):s;await a.update(t,u,e)}else await a.create(t,s)}catch(n){console.error(`Failed to sync ${r.listKey} "${e.name}" to tenant "${t}":`,n)}}))}async function u(e){let t=await a();await Promise.all(t.map(async t=>{try{let r=await o(t),i=n(r),a=await c(r,t,e),s=a?i.getId(a):void 0;a&&s&&await i.remove(t,s)}catch(n){console.error(`Failed to delete entity "${e}" from tenant "${t}":`,n)}}))}return{afterCreate:async(e,t)=>{e.tenantId===i&&r(t)&&await l(t)},afterUpdate:async(e,t,n)=>{e.tenantId===i&&r(n)&&await l(n)},beforeDelete:async(e,t)=>{if(e.tenantId!==i)return;let a=await n(e.adapters).get(e.tenantId,t);a&&r(a)&&s.set(t,a)},afterDelete:async(e,t)=>{if(e.tenantId!==i)return;let n=s.get(t);n&&(s.delete(t),await u(n.name))}}}function E(e,n,r=()=>!0){let{controlPlaneTenantId:i,getControlPlaneAdapters:a,getAdapters:o}=e;return{async afterCreate(e,s){if(s.id!==i)try{let e=await a(),c=await o(s.id),l=n(e),u=n(c),d=await(0,t.fetchAll)(e=>l.listPaginated(i,e),l.listKey,{cursorField:`id`,pageSize:100});await Promise.all(d.filter(e=>r(e)).map(async e=>{try{let t=l.transform(e);await u.create(s.id,{...t,is_system:!0})}catch(e){console.error(`Failed to sync entity to new tenant "${s.id}":`,e)}}))}catch(e){console.error(`Failed to sync entities to new tenant "${s.id}":`,e)}}}}var D=e=>({list:async(t,n)=>(await e.resourceServers.list(t,n)).resource_servers,listPaginated:(t,n)=>e.resourceServers.list(t,n),get:(t,n)=>e.resourceServers.get(t,n),create:(t,n)=>e.resourceServers.create(t,n),update:(t,n,r)=>e.resourceServers.update(t,n,r),remove:(t,n)=>e.resourceServers.remove(t,n),listKey:`resource_servers`,getId:e=>e.id,transform:e=>({id:e.id,name:e.name,identifier:e.identifier,scopes:e.scopes,signing_alg:e.signing_alg,token_lifetime:e.token_lifetime,token_lifetime_for_web:e.token_lifetime_for_web})}),O=e=>({list:async(t,n)=>(await e.roles.list(t,n)).roles,listPaginated:(t,n)=>e.roles.list(t,n),get:(t,n)=>e.roles.get(t,n),create:(t,n)=>e.roles.create(t,n),update:(t,n,r)=>e.roles.update(t,n,r),remove:(t,n)=>e.roles.remove(t,n),listKey:`roles`,getId:e=>e.id,transform:e=>({id:e.id,name:e.name,description:e.description})});function k(e){return e.metadata?.sync!==!1}function A(e){let{sync:n={},filters:r={}}=e,i=n.resourceServers??!0,a=n.roles??!0,o=e=>k(e)?r.resourceServers?r.resourceServers(e):!0:!1,s=e=>k(e)?r.roles?r.roles(e):!0:!1,c=i?T(e,D,o):void 0,l=a?T(e,O,s):void 0,u=i?E(e,D,o):void 0,d=a?E(e,O,s):void 0,f=a?{async afterCreate(n,i){if(i.id!==e.controlPlaneTenantId){await d?.afterCreate?.(n,i);try{let n=await e.getControlPlaneAdapters(),a=await e.getAdapters(i.id),o=await(0,t.fetchAll)(t=>n.roles.list(e.controlPlaneTenantId,t),`roles`,{cursorField:`id`,pageSize:100}),s=new Map;for(let e of o.filter(e=>r.roles?.(e)??!0)){let t=await p(a,i.id,e.name);t&&s.set(e.name,t.id)}for(let t of o.filter(e=>r.roles?.(e)??!0)){let r=s.get(t.name);if(r)try{let o=await n.rolePermissions.list(e.controlPlaneTenantId,t.id,{});o.length>0&&await a.rolePermissions.assign(i.id,r,o.map(e=>({role_id:r,resource_server_identifier:e.resource_server_identifier,permission_name:e.permission_name})))}catch(e){console.error(`Failed to sync permissions for role "${t.name}" to tenant "${i.id}":`,e)}}}catch(e){console.error(`Failed to sync role permissions to tenant "${i.id}":`,e)}}}}:void 0;async function p(e,n,r){return(await e.roles.list(n,{q:`name:${(0,t.escapeLuceneValue)(r)}`,per_page:1})).roles[0]??null}return{entityHooks:{resourceServers:c,roles:l},tenantHooks:{async afterCreate(e,t){let n=[u?.afterCreate,f?.afterCreate??d?.afterCreate],r=[];for(let i of n)if(i)try{await i(e,t)}catch(e){r.push(e instanceof Error?e:Error(String(e)))}if(r.length===1)throw r[0];if(r.length>1)throw AggregateError(r,r.map(e=>e.message).join(`; `))}}}}function j(e){return e.var.data??e.env.data}var ee=n.z.object({sub:n.z.string(),tenant_id:n.z.string().optional(),org_id:n.z.string().optional(),scope:n.z.string().optional(),permissions:n.z.array(n.z.string()).optional()}).passthrough();function te(e){let t=ee.safeParse(e);return t.success?t.data:void 0}function ne(e){let t=e.permissions??[],n=e.scope?e.scope.split(` `).filter(Boolean):[],r=new Set([...t,...n]);return r.has(`delete:tenants`)||r.has(`admin:organizations`)}function M(e,i){let a=new n.OpenAPIHono;return a.openapi((0,n.createRoute)({tags:[`tenants`],method:`get`,path:`/`,request:{query:t.auth0QuerySchema},security:[{Bearer:[]}],responses:{200:{content:{"application/json":{schema:n.z.object({tenants:n.z.array(t.tenantSchema),start:n.z.number().optional(),limit:n.z.number().optional(),length:n.z.number().optional()})}},description:`List of tenants`}}}),async n=>{let{page:i,per_page:a,include_totals:o,q:s}=n.req.valid(`query`),c=n.var.user,l=c?.permissions||[];if(!(c?.org_id??n.var.organization_id)&&l.includes(`admin:organizations`)){let e=await j(n).tenants.list({page:i,per_page:a,include_totals:o,q:s});return o?n.json({tenants:e.tenants,start:e.totals?.start??0,limit:e.totals?.limit??a,length:e.tenants.length}):n.json({tenants:e.tenants})}let u=e.accessControl?.controlPlaneTenantId??j(n).multiTenancyConfig?.controlPlaneTenantId;if(u&&!c?.sub)throw new r.HTTPException(403,{message:`Access denied: token has no subject`});if(u&&c?.sub){let e=(await(0,t.fetchAll)(e=>j(n).userOrganizations.listUserOrganizations(u,c.sub,e),`organizations`)).map(e=>e.name);if(e.length===0)return o?n.json({tenants:[],start:0,limit:a??50,length:0}):n.json({tenants:[]});let r=e.length,l=i??0,d=a??50,f=l*d,p=e.slice(f,f+d);if(p.length===0)return o?n.json({tenants:[],start:f,limit:d,length:r}):n.json({tenants:[]});let m=p.map(e=>`id:${e}`).join(` OR `),h=s?`(${m}) AND (${s})`:m,g=await j(n).tenants.list({q:h,per_page:d,include_totals:!1});return o?n.json({tenants:g.tenants,start:f,limit:d,length:r}):n.json({tenants:g.tenants})}let d=await j(n).tenants.list({page:i,per_page:a,include_totals:o,q:s});return o?n.json({tenants:d.tenants,start:d.totals?.start??0,limit:d.totals?.limit??a,length:d.tenants.length}):n.json({tenants:d.tenants})}),a.openapi((0,n.createRoute)({tags:[`tenants`],method:`post`,path:`/`,request:{body:{content:{"application/json":{schema:t.tenantInsertSchema}}}},security:[{Bearer:[]}],responses:{201:{content:{"application/json":{schema:t.tenantSchema}},description:`Tenant created`},400:{description:`Validation error`},409:{description:`Tenant with this ID already exists`}}}),async e=>{if(!e.var.user?.sub)throw new r.HTTPException(401,{message:`Authentication required to create tenants`});let t=e.req.valid(`json`),n={adapters:j(e),ctx:e};i.tenants?.beforeCreate&&(t=await i.tenants.beforeCreate(n,t));let a=await j(e).tenants.create(t);return i.tenants?.afterCreate&&await i.tenants.afterCreate(n,a),e.json(a,201)}),a.openapi((0,n.createRoute)({tags:[`tenants`],method:`delete`,path:`/{id}`,request:{params:n.z.object({id:n.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 n=>{let{id:a}=n.req.valid(`param`),o=e.accessControl?.controlPlaneTenantId??j(n).multiTenancyConfig?.controlPlaneTenantId;if(o){let e=te(n.var.user);if(!e?.sub)throw new r.HTTPException(401,{message:`Authentication required`});if(a===o)throw new r.HTTPException(403,{message:`Cannot delete the control plane`});let i=n.var.org_name,s=a.toLowerCase(),c=!!i&&i.toLowerCase()===s;if(!c){let t=!!(e.org_id??n.var.organization_id??i),r=!e.tenant_id||e.tenant_id===o;!t&&r&&ne(e)&&(c=!0)}if(c||=(await(0,t.fetchAll)(t=>j(n).userOrganizations.listUserOrganizations(o,e.sub,t),`organizations`)).some(e=>e.name?.toLowerCase()===s),!c)throw new r.HTTPException(403,{message:`Access denied to this tenant`})}if(!await j(n).tenants.get(a))throw new r.HTTPException(404,{message:`Tenant not found`});let s={adapters:j(n),ctx:n};return i.tenants?.beforeDelete&&await i.tenants.beforeDelete(s,a),await j(n).tenants.remove(a),i.tenants?.afterDelete&&await i.tenants.afterDelete(s,a),n.body(null,204)}),a.openapi((0,n.createRoute)({tags:[`tenants`,`settings`],method:`get`,path:`/settings`,request:{headers:n.z.object({"tenant-id":n.z.string().optional()})},security:[{Bearer:[`read:tenants`]}],responses:{200:{content:{"application/json":{schema:t.tenantSchema}},description:`Current tenant settings`}}}),async e=>{let t=await j(e).tenants.get(e.var.tenant_id);if(!t)throw new r.HTTPException(404,{message:`Tenant not found`});return e.json(t)}),a.openapi((0,n.createRoute)({tags:[`tenants`,`settings`],method:`patch`,path:`/settings`,request:{headers:n.z.object({"tenant-id":n.z.string().optional()}),body:{content:{"application/json":{schema:n.z.object(t.tenantInsertSchema.shape).partial()}}}},security:[{Bearer:[`update:tenants`]}],responses:{200:{content:{"application/json":{schema:t.tenantSchema}},description:`Updated tenant settings`}}}),async e=>{let{id:n,...i}=e.req.valid(`json`),a=await j(e).tenants.get(e.var.tenant_id);if(!a)throw new r.HTTPException(404,{message:`Tenant not found`});if(`default_client_id`in i){let n=i.default_client_id;if(typeof n==`string`&&n.length>0){let i=await j(e).clients.get(e.var.tenant_id,n);if(!i)throw new r.HTTPException(400,{message:`Client with id '${n}' not found`});if(!(0,t.isInteractiveClient)(i))throw new r.HTTPException(400,{message:`Client '${n}' is not an interactive client and cannot be used as the default client`})}}let o=(0,t.deepMergePatch)(a,i);await j(e).tenants.update(e.var.tenant_id,o);let s=await j(e).tenants.get(e.var.tenant_id);if(!s)throw new r.HTTPException(500,{message:`Failed to retrieve updated tenant`});return e.json(s)}),a}function re(e){for(let{pattern:t,type:n}of[{pattern:/\/api\/v2\/resource-servers\/([^/]+)$/,type:`resource_server`},{pattern:/\/api\/v2\/roles\/([^/]+)$/,type:`role`},{pattern:/\/api\/v2\/connections\/([^/]+)$/,type:`connection`}]){let r=e.match(t);if(r&&r[1])return{type:n,id:r[1]}}return null}async function ie(e,t,n){try{switch(n.type){case`resource_server`:return(await e.resourceServers.get(t,n.id))?.is_system===!0;case`role`:return(await e.roles.get(t,n.id))?.is_system===!0;case`connection`:return(await e.connections.get(t,n.id))?.is_system===!0;default:return!1}}catch{return!1}}function ae(e){return{resource_server:`resource server`,role:`role`,connection:`connection`}[e]}function oe(){return async(e,t)=>{if(![`PATCH`,`PUT`,`DELETE`].includes(e.req.method))return t();let n=re(e.req.path);if(!n)return t();let i=e.var.tenant_id||e.req.header(`x-tenant-id`)||e.req.header(`tenant-id`);if(!i)return t();if(await ie(j(e),i,n))throw new r.HTTPException(403,{message:`This ${ae(n.type)} is a system resource and cannot be modified. Make changes in the control plane instead.`});return t()}}function N(e,n){let r=n.find(t=>t.strategy===e.strategy);if(!r?.options)return e;let i=t.connectionSchema.passthrough().parse({...r,...e});return i.options=t.connectionOptionsSchema.passthrough().parse({...r.options||{},...e.options}),i}function P(e,t){let n=[...t||[],...e||[]];return[...new Set(n)]}function se(e,t){if(!t?.length)return e||[];if(!e?.length)return t;let n=new Map;for(let e of t)n.set(e.value,e);for(let t of e)n.set(t.value,t);return Array.from(n.values())}function F(e,t){return t?{...e,scopes:se(e.scopes,t.scopes)}:e}function ce(e,t){return t?{...e,callbacks:P(e.callbacks,t.callbacks),web_origins:P(e.web_origins,t.web_origins),allowed_logout_urls:P(e.allowed_logout_urls,t.allowed_logout_urls),allowed_origins:P(e.allowed_origins,t.allowed_origins)}:e}function I(e){let{controlPlaneTenantId:t,controlPlaneClientId:n,resolveControlPlane:r}=e;if(r)return async e=>r({tenant_id:e});if(!t)return async()=>void 0;let i={tenantId:t,clientId:n};return async()=>i}function L(e,t){return{...e.resourceServers,get:async(n,r)=>{let i=await e.resourceServers.get(n,r);if(!i)return i;let a=await t(n);return!a||n===a.tenantId||!i.is_system?i:F(i,await e.resourceServers.get(a.tenantId,r))},list:async(n,r)=>{let i=await e.resourceServers.list(n,r),a=await t(n);if(!a||n===a.tenantId)return i;let o=a.tenantId,s=i.resource_servers.filter(e=>!!(e.is_system&&e.id)).map(e=>e.id);if(s.length===0)return i;let c=new Map;await Promise.all(s.map(async t=>{let n=await e.resourceServers.get(o,t);n&&c.set(t,n)}));let l=i.resource_servers.map(e=>e.is_system&&e.id?F(e,c.get(e.id)??null):e);return{...i,resource_servers:l}}}}function R(e,t){let n=I({controlPlaneTenantId:t.controlPlaneTenantId,resolveControlPlane:t.resolveControlPlane});return{...e,resourceServers:L(e,n)}}function z(e,t){let{controlPlaneTenantId:n,controlPlaneClientId:r,resolveControlPlane:i}=t,a=I({controlPlaneTenantId:n,controlPlaneClientId:r,resolveControlPlane:i});return{...e,multiTenancyConfig:{controlPlaneTenantId:n,controlPlaneClientId:r,resolveControlPlane:i},connections:{...e.connections,get:async(t,n)=>{let r=await e.connections.get(t,n);if(!r)return r;let i=await a(t);return!i||t===i.tenantId?r:N(r,(await e.connections.list(i.tenantId)).connections||[])},list:async(t,n)=>{let r=await e.connections.list(t,n),i=await a(t);if(!i||t===i.tenantId)return r;let o=await e.connections.list(i.tenantId),s=r.connections.map(e=>N(e,o.connections||[]));return{...r,connections:s}}},clientConnections:{...e.clientConnections,listByClient:async(t,n)=>{let r=await e.clientConnections.listByClient(t,n);r.length===0&&(r=(await e.connections.list(t)).connections||[]);let i=await a(t);if(!i||t===i.tenantId)return r;let o=await e.connections.list(i.tenantId);return r.map(e=>N(e,o.connections||[]))}},emailProviders:{...e.emailProviders,get:async t=>{let n=await e.emailProviders.get(t);if(n)return n;let r=await a(t);return!r||t===r.tenantId?null:e.emailProviders.get(r.tenantId)}},resourceServers:L(e,a),hooks:le(e,a)}}function B(e){if(!e||typeof e!=`object`)return!1;let t=e.metadata;return!t||typeof t!=`object`?!1:t.inheritable===!0}function le(e,t){return{...e.hooks,list:async(n,r)=>{let i=await e.hooks.list(n,r),a=await t(n);if(!a||n===a.tenantId)return i;let o=((await e.hooks.list(a.tenantId,r)).hooks||[]).filter(B);if(o.length===0)return i;let s=new Set((i.hooks||[]).map(e=>e.hook_id)),c=o.filter(e=>!s.has(e.hook_id));return{...i,hooks:[...i.hooks||[],...c],length:typeof i.length==`number`?i.length+c.length:i.length}},get:async(n,r)=>{let i=await e.hooks.get(n,r);if(i)return i;let a=await t(n);if(!a||n===a.tenantId)return i;let o=await e.hooks.get(a.tenantId,r);return o&&B(o)?o:null}}}function V(e,t){return z(e,t)}function H(e){return async(t,n)=>{let r=t.var.user;return r?.tenant_id===e&&r.org_name&&t.set(`tenant_id`,r.org_name),n()}}function U(e){return async(n,i)=>{if(!e.accessControl)return i();let{controlPlaneTenantId:o}=e.accessControl,s=n.var.org_name,c=n.var.organization_id,l=s||c,u=n.var.tenant_id,d=n.var.user,f=(d?.aud?Array.isArray(d.aud)?d.aud:[d.aud]:[]).includes(t.MANAGEMENT_API_AUDIENCE);if(!u&&l&&f&&(n.set(`tenant_id`,l),u=l),!u)throw new r.HTTPException(400,{message:`Tenant ID not found in request`});if(!a(c,u,o,s))throw new r.HTTPException(403,{message:`Access denied to tenant ${u}`});return i()}}function W(e){return async(t,n)=>{if(!e.subdomainRouting)return n();let{baseDomain:i,reservedSubdomains:a=[],resolveSubdomain:o}=e.subdomainRouting,s=t.req.header(`x-forwarded-host`)||t.req.header(`host`)||``,c=null;if(s.endsWith(i)){let e=s.slice(0,-(i.length+1));e&&!e.includes(`.`)&&(c=e)}if(c&&a.includes(c)&&(c=null),!c)return e.accessControl&&t.set(`tenant_id`,e.accessControl.controlPlaneTenantId),n();let l=null;if(o)l=await o(c);else if(e.subdomainRouting.useOrganizations!==!1&&e.accessControl)try{let n=await j(t).organizations.get(e.accessControl.controlPlaneTenantId,c);n&&(l=n.id)}catch{}if(!l)throw new r.HTTPException(404,{message:`Tenant not found for subdomain: ${c}`});return t.set(`tenant_id`,l),n()}}function G(e){return async(t,n)=>{if(!e.databaseIsolation)return n();let i=t.var.tenant_id;if(!i)throw new r.HTTPException(400,{message:`Tenant ID not found in request`});try{let n=await e.databaseIsolation.getAdapters(i);t.set(`baseData`,n),t.env={...t.env,data:n}}catch(e){throw console.error(`Failed to resolve database for tenant ${i}:`,e),new r.HTTPException(500,{message:`Failed to resolve tenant database`})}return n()}}function K(e){let t=W(e),n=U(e),r=G(e);return async(e,i)=>(await t(e,async()=>{}),await n(e,async()=>{}),await r(e,async()=>{}),i())}function ue(e){let{dataAdapter:n,controlPlane:r,controlPlane:{tenantId:i=`control_plane`,clientId:a}={},resolveControlPlane:o,sync:s={resourceServers:!0,roles:!0},defaultPermissions:c=[`tenant:admin`],requireOrganizationMatch:l=!1,managementApiExtensions:u=[],entityHooks:d,getChildTenantIds:f,getAdapters:p,...m}=e;if(o&&!r)throw Error("initMultiTenant: `resolveControlPlane` requires `controlPlane` to be set. The static `controlPlane.tenantId` is used for access control, sync direction, and tenant management routing; the resolver only overrides per-tenant runtime inheritance lookups on top of it.");let g=n,v=n;r&&(g=V(n,{controlPlaneTenantId:i,controlPlaneClientId:a,resolveControlPlane:o}),v={...R(n,{controlPlaneTenantId:i,resolveControlPlane:o}),multiTenancyConfig:{controlPlaneTenantId:i,controlPlaneClientId:a,resolveControlPlane:o}});let y=m.tenantOperationExecutor;if(!y&&n.tenantOperations&&n.tenantOperationEvents&&m.tenantUpgrade){let e={tenantOperations:n.tenantOperations,tenantOperationEvents:n.tenantOperationEvents},t=m.tenantUpgrade,r=h({stores:e,definitions:{upgrade:e=>[{name:`upgrade`,async run(){if(!e.tenant_id)throw Error(`upgrade operations require a tenant_id`);await t(e.tenant_id)}}]}});y={engine:r.engine,enqueue:t=>_(e,r,{...t,tenant_id:t.tenant_id})}}let b=s!==!1,S=b?{resourceServers:s.resourceServers??!0,roles:s.roles??!0}:{resourceServers:!1,roles:!1},{entityHooks:C,tenantHooks:w}=A({controlPlaneTenantId:i,getChildTenantIds:f??(async()=>(await(0,t.fetchAll)(e=>g.tenants.list(e),`tenants`,{cursorField:`id`,pageSize:100})).filter(e=>e.id!==i).map(e=>e.id)),getAdapters:p??(async()=>g),getControlPlaneAdapters:async()=>g,sync:S}),T={resourceServers:[C.resourceServers,...d?.resourceServers??[]],roles:[C.roles,...d?.roles??[]],connections:d?.connections??[],tenants:d?.tenants??[],rolePermissions:d?.rolePermissions??[]},E=x({accessControl:{controlPlaneTenantId:i,requireOrganizationMatch:l,defaultPermissions:c}}),D=M({accessControl:{controlPlaneTenantId:i,requireOrganizationMatch:l,defaultPermissions:c}},{tenants:{async beforeCreate(e,t){return E.beforeCreate&&(t=await E.beforeCreate(e,t)),w.beforeCreate&&(t=await w.beforeCreate(e,t)),t},async afterCreate(e,t){await E.afterCreate?.(e,t),await w.afterCreate?.(e,t)},async beforeDelete(e,t){await E.beforeDelete?.(e,t),await w.beforeDelete?.(e,t)}}}),{app:O}=(0,t.init)({dataAdapter:g,managementDataAdapter:v,...m,tenantOperationExecutor:y,entityHooks:T,managementApiExtensions:[...u,{path:`/tenants`,router:D}]});return O.use(`/api/v2/*`,H(i)),b&&O.use(`/api/v2/*`,oe()),{app:O,controlPlaneTenantId:i}}function q(e={}){return{connections:e.connections??!0,resourceServers:e.resourceServers??!0,hooks:e.hooks??!0,emailProvider:e.emailProvider??!0,branding:e.branding??!0,promptSettings:e.promptSettings??!0}}function J(){return{upserted:0,errors:[]}}function Y(e){return{tenantId:e,connections:J(),resourceServers:J(),hooks:J(),emailProvider:J(),branding:J(),promptSettings:J()}}function X(e){let t=e.metadata;return!!(t&&t.inheritable===!0)}async function Z(e,t,n,r){try{await r()}catch(r){let i=`${t}: ${r instanceof Error?r.message:String(r)}`;if(!n)throw Error(i,{cause:r});e.errors.push(i)}}async function de(e,n,r){return{connections:r.connections?await(0,t.fetchAll)(t=>e.connections.list(n,t),`connections`,{cursorField:`id`,pageSize:100}):[],resourceServers:r.resourceServers?await(0,t.fetchAll)(t=>e.resourceServers.list(n,t),`resource_servers`,{cursorField:`id`,pageSize:100}):[],hooks:r.hooks?await(0,t.fetchAll)(t=>e.hooks.list(n,t),`hooks`,{cursorField:`hook_id`,pageSize:100}):[],emailProvider:r.emailProvider?await e.emailProviders.get(n)??null:null,branding:r.branding?await e.branding.get(n)??null:null,promptSettings:r.promptSettings?await e.promptSettings.get(n)??null:null}}async function fe(e,n,r,i,a,o){if(i.connections)for(let i of e.connections){let e=i.id;e&&await Z(o.connections,`connection ${e}`,a,async()=>{let a=t.connectionInsertSchema.parse(i);await n.connections.get(r,e)?await n.connections.update(r,e,a):await n.connections.create(r,a),o.connections.upserted+=1})}if(i.resourceServers)for(let i of e.resourceServers)!i.is_system||!i.id||await Z(o.resourceServers,`resource_server ${i.id}`,a,async()=>{let e=t.resourceServerInsertSchema.parse(i);await n.resourceServers.get(r,i.id)?await n.resourceServers.update(r,i.id,e):await n.resourceServers.create(r,e),o.resourceServers.upserted+=1});if(i.hooks)for(let i of e.hooks)!X(i)||!i.hook_id||await Z(o.hooks,`hook ${i.hook_id}`,a,async()=>{let e=t.hookInsertSchema.parse(i);await n.hooks.get(r,i.hook_id)?await n.hooks.update(r,i.hook_id,e):await n.hooks.create(r,e),o.hooks.upserted+=1});i.emailProvider&&e.emailProvider&&await Z(o.emailProvider,`email_provider`,a,async()=>{let t=e.emailProvider;await n.emailProviders.get(r)?await n.emailProviders.update(r,t):await n.emailProviders.create(r,t),o.emailProvider.upserted+=1}),i.branding&&e.branding&&await Z(o.branding,`branding`,a,async()=>{await n.branding.set(r,e.branding),o.branding.upserted+=1}),i.promptSettings&&e.promptSettings&&await Z(o.promptSettings,`prompt_settings`,a,async()=>{await n.promptSettings.set(r,e.promptSettings),o.promptSettings.upserted+=1})}async function Q(e,t){let{controlPlaneTenantId:n,getControlPlaneAdapters:r,getAdapters:i,entities:a,continueOnError:o=!1}=e,s=q(a),c=await de(await r(),n,s),l=await i(t),u=Y(t);return await fe(c,l,n,s,o,u),u}function pe(e){let{pkcs7:t,tenant_id:n,...r}=e;return r}async function me(e,n,r={},i){let a=q(r),o=r.signingKeys??!0,s=r.tenants??!0,c=await de(e,n,a),l=o?(await(0,t.listControlPlaneKeys)(e.keys)).map(pe):[],u=s?await he(e,n,i):[];return{connections:c.connections,resourceServers:c.resourceServers.filter(e=>e.is_system),hooks:c.hooks.filter(X),emailProvider:c.emailProvider,branding:c.branding,promptSettings:c.promptSettings,signingKeys:l,tenants:u}}async function he(e,t,n){let r=n&&n!==t?[t,n]:[t],i=[];for(let t of r){let n=await e.tenants.get(t);i.push({id:t,friendly_name:n?.friendly_name||t})}return i}async function ge(e,n,r){let i=J();if(e.length===0)return i;let a=await(0,t.listControlPlaneKeys)(n.keys),o=new Set(a.map(e=>e.kid));for(let t of e)await Z(i,`signing_key ${t.kid}`,r,async()=>{let e=pe(t);o.has(e.kid)||(await n.keys.create(e),o.add(e.kid),i.upserted+=1)});return i}async function _e(e,t,n){let r=J();for(let i of e)await Z(r,`tenant ${i.id}`,n,async()=>{await t.tenants.get(i.id)||(await t.tenants.create({id:i.id,friendly_name:i.friendly_name}),r.upserted+=1)});return r}async function ve(e,n,r,i={}){let a=i.continueOnError??!1,o=q(i.entities),s=i.entities?.signingKeys??!0,c=i.entities?.tenants??!0,l={connections:e.connections,resourceServers:e.resourceServers,hooks:e.hooks,emailProvider:e.emailProvider?t.emailProviderSchema.parse(e.emailProvider):null,branding:e.branding?t.brandingSchema.parse(e.branding):null,promptSettings:e.promptSettings?t.promptSettingSchema.parse(e.promptSettings):null},u=c?await _e(e.tenants??[],n,a):J(),d=Y(r);await fe(l,n,r,o,a,d);let f=s?await ge(e.signingKeys,n,a):J();return{...d,signingKeys:f,tenants:u}}function ye(e){return{syncDefaults:t=>Q(e,t),syncDefaultsToTenants:async t=>{let n=[];for(let r of t)n.push(await Q(e,r));return n}}}function be(e){let t=$(e);return{name:`multi-tenancy`,middleware:K(e),hooks:t,routes:[{path:`/management`,handler:M(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 $(e){let t=e.accessControl?i(e.accessControl):{},n=e.databaseIsolation?o(e.databaseIsolation):{},r=x(e);return{...t,...n,tenants:r}}function xe(t){let n=new e.Hono,r=$(t);return n.route(`/tenants`,M(t,r)),n}function Se(e){return{hooks:$(e),middleware:K(e),app:xe(e),config:e,wrapAdapters:(t,n)=>V(t,{controlPlaneTenantId:e.accessControl?.controlPlaneTenantId,controlPlaneClientId:n?.controlPlaneClientId})}}exports.applyControlPlaneDefaultsPayload=ve,exports.buildControlPlaneDefaultsPayload=me,exports.buildEngineInstanceId=l,exports.createAccessControlHooks=i,exports.createAccessControlMiddleware=U,exports.createControlPlaneTenantMiddleware=H,exports.createDatabaseHooks=o,exports.createDatabaseMiddleware=G,exports.createDirectRolloutAdapter=ye,exports.createInlineExecutor=h,exports.createMultiTenancy=xe,exports.createMultiTenancyHooks=$,exports.createMultiTenancyMiddleware=K,exports.createMultiTenancyPlugin=be,exports.createOperationRecorder=f,exports.createProtectSyncedMiddleware=oe,exports.createProvisioningHooks=x,exports.createRuntimeFallbackAdapter=z,exports.createSubdomainMiddleware=W,exports.createSyncHooks=A,exports.createTenantsOpenAPIRouter=M,exports.enqueueTenantOperation=_,exports.errorToMessage=d,exports.initMultiTenant=ue,exports.inlineStepRunner=m,exports.isTerminalStatus=p,exports.mergeClientWithFallback=ce,exports.projectControlPlaneDefaults=Q,exports.runRecordedTenantOperation=y,exports.setupMultiTenancy=Se,exports.validateTenantAccess=a,exports.withRuntimeFallback=V,exports.withSystemResourceServerInheritance=R;
|
package/dist/multi-tenancy.mjs
CHANGED
|
@@ -96,12 +96,12 @@ function N(e) {
|
|
|
96
96
|
}
|
|
97
97
|
//#endregion
|
|
98
98
|
//#region src/operations/inline-executor.ts
|
|
99
|
-
var
|
|
99
|
+
var te = { async do(e, t, n) {
|
|
100
100
|
let r = typeof t == "function" ? t : n;
|
|
101
101
|
if (!r) throw Error("StepRunner.do called without a function");
|
|
102
102
|
return r();
|
|
103
103
|
} };
|
|
104
|
-
function
|
|
104
|
+
function ne(e) {
|
|
105
105
|
let t = M(e.stores);
|
|
106
106
|
return {
|
|
107
107
|
engine: "inline",
|
|
@@ -121,7 +121,7 @@ function te(e) {
|
|
|
121
121
|
try {
|
|
122
122
|
let r = await e.run({
|
|
123
123
|
operation: n,
|
|
124
|
-
step:
|
|
124
|
+
step: te
|
|
125
125
|
});
|
|
126
126
|
await t.appendEvent(n.id, {
|
|
127
127
|
step: e.name,
|
|
@@ -142,7 +142,7 @@ function te(e) {
|
|
|
142
142
|
}
|
|
143
143
|
//#endregion
|
|
144
144
|
//#region src/operations/enqueue.ts
|
|
145
|
-
async function
|
|
145
|
+
async function re(e, t, n) {
|
|
146
146
|
let r = await e.tenantOperations.create({
|
|
147
147
|
tenant_id: t.tenant_id,
|
|
148
148
|
rollout_id: t.rollout_id,
|
|
@@ -165,8 +165,8 @@ async function ne(e, t, n) {
|
|
|
165
165
|
engine_instance_id: i
|
|
166
166
|
};
|
|
167
167
|
}
|
|
168
|
-
async function
|
|
169
|
-
let r = M(e), i = await
|
|
168
|
+
async function ie(e, t, n) {
|
|
169
|
+
let r = M(e), i = await re(e, n, t.engine);
|
|
170
170
|
try {
|
|
171
171
|
await t.start(i);
|
|
172
172
|
} catch (t) {
|
|
@@ -186,14 +186,14 @@ async function re(e, t, n) {
|
|
|
186
186
|
}
|
|
187
187
|
//#endregion
|
|
188
188
|
//#region src/operations/record-provision.ts
|
|
189
|
-
function
|
|
189
|
+
function ae(e) {
|
|
190
190
|
if (e.tenantOperations && e.tenantOperationEvents) return {
|
|
191
191
|
tenantOperations: e.tenantOperations,
|
|
192
192
|
tenantOperationEvents: e.tenantOperationEvents
|
|
193
193
|
};
|
|
194
194
|
}
|
|
195
|
-
async function
|
|
196
|
-
let r =
|
|
195
|
+
async function oe(e, t, n) {
|
|
196
|
+
let r = ae(e);
|
|
197
197
|
if (!r) {
|
|
198
198
|
await n(void 0);
|
|
199
199
|
return;
|
|
@@ -206,7 +206,7 @@ async function ae(e, t, n) {
|
|
|
206
206
|
}
|
|
207
207
|
}, o;
|
|
208
208
|
if (await a(async () => {
|
|
209
|
-
let e = await
|
|
209
|
+
let e = await re(r, t, "inline");
|
|
210
210
|
o = e.id, await i.markRunning(e.id);
|
|
211
211
|
}), !o) {
|
|
212
212
|
await n(void 0);
|
|
@@ -241,22 +241,22 @@ async function ae(e, t, n) {
|
|
|
241
241
|
}
|
|
242
242
|
//#endregion
|
|
243
243
|
//#region src/hooks/provisioning.ts
|
|
244
|
-
function
|
|
244
|
+
function se(e) {
|
|
245
245
|
return `urn:authhero:tenant:${e.toLowerCase()}`;
|
|
246
246
|
}
|
|
247
|
-
function
|
|
247
|
+
function P(e) {
|
|
248
248
|
return {
|
|
249
249
|
async beforeCreate(e, t) {
|
|
250
250
|
return !t.audience && t.id ? {
|
|
251
251
|
...t,
|
|
252
|
-
audience:
|
|
252
|
+
audience: se(t.id)
|
|
253
253
|
} : t;
|
|
254
254
|
},
|
|
255
255
|
async afterCreate(r, i) {
|
|
256
256
|
let { accessControl: a, databaseIsolation: o } = e;
|
|
257
|
-
if (a && r.ctx && await
|
|
257
|
+
if (a && r.ctx && await ce(r, i, a), o?.onProvision) {
|
|
258
258
|
let e = o.onProvision;
|
|
259
|
-
o.recordProvisionOperations === !1 ? await e(i.id) : await
|
|
259
|
+
o.recordProvisionOperations === !1 ? await e(i.id) : await oe(r.adapters, {
|
|
260
260
|
kind: "provision",
|
|
261
261
|
tenant_id: i.id,
|
|
262
262
|
initiated_by: r.ctx?.var.user?.sub
|
|
@@ -286,14 +286,14 @@ function F(e) {
|
|
|
286
286
|
}
|
|
287
287
|
};
|
|
288
288
|
}
|
|
289
|
-
async function
|
|
289
|
+
async function ce(e, t, n) {
|
|
290
290
|
let { controlPlaneTenantId: r, defaultPermissions: i, defaultRoles: a, issuer: o, adminRoleName: s = "Tenant Admin", adminRoleDescription: c = "Full access to all tenant management operations", addCreatorToOrganization: l = !0 } = n, u = await e.adapters.organizations.create(r, {
|
|
291
291
|
name: t.id,
|
|
292
292
|
display_name: t.friendly_name || t.id
|
|
293
293
|
}), d;
|
|
294
|
-
if (o && (d = await
|
|
294
|
+
if (o && (d = await ue(e, r, s, c)), l && e.ctx) {
|
|
295
295
|
let t = e.ctx.var.user;
|
|
296
|
-
if (t?.sub && !await
|
|
296
|
+
if (t?.sub && !await le(e, r, t.sub)) try {
|
|
297
297
|
await e.adapters.userOrganizations.create(r, {
|
|
298
298
|
user_id: t.sub,
|
|
299
299
|
organization_id: u.id
|
|
@@ -304,12 +304,12 @@ async function se(e, t, n) {
|
|
|
304
304
|
}
|
|
305
305
|
a && a.length > 0 && console.log(`Would assign roles ${a.join(", ")} to organization ${u.id}`), i && i.length > 0 && console.log(`Would grant permissions ${i.join(", ")} to organization ${u.id}`);
|
|
306
306
|
}
|
|
307
|
-
async function
|
|
307
|
+
async function le(e, n, r) {
|
|
308
308
|
let i = await e.adapters.userRoles.list(n, r, void 0, "");
|
|
309
309
|
for (let r of i) if ((await e.adapters.rolePermissions.list(n, r.id, { per_page: 1e3 })).some((e) => e.permission_name === "admin:organizations" && e.resource_server_identifier === t)) return !0;
|
|
310
310
|
return !1;
|
|
311
311
|
}
|
|
312
|
-
async function
|
|
312
|
+
async function ue(e, r, i, a) {
|
|
313
313
|
let o = (await e.adapters.roles.list(r, {})).roles.find((e) => e.name === i);
|
|
314
314
|
if (o) return o.id;
|
|
315
315
|
let s = await e.adapters.roles.create(r, {
|
|
@@ -324,7 +324,7 @@ async function le(e, r, i, a) {
|
|
|
324
324
|
}
|
|
325
325
|
//#endregion
|
|
326
326
|
//#region src/hooks/sync.ts
|
|
327
|
-
function
|
|
327
|
+
function F(e, t, n = () => !0) {
|
|
328
328
|
let { controlPlaneTenantId: r, getChildTenantIds: i, getAdapters: a } = e, o = /* @__PURE__ */ new Map();
|
|
329
329
|
async function s(e, n, r) {
|
|
330
330
|
return (await t(e).list(n, {
|
|
@@ -379,7 +379,7 @@ function I(e, t, n = () => !0) {
|
|
|
379
379
|
}
|
|
380
380
|
};
|
|
381
381
|
}
|
|
382
|
-
function
|
|
382
|
+
function I(e, t, n = () => !0) {
|
|
383
383
|
let { controlPlaneTenantId: r, getControlPlaneAdapters: i, getAdapters: a } = e;
|
|
384
384
|
return { async afterCreate(e, o) {
|
|
385
385
|
if (o.id !== r) try {
|
|
@@ -403,7 +403,7 @@ function L(e, t, n = () => !0) {
|
|
|
403
403
|
}
|
|
404
404
|
} };
|
|
405
405
|
}
|
|
406
|
-
var
|
|
406
|
+
var L = (e) => ({
|
|
407
407
|
list: async (t, n) => (await e.resourceServers.list(t, n)).resource_servers,
|
|
408
408
|
listPaginated: (t, n) => e.resourceServers.list(t, n),
|
|
409
409
|
get: (t, n) => e.resourceServers.get(t, n),
|
|
@@ -421,7 +421,7 @@ var R = (e) => ({
|
|
|
421
421
|
token_lifetime: e.token_lifetime,
|
|
422
422
|
token_lifetime_for_web: e.token_lifetime_for_web
|
|
423
423
|
})
|
|
424
|
-
}),
|
|
424
|
+
}), R = (e) => ({
|
|
425
425
|
list: async (t, n) => (await e.roles.list(t, n)).roles,
|
|
426
426
|
listPaginated: (t, n) => e.roles.list(t, n),
|
|
427
427
|
get: (t, n) => e.roles.get(t, n),
|
|
@@ -436,11 +436,11 @@ var R = (e) => ({
|
|
|
436
436
|
description: e.description
|
|
437
437
|
})
|
|
438
438
|
});
|
|
439
|
-
function
|
|
439
|
+
function z(e) {
|
|
440
440
|
return e.metadata?.sync !== !1;
|
|
441
441
|
}
|
|
442
|
-
function
|
|
443
|
-
let { sync: t = {}, filters: n = {} } = e, r = t.resourceServers ?? !0, i = t.roles ?? !0, a = (e) =>
|
|
442
|
+
function B(e) {
|
|
443
|
+
let { sync: t = {}, filters: n = {} } = e, r = t.resourceServers ?? !0, i = t.roles ?? !0, a = (e) => z(e) ? n.resourceServers ? n.resourceServers(e) : !0 : !1, o = (e) => z(e) ? n.roles ? n.roles(e) : !0 : !1, s = r ? F(e, L, a) : void 0, c = i ? F(e, R, o) : void 0, l = r ? I(e, L, a) : void 0, f = i ? I(e, R, o) : void 0, p = i ? { async afterCreate(t, r) {
|
|
444
444
|
if (r.id !== e.controlPlaneTenantId) {
|
|
445
445
|
await f?.afterCreate?.(t, r);
|
|
446
446
|
try {
|
|
@@ -494,19 +494,24 @@ function V(e) {
|
|
|
494
494
|
};
|
|
495
495
|
}
|
|
496
496
|
//#endregion
|
|
497
|
+
//#region src/middleware/request-data.ts
|
|
498
|
+
function V(e) {
|
|
499
|
+
return e.var.data ?? e.env.data;
|
|
500
|
+
}
|
|
501
|
+
//#endregion
|
|
497
502
|
//#region src/routes/tenants.ts
|
|
498
|
-
var
|
|
503
|
+
var de = C.object({
|
|
499
504
|
sub: C.string(),
|
|
500
505
|
tenant_id: C.string().optional(),
|
|
501
506
|
org_id: C.string().optional(),
|
|
502
507
|
scope: C.string().optional(),
|
|
503
508
|
permissions: C.array(C.string()).optional()
|
|
504
509
|
}).passthrough();
|
|
505
|
-
function
|
|
506
|
-
let t =
|
|
510
|
+
function fe(e) {
|
|
511
|
+
let t = de.safeParse(e);
|
|
507
512
|
return t.success ? t.data : void 0;
|
|
508
513
|
}
|
|
509
|
-
function
|
|
514
|
+
function pe(e) {
|
|
510
515
|
let t = e.permissions ?? [], n = e.scope ? e.scope.split(" ").filter(Boolean) : [], r = new Set([...t, ...n]);
|
|
511
516
|
return r.has("delete:tenants") || r.has("admin:organizations");
|
|
512
517
|
}
|
|
@@ -530,7 +535,7 @@ function H(e, t) {
|
|
|
530
535
|
}), async (t) => {
|
|
531
536
|
let { page: n, per_page: r, include_totals: i, q: a } = t.req.valid("query"), o = t.var.user, s = o?.permissions || [];
|
|
532
537
|
if (!(o?.org_id ?? t.var.organization_id) && s.includes("admin:organizations")) {
|
|
533
|
-
let e = await t.
|
|
538
|
+
let e = await V(t).tenants.list({
|
|
534
539
|
page: n,
|
|
535
540
|
per_page: r,
|
|
536
541
|
include_totals: i,
|
|
@@ -543,10 +548,10 @@ function H(e, t) {
|
|
|
543
548
|
length: e.tenants.length
|
|
544
549
|
}) : t.json({ tenants: e.tenants });
|
|
545
550
|
}
|
|
546
|
-
let c = e.accessControl?.controlPlaneTenantId ?? t.
|
|
551
|
+
let c = e.accessControl?.controlPlaneTenantId ?? V(t).multiTenancyConfig?.controlPlaneTenantId;
|
|
547
552
|
if (c && !o?.sub) throw new w(403, { message: "Access denied: token has no subject" });
|
|
548
553
|
if (c && o?.sub) {
|
|
549
|
-
let e = (await d((e) => t.
|
|
554
|
+
let e = (await d((e) => V(t).userOrganizations.listUserOrganizations(c, o.sub, e), "organizations")).map((e) => e.name);
|
|
550
555
|
if (e.length === 0) return i ? t.json({
|
|
551
556
|
tenants: [],
|
|
552
557
|
start: 0,
|
|
@@ -560,7 +565,7 @@ function H(e, t) {
|
|
|
560
565
|
limit: u,
|
|
561
566
|
length: s
|
|
562
567
|
}) : t.json({ tenants: [] });
|
|
563
|
-
let m = p.map((e) => `id:${e}`).join(" OR "), h = a ? `(${m}) AND (${a})` : m, g = await t.
|
|
568
|
+
let m = p.map((e) => `id:${e}`).join(" OR "), h = a ? `(${m}) AND (${a})` : m, g = await V(t).tenants.list({
|
|
564
569
|
q: h,
|
|
565
570
|
per_page: u,
|
|
566
571
|
include_totals: !1
|
|
@@ -572,7 +577,7 @@ function H(e, t) {
|
|
|
572
577
|
length: s
|
|
573
578
|
}) : t.json({ tenants: g.tenants });
|
|
574
579
|
}
|
|
575
|
-
let l = await t.
|
|
580
|
+
let l = await V(t).tenants.list({
|
|
576
581
|
page: n,
|
|
577
582
|
per_page: r,
|
|
578
583
|
include_totals: i,
|
|
@@ -601,11 +606,11 @@ function H(e, t) {
|
|
|
601
606
|
}), async (e) => {
|
|
602
607
|
if (!e.var.user?.sub) throw new w(401, { message: "Authentication required to create tenants" });
|
|
603
608
|
let n = e.req.valid("json"), r = {
|
|
604
|
-
adapters: e
|
|
609
|
+
adapters: V(e),
|
|
605
610
|
ctx: e
|
|
606
611
|
};
|
|
607
612
|
t.tenants?.beforeCreate && (n = await t.tenants.beforeCreate(r, n));
|
|
608
|
-
let i = await e.
|
|
613
|
+
let i = await V(e).tenants.create(n);
|
|
609
614
|
return t.tenants?.afterCreate && await t.tenants.afterCreate(r, i), e.json(i, 201);
|
|
610
615
|
}), n.openapi(S({
|
|
611
616
|
tags: ["tenants"],
|
|
@@ -619,24 +624,24 @@ function H(e, t) {
|
|
|
619
624
|
404: { description: "Tenant not found" }
|
|
620
625
|
}
|
|
621
626
|
}), async (n) => {
|
|
622
|
-
let { id: r } = n.req.valid("param"), i = e.accessControl?.controlPlaneTenantId ?? n.
|
|
627
|
+
let { id: r } = n.req.valid("param"), i = e.accessControl?.controlPlaneTenantId ?? V(n).multiTenancyConfig?.controlPlaneTenantId;
|
|
623
628
|
if (i) {
|
|
624
|
-
let e =
|
|
629
|
+
let e = fe(n.var.user);
|
|
625
630
|
if (!e?.sub) throw new w(401, { message: "Authentication required" });
|
|
626
631
|
if (r === i) throw new w(403, { message: "Cannot delete the control plane" });
|
|
627
632
|
let t = n.var.org_name, a = r.toLowerCase(), o = !!t && t.toLowerCase() === a;
|
|
628
633
|
if (!o) {
|
|
629
634
|
let r = !!(e.org_id ?? n.var.organization_id ?? t), a = !e.tenant_id || e.tenant_id === i;
|
|
630
|
-
!r && a &&
|
|
635
|
+
!r && a && pe(e) && (o = !0);
|
|
631
636
|
}
|
|
632
|
-
if (o ||= (await d((t) => n.
|
|
637
|
+
if (o ||= (await d((t) => V(n).userOrganizations.listUserOrganizations(i, e.sub, t), "organizations")).some((e) => e.name?.toLowerCase() === a), !o) throw new w(403, { message: "Access denied to this tenant" });
|
|
633
638
|
}
|
|
634
|
-
if (!await n.
|
|
639
|
+
if (!await V(n).tenants.get(r)) throw new w(404, { message: "Tenant not found" });
|
|
635
640
|
let a = {
|
|
636
|
-
adapters: n
|
|
641
|
+
adapters: V(n),
|
|
637
642
|
ctx: n
|
|
638
643
|
};
|
|
639
|
-
return t.tenants?.beforeDelete && await t.tenants.beforeDelete(a, r), await n.
|
|
644
|
+
return t.tenants?.beforeDelete && await t.tenants.beforeDelete(a, r), await V(n).tenants.remove(r), t.tenants?.afterDelete && await t.tenants.afterDelete(a, r), n.body(null, 204);
|
|
640
645
|
}), n.openapi(S({
|
|
641
646
|
tags: ["tenants", "settings"],
|
|
642
647
|
method: "get",
|
|
@@ -648,7 +653,7 @@ function H(e, t) {
|
|
|
648
653
|
description: "Current tenant settings"
|
|
649
654
|
} }
|
|
650
655
|
}), async (e) => {
|
|
651
|
-
let t = await e.
|
|
656
|
+
let t = await V(e).tenants.get(e.var.tenant_id);
|
|
652
657
|
if (!t) throw new w(404, { message: "Tenant not found" });
|
|
653
658
|
return e.json(t);
|
|
654
659
|
}), n.openapi(S({
|
|
@@ -665,26 +670,26 @@ function H(e, t) {
|
|
|
665
670
|
description: "Updated tenant settings"
|
|
666
671
|
} }
|
|
667
672
|
}), async (e) => {
|
|
668
|
-
let { id: t, ...n } = e.req.valid("json"), r = await e.
|
|
673
|
+
let { id: t, ...n } = e.req.valid("json"), r = await V(e).tenants.get(e.var.tenant_id);
|
|
669
674
|
if (!r) throw new w(404, { message: "Tenant not found" });
|
|
670
675
|
if ("default_client_id" in n) {
|
|
671
676
|
let t = n.default_client_id;
|
|
672
677
|
if (typeof t == "string" && t.length > 0) {
|
|
673
|
-
let n = await e.
|
|
678
|
+
let n = await V(e).clients.get(e.var.tenant_id, t);
|
|
674
679
|
if (!n) throw new w(400, { message: `Client with id '${t}' not found` });
|
|
675
680
|
if (!m(n)) throw new w(400, { message: `Client '${t}' is not an interactive client and cannot be used as the default client` });
|
|
676
681
|
}
|
|
677
682
|
}
|
|
678
683
|
let i = c(r, n);
|
|
679
|
-
await e.
|
|
680
|
-
let a = await e.
|
|
684
|
+
await V(e).tenants.update(e.var.tenant_id, i);
|
|
685
|
+
let a = await V(e).tenants.get(e.var.tenant_id);
|
|
681
686
|
if (!a) throw new w(500, { message: "Failed to retrieve updated tenant" });
|
|
682
687
|
return e.json(a);
|
|
683
688
|
}), n;
|
|
684
689
|
}
|
|
685
690
|
//#endregion
|
|
686
691
|
//#region src/middleware/protect-synced.ts
|
|
687
|
-
function
|
|
692
|
+
function me(e) {
|
|
688
693
|
for (let { pattern: t, type: n } of [
|
|
689
694
|
{
|
|
690
695
|
pattern: /\/api\/v2\/resource-servers\/([^/]+)$/,
|
|
@@ -707,7 +712,7 @@ function pe(e) {
|
|
|
707
712
|
}
|
|
708
713
|
return null;
|
|
709
714
|
}
|
|
710
|
-
async function
|
|
715
|
+
async function he(e, t, n) {
|
|
711
716
|
try {
|
|
712
717
|
switch (n.type) {
|
|
713
718
|
case "resource_server": return (await e.resourceServers.get(t, n.id))?.is_system === !0;
|
|
@@ -719,7 +724,7 @@ async function me(e, t, n) {
|
|
|
719
724
|
return !1;
|
|
720
725
|
}
|
|
721
726
|
}
|
|
722
|
-
function
|
|
727
|
+
function ge(e) {
|
|
723
728
|
return {
|
|
724
729
|
resource_server: "resource server",
|
|
725
730
|
role: "role",
|
|
@@ -733,11 +738,11 @@ function U() {
|
|
|
733
738
|
"PUT",
|
|
734
739
|
"DELETE"
|
|
735
740
|
].includes(e.req.method)) return t();
|
|
736
|
-
let n =
|
|
741
|
+
let n = me(e.req.path);
|
|
737
742
|
if (!n) return t();
|
|
738
743
|
let r = e.var.tenant_id || e.req.header("x-tenant-id") || e.req.header("tenant-id");
|
|
739
744
|
if (!r) return t();
|
|
740
|
-
if (await
|
|
745
|
+
if (await he(V(e), r, n)) throw new w(403, { message: `This ${ge(n.type)} is a system resource and cannot be modified. Make changes in the control plane instead.` });
|
|
741
746
|
return t();
|
|
742
747
|
};
|
|
743
748
|
}
|
|
@@ -759,7 +764,7 @@ function G(e, t) {
|
|
|
759
764
|
let n = [...t || [], ...e || []];
|
|
760
765
|
return [...new Set(n)];
|
|
761
766
|
}
|
|
762
|
-
function
|
|
767
|
+
function _e(e, t) {
|
|
763
768
|
if (!t?.length) return e || [];
|
|
764
769
|
if (!e?.length) return t;
|
|
765
770
|
let n = /* @__PURE__ */ new Map();
|
|
@@ -767,13 +772,13 @@ function ge(e, t) {
|
|
|
767
772
|
for (let t of e) n.set(t.value, t);
|
|
768
773
|
return Array.from(n.values());
|
|
769
774
|
}
|
|
770
|
-
function
|
|
775
|
+
function ve(e, t) {
|
|
771
776
|
return t ? {
|
|
772
777
|
...e,
|
|
773
|
-
scopes:
|
|
778
|
+
scopes: _e(e.scopes, t.scopes)
|
|
774
779
|
} : e;
|
|
775
780
|
}
|
|
776
|
-
function
|
|
781
|
+
function ye(e, t) {
|
|
777
782
|
return t ? {
|
|
778
783
|
...e,
|
|
779
784
|
callbacks: G(e.callbacks, t.callbacks),
|
|
@@ -782,7 +787,7 @@ function ve(e, t) {
|
|
|
782
787
|
allowed_origins: G(e.allowed_origins, t.allowed_origins)
|
|
783
788
|
} : e;
|
|
784
789
|
}
|
|
785
|
-
function
|
|
790
|
+
function be(e) {
|
|
786
791
|
let { controlPlaneTenantId: t, controlPlaneClientId: n, resolveControlPlane: r } = e;
|
|
787
792
|
if (r) return async (e) => r({ tenant_id: e });
|
|
788
793
|
if (!t) return async () => void 0;
|
|
@@ -792,14 +797,14 @@ function ye(e) {
|
|
|
792
797
|
};
|
|
793
798
|
return async () => i;
|
|
794
799
|
}
|
|
795
|
-
function
|
|
800
|
+
function xe(e, t) {
|
|
796
801
|
return {
|
|
797
802
|
...e.resourceServers,
|
|
798
803
|
get: async (n, r) => {
|
|
799
804
|
let i = await e.resourceServers.get(n, r);
|
|
800
805
|
if (!i) return i;
|
|
801
806
|
let a = await t(n);
|
|
802
|
-
return !a || n === a.tenantId || !i.is_system ? i :
|
|
807
|
+
return !a || n === a.tenantId || !i.is_system ? i : ve(i, await e.resourceServers.get(a.tenantId, r));
|
|
803
808
|
},
|
|
804
809
|
list: async (n, r) => {
|
|
805
810
|
let i = await e.resourceServers.list(n, r), a = await t(n);
|
|
@@ -811,7 +816,7 @@ function be(e, t) {
|
|
|
811
816
|
let n = await e.resourceServers.get(o, t);
|
|
812
817
|
n && c.set(t, n);
|
|
813
818
|
}));
|
|
814
|
-
let l = i.resource_servers.map((e) => e.is_system && e.id ?
|
|
819
|
+
let l = i.resource_servers.map((e) => e.is_system && e.id ? ve(e, c.get(e.id) ?? null) : e);
|
|
815
820
|
return {
|
|
816
821
|
...i,
|
|
817
822
|
resource_servers: l
|
|
@@ -819,18 +824,18 @@ function be(e, t) {
|
|
|
819
824
|
}
|
|
820
825
|
};
|
|
821
826
|
}
|
|
822
|
-
function
|
|
823
|
-
let n =
|
|
827
|
+
function Se(e, t) {
|
|
828
|
+
let n = be({
|
|
824
829
|
controlPlaneTenantId: t.controlPlaneTenantId,
|
|
825
830
|
resolveControlPlane: t.resolveControlPlane
|
|
826
831
|
});
|
|
827
832
|
return {
|
|
828
833
|
...e,
|
|
829
|
-
resourceServers:
|
|
834
|
+
resourceServers: xe(e, n)
|
|
830
835
|
};
|
|
831
836
|
}
|
|
832
|
-
function
|
|
833
|
-
let { controlPlaneTenantId: n, controlPlaneClientId: r, resolveControlPlane: i } = t, a =
|
|
837
|
+
function Ce(e, t) {
|
|
838
|
+
let { controlPlaneTenantId: n, controlPlaneClientId: r, resolveControlPlane: i } = t, a = be({
|
|
834
839
|
controlPlaneTenantId: n,
|
|
835
840
|
controlPlaneClientId: r,
|
|
836
841
|
resolveControlPlane: i
|
|
@@ -880,22 +885,22 @@ function Se(e, t) {
|
|
|
880
885
|
return !r || t === r.tenantId ? null : e.emailProviders.get(r.tenantId);
|
|
881
886
|
}
|
|
882
887
|
},
|
|
883
|
-
resourceServers:
|
|
884
|
-
hooks:
|
|
888
|
+
resourceServers: xe(e, a),
|
|
889
|
+
hooks: Te(e, a)
|
|
885
890
|
};
|
|
886
891
|
}
|
|
887
|
-
function
|
|
892
|
+
function we(e) {
|
|
888
893
|
if (!e || typeof e != "object") return !1;
|
|
889
894
|
let t = e.metadata;
|
|
890
895
|
return !t || typeof t != "object" ? !1 : t.inheritable === !0;
|
|
891
896
|
}
|
|
892
|
-
function
|
|
897
|
+
function Te(e, t) {
|
|
893
898
|
return {
|
|
894
899
|
...e.hooks,
|
|
895
900
|
list: async (n, r) => {
|
|
896
901
|
let i = await e.hooks.list(n, r), a = await t(n);
|
|
897
902
|
if (!a || n === a.tenantId) return i;
|
|
898
|
-
let o = ((await e.hooks.list(a.tenantId, r)).hooks || []).filter(
|
|
903
|
+
let o = ((await e.hooks.list(a.tenantId, r)).hooks || []).filter(we);
|
|
899
904
|
if (o.length === 0) return i;
|
|
900
905
|
let s = new Set((i.hooks || []).map((e) => e.hook_id)), c = o.filter((e) => !s.has(e.hook_id));
|
|
901
906
|
return {
|
|
@@ -910,22 +915,22 @@ function we(e, t) {
|
|
|
910
915
|
let a = await t(n);
|
|
911
916
|
if (!a || n === a.tenantId) return i;
|
|
912
917
|
let o = await e.hooks.get(a.tenantId, r);
|
|
913
|
-
return o &&
|
|
918
|
+
return o && we(o) ? o : null;
|
|
914
919
|
}
|
|
915
920
|
};
|
|
916
921
|
}
|
|
917
922
|
function K(e, t) {
|
|
918
|
-
return
|
|
923
|
+
return Ce(e, t);
|
|
919
924
|
}
|
|
920
925
|
//#endregion
|
|
921
926
|
//#region src/middleware/index.ts
|
|
922
|
-
function
|
|
927
|
+
function Ee(e) {
|
|
923
928
|
return async (t, n) => {
|
|
924
929
|
let r = t.var.user;
|
|
925
930
|
return r?.tenant_id === e && r.org_name && t.set("tenant_id", r.org_name), n();
|
|
926
931
|
};
|
|
927
932
|
}
|
|
928
|
-
function
|
|
933
|
+
function De(e) {
|
|
929
934
|
return async (n, r) => {
|
|
930
935
|
if (!e.accessControl) return r();
|
|
931
936
|
let { controlPlaneTenantId: i } = e.accessControl, a = n.var.org_name, o = n.var.organization_id, s = a || o, c = n.var.tenant_id, l = n.var.user, u = (l?.aud ? Array.isArray(l.aud) ? l.aud : [l.aud] : []).includes(t);
|
|
@@ -934,7 +939,7 @@ function Ee(e) {
|
|
|
934
939
|
return r();
|
|
935
940
|
};
|
|
936
941
|
}
|
|
937
|
-
function
|
|
942
|
+
function Oe(e) {
|
|
938
943
|
return async (t, n) => {
|
|
939
944
|
if (!e.subdomainRouting) return n();
|
|
940
945
|
let { baseDomain: r, reservedSubdomains: i = [], resolveSubdomain: a } = e.subdomainRouting, o = t.req.header("x-forwarded-host") || t.req.header("host") || "", s = null;
|
|
@@ -946,21 +951,24 @@ function De(e) {
|
|
|
946
951
|
let c = null;
|
|
947
952
|
if (a) c = await a(s);
|
|
948
953
|
else if (e.subdomainRouting.useOrganizations !== !1 && e.accessControl) try {
|
|
949
|
-
let n = await t.
|
|
954
|
+
let n = await V(t).organizations.get(e.accessControl.controlPlaneTenantId, s);
|
|
950
955
|
n && (c = n.id);
|
|
951
956
|
} catch {}
|
|
952
957
|
if (!c) throw new w(404, { message: `Tenant not found for subdomain: ${s}` });
|
|
953
958
|
return t.set("tenant_id", c), n();
|
|
954
959
|
};
|
|
955
960
|
}
|
|
956
|
-
function
|
|
961
|
+
function ke(e) {
|
|
957
962
|
return async (t, n) => {
|
|
958
963
|
if (!e.databaseIsolation) return n();
|
|
959
964
|
let r = t.var.tenant_id;
|
|
960
965
|
if (!r) throw new w(400, { message: "Tenant ID not found in request" });
|
|
961
966
|
try {
|
|
962
967
|
let n = await e.databaseIsolation.getAdapters(r);
|
|
963
|
-
t.env
|
|
968
|
+
t.set("baseData", n), t.env = {
|
|
969
|
+
...t.env,
|
|
970
|
+
data: n
|
|
971
|
+
};
|
|
964
972
|
} catch (e) {
|
|
965
973
|
throw console.error(`Failed to resolve database for tenant ${r}:`, e), new w(500, { message: "Failed to resolve tenant database" });
|
|
966
974
|
}
|
|
@@ -968,12 +976,12 @@ function Oe(e) {
|
|
|
968
976
|
};
|
|
969
977
|
}
|
|
970
978
|
function q(e) {
|
|
971
|
-
let t =
|
|
979
|
+
let t = Oe(e), n = De(e), r = ke(e);
|
|
972
980
|
return async (e, i) => (await t(e, async () => {}), await n(e, async () => {}), await r(e, async () => {}), i());
|
|
973
981
|
}
|
|
974
982
|
//#endregion
|
|
975
983
|
//#region src/init.ts
|
|
976
|
-
function
|
|
984
|
+
function Ae(e) {
|
|
977
985
|
let { dataAdapter: t, controlPlane: n, controlPlane: { tenantId: r = "control_plane", clientId: i } = {}, resolveControlPlane: a, sync: o = {
|
|
978
986
|
resourceServers: !0,
|
|
979
987
|
roles: !0
|
|
@@ -985,7 +993,7 @@ function ke(e) {
|
|
|
985
993
|
controlPlaneClientId: i,
|
|
986
994
|
resolveControlPlane: a
|
|
987
995
|
}), _ = {
|
|
988
|
-
...
|
|
996
|
+
...Se(t, {
|
|
989
997
|
controlPlaneTenantId: r,
|
|
990
998
|
resolveControlPlane: a
|
|
991
999
|
}),
|
|
@@ -1000,7 +1008,7 @@ function ke(e) {
|
|
|
1000
1008
|
let e = {
|
|
1001
1009
|
tenantOperations: t.tenantOperations,
|
|
1002
1010
|
tenantOperationEvents: t.tenantOperationEvents
|
|
1003
|
-
}, n = h.tenantUpgrade, r =
|
|
1011
|
+
}, n = h.tenantUpgrade, r = ne({
|
|
1004
1012
|
stores: e,
|
|
1005
1013
|
definitions: { upgrade: (e) => [{
|
|
1006
1014
|
name: "upgrade",
|
|
@@ -1012,7 +1020,7 @@ function ke(e) {
|
|
|
1012
1020
|
});
|
|
1013
1021
|
v = {
|
|
1014
1022
|
engine: r.engine,
|
|
1015
|
-
enqueue: (t) =>
|
|
1023
|
+
enqueue: (t) => ie(e, r, {
|
|
1016
1024
|
...t,
|
|
1017
1025
|
tenant_id: t.tenant_id
|
|
1018
1026
|
})
|
|
@@ -1024,7 +1032,7 @@ function ke(e) {
|
|
|
1024
1032
|
} : {
|
|
1025
1033
|
resourceServers: !1,
|
|
1026
1034
|
roles: !1
|
|
1027
|
-
}, { entityHooks: x, tenantHooks: S } =
|
|
1035
|
+
}, { entityHooks: x, tenantHooks: S } = B({
|
|
1028
1036
|
controlPlaneTenantId: r,
|
|
1029
1037
|
getChildTenantIds: f ?? (async () => (await d((e) => g.tenants.list(e), "tenants", {
|
|
1030
1038
|
cursorField: "id",
|
|
@@ -1039,7 +1047,7 @@ function ke(e) {
|
|
|
1039
1047
|
connections: u?.connections ?? [],
|
|
1040
1048
|
tenants: u?.tenants ?? [],
|
|
1041
1049
|
rolePermissions: u?.rolePermissions ?? []
|
|
1042
|
-
}, w =
|
|
1050
|
+
}, w = P({ accessControl: {
|
|
1043
1051
|
controlPlaneTenantId: r,
|
|
1044
1052
|
requireOrganizationMatch: c,
|
|
1045
1053
|
defaultPermissions: s
|
|
@@ -1068,7 +1076,7 @@ function ke(e) {
|
|
|
1068
1076
|
router: T
|
|
1069
1077
|
}]
|
|
1070
1078
|
});
|
|
1071
|
-
return E.use("/api/v2/*",
|
|
1079
|
+
return E.use("/api/v2/*", Ee(r)), y && E.use("/api/v2/*", U()), {
|
|
1072
1080
|
app: E,
|
|
1073
1081
|
controlPlaneTenantId: r
|
|
1074
1082
|
};
|
|
@@ -1091,7 +1099,7 @@ function Y() {
|
|
|
1091
1099
|
errors: []
|
|
1092
1100
|
};
|
|
1093
1101
|
}
|
|
1094
|
-
function
|
|
1102
|
+
function je(e) {
|
|
1095
1103
|
return {
|
|
1096
1104
|
tenantId: e,
|
|
1097
1105
|
connections: Y(),
|
|
@@ -1102,7 +1110,7 @@ function Ae(e) {
|
|
|
1102
1110
|
promptSettings: Y()
|
|
1103
1111
|
};
|
|
1104
1112
|
}
|
|
1105
|
-
function
|
|
1113
|
+
function Me(e) {
|
|
1106
1114
|
let t = e.metadata;
|
|
1107
1115
|
return !!(t && t.inheritable === !0);
|
|
1108
1116
|
}
|
|
@@ -1115,7 +1123,7 @@ async function X(e, t, n, r) {
|
|
|
1115
1123
|
e.errors.push(i);
|
|
1116
1124
|
}
|
|
1117
1125
|
}
|
|
1118
|
-
async function
|
|
1126
|
+
async function Ne(e, t, n) {
|
|
1119
1127
|
return {
|
|
1120
1128
|
connections: n.connections ? await d((n) => e.connections.list(t, n), "connections", {
|
|
1121
1129
|
cursorField: "id",
|
|
@@ -1134,7 +1142,7 @@ async function Me(e, t, n) {
|
|
|
1134
1142
|
promptSettings: n.promptSettings ? await e.promptSettings.get(t) ?? null : null
|
|
1135
1143
|
};
|
|
1136
1144
|
}
|
|
1137
|
-
async function
|
|
1145
|
+
async function Pe(e, t, n, r, i, o) {
|
|
1138
1146
|
if (r.connections) for (let r of e.connections) {
|
|
1139
1147
|
let e = r.id;
|
|
1140
1148
|
e && await X(o.connections, `connection ${e}`, i, async () => {
|
|
@@ -1146,7 +1154,7 @@ async function Ne(e, t, n, r, i, o) {
|
|
|
1146
1154
|
let e = v.parse(r);
|
|
1147
1155
|
await t.resourceServers.get(n, r.id) ? await t.resourceServers.update(n, r.id, e) : await t.resourceServers.create(n, e), o.resourceServers.upserted += 1;
|
|
1148
1156
|
});
|
|
1149
|
-
if (r.hooks) for (let r of e.hooks) !
|
|
1157
|
+
if (r.hooks) for (let r of e.hooks) !Me(r) || !r.hook_id || await X(o.hooks, `hook ${r.hook_id}`, i, async () => {
|
|
1150
1158
|
let e = f.parse(r);
|
|
1151
1159
|
await t.hooks.get(n, r.hook_id) ? await t.hooks.update(n, r.hook_id, e) : await t.hooks.create(n, e), o.hooks.upserted += 1;
|
|
1152
1160
|
});
|
|
@@ -1160,21 +1168,21 @@ async function Ne(e, t, n, r, i, o) {
|
|
|
1160
1168
|
});
|
|
1161
1169
|
}
|
|
1162
1170
|
async function Z(e, t) {
|
|
1163
|
-
let { controlPlaneTenantId: n, getControlPlaneAdapters: r, getAdapters: i, entities: a, continueOnError: o = !1 } = e, s = J(a), c = await
|
|
1164
|
-
return await
|
|
1171
|
+
let { controlPlaneTenantId: n, getControlPlaneAdapters: r, getAdapters: i, entities: a, continueOnError: o = !1 } = e, s = J(a), c = await Ne(await r(), n, s), l = await i(t), u = je(t);
|
|
1172
|
+
return await Pe(c, l, n, s, o, u), u;
|
|
1165
1173
|
}
|
|
1166
1174
|
//#endregion
|
|
1167
1175
|
//#region src/rollout/payload.ts
|
|
1168
|
-
function
|
|
1176
|
+
function Fe(e) {
|
|
1169
1177
|
let { pkcs7: t, tenant_id: n, ...r } = e;
|
|
1170
1178
|
return r;
|
|
1171
1179
|
}
|
|
1172
|
-
async function
|
|
1173
|
-
let i = J(n), a = n.signingKeys ?? !0, o = n.tenants ?? !0, s = await
|
|
1180
|
+
async function Ie(e, t, n = {}, r) {
|
|
1181
|
+
let i = J(n), a = n.signingKeys ?? !0, o = n.tenants ?? !0, s = await Ne(e, t, i), c = a ? (await h(e.keys)).map(Fe) : [], l = o ? await Le(e, t, r) : [];
|
|
1174
1182
|
return {
|
|
1175
1183
|
connections: s.connections,
|
|
1176
1184
|
resourceServers: s.resourceServers.filter((e) => e.is_system),
|
|
1177
|
-
hooks: s.hooks.filter(
|
|
1185
|
+
hooks: s.hooks.filter(Me),
|
|
1178
1186
|
emailProvider: s.emailProvider,
|
|
1179
1187
|
branding: s.branding,
|
|
1180
1188
|
promptSettings: s.promptSettings,
|
|
@@ -1182,7 +1190,7 @@ async function Fe(e, t, n = {}, r) {
|
|
|
1182
1190
|
tenants: l
|
|
1183
1191
|
};
|
|
1184
1192
|
}
|
|
1185
|
-
async function
|
|
1193
|
+
async function Le(e, t, n) {
|
|
1186
1194
|
let r = n && n !== t ? [t, n] : [t], i = [];
|
|
1187
1195
|
for (let t of r) {
|
|
1188
1196
|
let n = await e.tenants.get(t);
|
|
@@ -1193,17 +1201,17 @@ async function Ie(e, t, n) {
|
|
|
1193
1201
|
}
|
|
1194
1202
|
return i;
|
|
1195
1203
|
}
|
|
1196
|
-
async function
|
|
1204
|
+
async function Re(e, t, n) {
|
|
1197
1205
|
let r = Y();
|
|
1198
1206
|
if (e.length === 0) return r;
|
|
1199
1207
|
let i = await h(t.keys), a = new Set(i.map((e) => e.kid));
|
|
1200
1208
|
for (let i of e) await X(r, `signing_key ${i.kid}`, n, async () => {
|
|
1201
|
-
let e =
|
|
1209
|
+
let e = Fe(i);
|
|
1202
1210
|
a.has(e.kid) || (await t.keys.create(e), a.add(e.kid), r.upserted += 1);
|
|
1203
1211
|
});
|
|
1204
1212
|
return r;
|
|
1205
1213
|
}
|
|
1206
|
-
async function
|
|
1214
|
+
async function ze(e, t, n) {
|
|
1207
1215
|
let r = Y();
|
|
1208
1216
|
for (let i of e) await X(r, `tenant ${i.id}`, n, async () => {
|
|
1209
1217
|
await t.tenants.get(i.id) || (await t.tenants.create({
|
|
@@ -1213,7 +1221,7 @@ async function Re(e, t, n) {
|
|
|
1213
1221
|
});
|
|
1214
1222
|
return r;
|
|
1215
1223
|
}
|
|
1216
|
-
async function
|
|
1224
|
+
async function Be(e, t, n, r = {}) {
|
|
1217
1225
|
let a = r.continueOnError ?? !1, o = J(r.entities), s = r.entities?.signingKeys ?? !0, c = r.entities?.tenants ?? !0, u = {
|
|
1218
1226
|
connections: e.connections,
|
|
1219
1227
|
resourceServers: e.resourceServers,
|
|
@@ -1221,9 +1229,9 @@ async function ze(e, t, n, r = {}) {
|
|
|
1221
1229
|
emailProvider: e.emailProvider ? l.parse(e.emailProvider) : null,
|
|
1222
1230
|
branding: e.branding ? i.parse(e.branding) : null,
|
|
1223
1231
|
promptSettings: e.promptSettings ? g.parse(e.promptSettings) : null
|
|
1224
|
-
}, d = c ? await
|
|
1225
|
-
await
|
|
1226
|
-
let p = s ? await
|
|
1232
|
+
}, d = c ? await ze(e.tenants ?? [], t, a) : Y(), f = je(n);
|
|
1233
|
+
await Pe(u, t, n, o, a, f);
|
|
1234
|
+
let p = s ? await Re(e.signingKeys, t, a) : Y();
|
|
1227
1235
|
return {
|
|
1228
1236
|
...f,
|
|
1229
1237
|
signingKeys: p,
|
|
@@ -1232,7 +1240,7 @@ async function ze(e, t, n, r = {}) {
|
|
|
1232
1240
|
}
|
|
1233
1241
|
//#endregion
|
|
1234
1242
|
//#region src/rollout/index.ts
|
|
1235
|
-
function
|
|
1243
|
+
function Ve(e) {
|
|
1236
1244
|
return {
|
|
1237
1245
|
syncDefaults: (t) => Z(e, t),
|
|
1238
1246
|
syncDefaultsToTenants: async (t) => {
|
|
@@ -1244,7 +1252,7 @@ function Be(e) {
|
|
|
1244
1252
|
}
|
|
1245
1253
|
//#endregion
|
|
1246
1254
|
//#region src/plugin.ts
|
|
1247
|
-
function
|
|
1255
|
+
function He(e) {
|
|
1248
1256
|
let t = Q(e);
|
|
1249
1257
|
return {
|
|
1250
1258
|
name: "multi-tenancy",
|
|
@@ -1262,7 +1270,7 @@ function Ve(e) {
|
|
|
1262
1270
|
//#endregion
|
|
1263
1271
|
//#region src/index.ts
|
|
1264
1272
|
function Q(e) {
|
|
1265
|
-
let t = e.accessControl ? T(e.accessControl) : {}, n = e.databaseIsolation ? D(e.databaseIsolation) : {}, r =
|
|
1273
|
+
let t = e.accessControl ? T(e.accessControl) : {}, n = e.databaseIsolation ? D(e.databaseIsolation) : {}, r = P(e);
|
|
1266
1274
|
return {
|
|
1267
1275
|
...t,
|
|
1268
1276
|
...n,
|
|
@@ -1273,7 +1281,7 @@ function $(t) {
|
|
|
1273
1281
|
let n = new e(), r = Q(t);
|
|
1274
1282
|
return n.route("/tenants", H(t, r)), n;
|
|
1275
1283
|
}
|
|
1276
|
-
function
|
|
1284
|
+
function Ue(e) {
|
|
1277
1285
|
return {
|
|
1278
1286
|
hooks: Q(e),
|
|
1279
1287
|
middleware: q(e),
|
|
@@ -1286,4 +1294,4 @@ function He(e) {
|
|
|
1286
1294
|
};
|
|
1287
1295
|
}
|
|
1288
1296
|
//#endregion
|
|
1289
|
-
export {
|
|
1297
|
+
export { Be as applyControlPlaneDefaultsPayload, Ie as buildControlPlaneDefaultsPayload, A as buildEngineInstanceId, T as createAccessControlHooks, De as createAccessControlMiddleware, Ee as createControlPlaneTenantMiddleware, D as createDatabaseHooks, ke as createDatabaseMiddleware, Ve as createDirectRolloutAdapter, ne as createInlineExecutor, $ as createMultiTenancy, Q as createMultiTenancyHooks, q as createMultiTenancyMiddleware, He as createMultiTenancyPlugin, M as createOperationRecorder, U as createProtectSyncedMiddleware, P as createProvisioningHooks, Ce as createRuntimeFallbackAdapter, Oe as createSubdomainMiddleware, B as createSyncHooks, H as createTenantsOpenAPIRouter, ie as enqueueTenantOperation, j as errorToMessage, Ae as initMultiTenant, te as inlineStepRunner, N as isTerminalStatus, ye as mergeClientWithFallback, Z as projectControlPlaneDefaults, oe as runRecordedTenantOperation, Ue as setupMultiTenancy, E as validateTenantAccess, K as withRuntimeFallback, Se as withSystemResourceServerInheritance };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/middleware/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,MAAM,CAAC;AAGzC,OAAO,EACL,oBAAoB,EACpB,qBAAqB,EACrB,kBAAkB,EACnB,MAAM,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/middleware/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,MAAM,CAAC;AAGzC,OAAO,EACL,oBAAoB,EACpB,qBAAqB,EACrB,kBAAkB,EACnB,MAAM,UAAU,CAAC;AAIlB;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,kCAAkC,CAChD,oBAAoB,EAAE,MAAM,GAC3B,iBAAiB,CAAC;IACnB,QAAQ,EAAE,oBAAoB,CAAC;IAC/B,SAAS,EAAE,qBAAqB,CAAC;CAClC,CAAC,CAUD;AAED;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,6BAA6B,CAC3C,MAAM,EAAE,kBAAkB,GACzB,iBAAiB,CAAC;IACnB,QAAQ,EAAE,oBAAoB,CAAC;IAC/B,SAAS,EAAE,qBAAqB,CAAC;CAClC,CAAC,CAsDD;AAED;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAgB,yBAAyB,CACvC,MAAM,EAAE,kBAAkB,GACzB,iBAAiB,CAAC;IACnB,QAAQ,EAAE,oBAAoB,CAAC;IAC/B,SAAS,EAAE,qBAAqB,CAAC;CAClC,CAAC,CAsED;AAED;;;;;;;;GAQG;AACH,wBAAgB,wBAAwB,CACtC,MAAM,EAAE,kBAAkB,GACzB,iBAAiB,CAAC;IACnB,QAAQ,EAAE,oBAAoB,CAAC;IAC/B,SAAS,EAAE,qBAAqB,CAAC;CAClC,CAAC,CAiCD;AAED;;;;;;;;GAQG;AACH,wBAAgB,4BAA4B,CAC1C,MAAM,EAAE,kBAAkB,GACzB,iBAAiB,CAAC;IACnB,QAAQ,EAAE,oBAAoB,CAAC;IAC/B,SAAS,EAAE,qBAAqB,CAAC;CAClC,CAAC,CAiBD;AAGD,OAAO,EAAE,6BAA6B,EAAE,MAAM,kBAAkB,CAAC;AAGjE,OAAO,EACL,4BAA4B,EAC5B,mBAAmB,EACnB,mCAAmC,EACnC,uBAAuB,GACxB,MAAM,wBAAwB,CAAC;AAChC,YAAY,EACV,qBAAqB,EACrB,oBAAoB,GACrB,MAAM,wBAAwB,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"protect-synced.d.ts","sourceRoot":"","sources":["../../../src/middleware/protect-synced.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,MAAM,CAAC;AAEzC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"protect-synced.d.ts","sourceRoot":"","sources":["../../../src/middleware/protect-synced.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,MAAM,CAAC;AAEzC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAG7C;;GAEG;AACH,UAAU,qBAAqB;IAC7B,IAAI,EAAE,YAAY,CAAC;CACpB;AAED;;GAEG;AACH,UAAU,sBAAsB;IAC9B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,IAAI,CAAC,EAAE,YAAY,CAAC;CACrB;AA4FD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,6BAA6B,IAAI,iBAAiB,CAAC;IACjE,QAAQ,EAAE,qBAAqB,CAAC;IAChC,SAAS,EAAE,sBAAsB,CAAC;CACnC,CAAC,CAmCD"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { DataAdapters } from "authhero";
|
|
2
|
+
/**
|
|
3
|
+
* The request's adapter stack. Behind authhero (or the database isolation
|
|
4
|
+
* middleware) that is `ctx.var.data`; a router mounted standalone, outside
|
|
5
|
+
* authhero, only has the `data` binding on `ctx.env`.
|
|
6
|
+
*/
|
|
7
|
+
export declare function getRequestData(ctx: {
|
|
8
|
+
var: {
|
|
9
|
+
data?: DataAdapters;
|
|
10
|
+
};
|
|
11
|
+
env: {
|
|
12
|
+
data: DataAdapters;
|
|
13
|
+
};
|
|
14
|
+
}): DataAdapters;
|
|
15
|
+
//# sourceMappingURL=request-data.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"request-data.d.ts","sourceRoot":"","sources":["../../../src/middleware/request-data.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAE7C;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE;IAClC,GAAG,EAAE;QAAE,IAAI,CAAC,EAAE,YAAY,CAAA;KAAE,CAAC;IAC7B,GAAG,EAAE;QAAE,IAAI,EAAE,YAAY,CAAA;KAAE,CAAC;CAC7B,GAAG,YAAY,CAEf"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tenants.d.ts","sourceRoot":"","sources":["../../../src/routes/tenants.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAkB,MAAM,mBAAmB,CAAC;AAWhE,OAAO,EACL,oBAAoB,EACpB,qBAAqB,EACrB,kBAAkB,EAClB,iBAAiB,EAElB,MAAM,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"tenants.d.ts","sourceRoot":"","sources":["../../../src/routes/tenants.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAkB,MAAM,mBAAmB,CAAC;AAWhE,OAAO,EACL,oBAAoB,EACpB,qBAAqB,EACrB,kBAAkB,EAClB,iBAAiB,EAElB,MAAM,UAAU,CAAC;AAyClB;;;;;;;;;;GAUG;AACH,wBAAgB,0BAA0B,CACxC,MAAM,EAAE,kBAAkB,EAC1B,KAAK,EAAE,iBAAiB;cAGZ,oBAAoB;eACnB,qBAAqB;YA0hBnC"}
|
package/dist/types/types.d.ts
CHANGED
|
@@ -12,6 +12,13 @@ export interface MultiTenancyBindings {
|
|
|
12
12
|
* Variables type from authhero core - simplified version for this package
|
|
13
13
|
*/
|
|
14
14
|
export interface MultiTenancyVariables {
|
|
15
|
+
/** The request's adapter stack, set by authhero (see `getRequestData`). */
|
|
16
|
+
data?: DataAdapters;
|
|
17
|
+
/**
|
|
18
|
+
* Raw per-tenant adapter installed by `createDatabaseMiddleware`; authhero
|
|
19
|
+
* composes its per-request stack on top of it.
|
|
20
|
+
*/
|
|
21
|
+
baseData?: DataAdapters;
|
|
15
22
|
tenant_id: string;
|
|
16
23
|
organization_id?: string;
|
|
17
24
|
org_name?: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
"type": "git",
|
|
12
12
|
"url": "https://github.com/markusahlstrand/authhero"
|
|
13
13
|
},
|
|
14
|
-
"version": "15.0
|
|
14
|
+
"version": "15.1.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"
|
|
@@ -36,9 +36,9 @@
|
|
|
36
36
|
"typescript": "^5.6.0",
|
|
37
37
|
"vite": "^8.0.14",
|
|
38
38
|
"vitest": "^4.1.7",
|
|
39
|
-
"@authhero/
|
|
40
|
-
"authhero": "
|
|
41
|
-
"
|
|
39
|
+
"@authhero/adapter-interfaces": "4.19.0",
|
|
40
|
+
"@authhero/kysely-adapter": "12.13.0",
|
|
41
|
+
"authhero": "9.21.0"
|
|
42
42
|
},
|
|
43
43
|
"dependencies": {
|
|
44
44
|
"zod": "^4.4.3"
|