@authhero/multi-tenancy 14.2.0 → 14.4.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.
Files changed (38) hide show
  1. package/dist/multi-tenancy.cjs +1 -1
  2. package/dist/multi-tenancy.mjs +429 -426
  3. package/dist/types/hooks/access-control.d.ts +25 -0
  4. package/dist/types/hooks/access-control.d.ts.map +1 -0
  5. package/dist/types/hooks/database.d.ts +35 -0
  6. package/dist/types/hooks/database.d.ts.map +1 -0
  7. package/dist/types/hooks/index.d.ts +5 -0
  8. package/dist/types/hooks/index.d.ts.map +1 -0
  9. package/dist/types/hooks/provisioning.d.ts +15 -0
  10. package/dist/types/hooks/provisioning.d.ts.map +1 -0
  11. package/dist/types/hooks/resource-server-sync.d.ts +140 -0
  12. package/dist/types/hooks/resource-server-sync.d.ts.map +1 -0
  13. package/dist/types/hooks/role-sync.d.ts +145 -0
  14. package/dist/types/hooks/role-sync.d.ts.map +1 -0
  15. package/dist/types/hooks/sync.d.ts +54 -0
  16. package/dist/types/hooks/sync.d.ts.map +1 -0
  17. package/dist/types/index.d.ts +117 -0
  18. package/dist/types/index.d.ts.map +1 -0
  19. package/dist/types/init.d.ts +110 -0
  20. package/dist/types/init.d.ts.map +1 -0
  21. package/dist/types/middleware/index.d.ts +114 -0
  22. package/dist/types/middleware/index.d.ts.map +1 -0
  23. package/dist/types/middleware/protect-synced.d.ts +40 -0
  24. package/dist/types/middleware/protect-synced.d.ts.map +1 -0
  25. package/dist/types/middleware/settings-inheritance.d.ts +89 -0
  26. package/dist/types/middleware/settings-inheritance.d.ts.map +1 -0
  27. package/dist/types/plugin.d.ts +66 -0
  28. package/dist/types/plugin.d.ts.map +1 -0
  29. package/dist/types/routes/index.d.ts +2 -0
  30. package/dist/types/routes/index.d.ts.map +1 -0
  31. package/dist/types/routes/tenants.d.ts +18 -0
  32. package/dist/types/routes/tenants.d.ts.map +1 -0
  33. package/dist/types/types.d.ts +295 -0
  34. package/dist/types/types.d.ts.map +1 -0
  35. package/dist/types/utils/index.d.ts +3 -0
  36. package/dist/types/utils/index.d.ts.map +1 -0
  37. package/package.json +9 -9
  38. package/dist/multi-tenancy.d.ts +0 -41331
@@ -0,0 +1,25 @@
1
+ import { AccessControlConfig, MultiTenancyHooks } from "../types";
2
+ /**
3
+ * Creates hooks for organization-based tenant access control.
4
+ *
5
+ * This implements the following access model:
6
+ * - Control plane: Accessible without an organization claim
7
+ * - Child tenants: Require an organization claim matching the tenant ID
8
+ * - org_name (organization name) takes precedence and should match tenant ID
9
+ * - org_id (organization ID) is checked as fallback
10
+ *
11
+ * @param config - Access control configuration
12
+ * @returns Hooks for access validation
13
+ */
14
+ export declare function createAccessControlHooks(config: AccessControlConfig): Pick<MultiTenancyHooks, "onTenantAccessValidation">;
15
+ /**
16
+ * Validates that a token can access a specific tenant based on its organization claim.
17
+ *
18
+ * @param organizationId - The organization ID from the token (may be undefined)
19
+ * @param orgName - The organization name from the token (may be undefined, takes precedence)
20
+ * @param targetTenantId - The tenant ID being accessed
21
+ * @param controlPlaneTenantId - The control plane/management tenant ID
22
+ * @returns true if access is allowed
23
+ */
24
+ export declare function validateTenantAccess(organizationId: string | undefined, targetTenantId: string, controlPlaneTenantId: string, orgName?: string): boolean;
25
+ //# sourceMappingURL=access-control.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"access-control.d.ts","sourceRoot":"","sources":["../../../src/hooks/access-control.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,mBAAmB,EAEnB,iBAAiB,EAClB,MAAM,UAAU,CAAC;AAElB;;;;;;;;;;;GAWG;AACH,wBAAgB,wBAAwB,CACtC,MAAM,EAAE,mBAAmB,GAC1B,IAAI,CAAC,iBAAiB,EAAE,0BAA0B,CAAC,CAuCrD;AAED;;;;;;;;GAQG;AACH,wBAAgB,oBAAoB,CAClC,cAAc,EAAE,MAAM,GAAG,SAAS,EAClC,cAAc,EAAE,MAAM,EACtB,oBAAoB,EAAE,MAAM,EAC5B,OAAO,CAAC,EAAE,MAAM,GACf,OAAO,CAiBT"}
@@ -0,0 +1,35 @@
1
+ import { DataAdapters } from "authhero";
2
+ import { DatabaseIsolationConfig, MultiTenancyHooks } from "../types";
3
+ /**
4
+ * Creates hooks for per-tenant database resolution.
5
+ *
6
+ * This enables scenarios where each tenant has its own database instance,
7
+ * providing complete data isolation.
8
+ *
9
+ * @param config - Database isolation configuration
10
+ * @returns Hooks for database resolution
11
+ */
12
+ export declare function createDatabaseHooks(config: DatabaseIsolationConfig): Pick<MultiTenancyHooks, "resolveDataAdapters">;
13
+ /**
14
+ * Database factory interface for creating tenant-specific database adapters.
15
+ *
16
+ * Implementations of this interface should live in the respective adapter packages:
17
+ * - D1: @authhero/cloudflare
18
+ * - Turso: @authhero/turso (or similar)
19
+ * - Custom: Implement your own
20
+ */
21
+ export interface DatabaseFactory {
22
+ /**
23
+ * Get or create a database adapter for a tenant.
24
+ */
25
+ getAdapters(tenantId: string): Promise<DataAdapters>;
26
+ /**
27
+ * Provision a new database for a tenant.
28
+ */
29
+ provision(tenantId: string): Promise<void>;
30
+ /**
31
+ * Deprovision (delete) a tenant's database.
32
+ */
33
+ deprovision(tenantId: string): Promise<void>;
34
+ }
35
+ //# sourceMappingURL=database.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"database.d.ts","sourceRoot":"","sources":["../../../src/hooks/database.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AACxC,OAAO,EAAE,uBAAuB,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAEtE;;;;;;;;GAQG;AACH,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,uBAAuB,GAC9B,IAAI,CAAC,iBAAiB,EAAE,qBAAqB,CAAC,CAgBhD;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,eAAe;IAC9B;;OAEG;IACH,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC;IAErD;;OAEG;IACH,SAAS,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAE3C;;OAEG;IACH,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC9C"}
@@ -0,0 +1,5 @@
1
+ export { createAccessControlHooks, validateTenantAccess, } from "./access-control";
2
+ export { createDatabaseHooks, type DatabaseFactory } from "./database";
3
+ export { createProvisioningHooks } from "./provisioning";
4
+ export { createSyncHooks, type EntitySyncConfig, type SyncHooksResult, } from "./sync";
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/hooks/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,wBAAwB,EACxB,oBAAoB,GACrB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,mBAAmB,EAAE,KAAK,eAAe,EAAE,MAAM,YAAY,CAAC;AACvE,OAAO,EAAE,uBAAuB,EAAE,MAAM,gBAAgB,CAAC;AACzD,OAAO,EACL,eAAe,EACf,KAAK,gBAAgB,EACrB,KAAK,eAAe,GACrB,MAAM,QAAQ,CAAC"}
@@ -0,0 +1,15 @@
1
+ import { MultiTenancyConfig, TenantEntityHooks } from "../types";
2
+ /**
3
+ * Creates hooks for tenant provisioning and deprovisioning.
4
+ *
5
+ * This handles:
6
+ * - Setting the correct audience for new tenants (urn:authhero:tenant:{id})
7
+ * - Creating organizations on the control plane when a new tenant is created
8
+ * - Provisioning databases for new tenants
9
+ * - Cleaning up organizations and databases when tenants are deleted
10
+ *
11
+ * @param config - Multi-tenancy configuration
12
+ * @returns Tenant entity hooks for lifecycle events
13
+ */
14
+ export declare function createProvisioningHooks(config: MultiTenancyConfig): TenantEntityHooks;
15
+ //# sourceMappingURL=provisioning.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"provisioning.d.ts","sourceRoot":"","sources":["../../../src/hooks/provisioning.ts"],"names":[],"mappings":"AAeA,OAAO,EACL,kBAAkB,EAClB,iBAAiB,EAElB,MAAM,UAAU,CAAC;AAElB;;;;;;;;;;;GAWG;AACH,wBAAgB,uBAAuB,CACrC,MAAM,EAAE,kBAAkB,GACzB,iBAAiB,CAyEnB"}
@@ -0,0 +1,140 @@
1
+ import { DataAdapters, ResourceServer, ResourceServerInsert } from "authhero";
2
+ import { TenantEntityHooks } from "../types";
3
+ /**
4
+ * Configuration for resource server synchronization
5
+ */
6
+ export interface ResourceServerSyncConfig {
7
+ /**
8
+ * The control plane tenant ID from which resource servers are synced
9
+ */
10
+ controlPlaneTenantId: string;
11
+ /**
12
+ * Function to get the list of all tenant IDs to sync to.
13
+ * Called when a resource server is created/updated/deleted on the control plane.
14
+ */
15
+ getChildTenantIds: () => Promise<string[]>;
16
+ /**
17
+ * Function to get adapters for a specific tenant.
18
+ * Used to write resource servers to child tenants.
19
+ */
20
+ getAdapters: (tenantId: string) => Promise<DataAdapters>;
21
+ /**
22
+ * Optional: Filter function to determine if a resource server should be synced.
23
+ * Return true to sync, false to skip.
24
+ * @default All resource servers are synced
25
+ */
26
+ shouldSync?: (resourceServer: ResourceServer) => boolean;
27
+ /**
28
+ * Optional: Transform the resource server before syncing to child tenants.
29
+ * Useful for modifying identifiers or removing sensitive data.
30
+ */
31
+ transformForSync?: (resourceServer: ResourceServer, targetTenantId: string) => ResourceServerInsert;
32
+ }
33
+ /**
34
+ * Context passed to entity hooks
35
+ */
36
+ interface EntityHookContext {
37
+ tenantId: string;
38
+ adapters: DataAdapters;
39
+ }
40
+ /**
41
+ * Entity hooks for resource server CRUD operations
42
+ */
43
+ export interface ResourceServerEntityHooks {
44
+ afterCreate?: (ctx: EntityHookContext, entity: ResourceServer) => Promise<void>;
45
+ afterUpdate?: (ctx: EntityHookContext, id: string, entity: ResourceServer) => Promise<void>;
46
+ afterDelete?: (ctx: EntityHookContext, id: string) => Promise<void>;
47
+ }
48
+ /**
49
+ * Creates entity hooks for syncing resource servers from the control plane to all child tenants.
50
+ *
51
+ * When a resource server is created, updated, or deleted on the control plane,
52
+ * the change is automatically propagated to all child tenants.
53
+ *
54
+ * @param config - Resource server sync configuration
55
+ * @returns Entity hooks for resource server synchronization
56
+ *
57
+ * @example
58
+ * ```typescript
59
+ * import { createResourceServerSyncHooks } from "@authhero/multi-tenancy";
60
+ *
61
+ * const resourceServerHooks = createResourceServerSyncHooks({
62
+ * controlPlaneTenantId: "main",
63
+ * getChildTenantIds: async () => {
64
+ * const tenants = await db.tenants.list();
65
+ * return tenants.filter(t => t.id !== "main").map(t => t.id);
66
+ * },
67
+ * getAdapters: async (tenantId) => {
68
+ * return createAdaptersForTenant(tenantId);
69
+ * },
70
+ * });
71
+ *
72
+ * // Use with AuthHero config
73
+ * const config: AuthHeroConfig = {
74
+ * dataAdapter,
75
+ * entityHooks: {
76
+ * resourceServers: resourceServerHooks,
77
+ * },
78
+ * };
79
+ * ```
80
+ */
81
+ export declare function createResourceServerSyncHooks(config: ResourceServerSyncConfig): ResourceServerEntityHooks;
82
+ /**
83
+ * Configuration for syncing resource servers to new tenants
84
+ */
85
+ export interface TenantResourceServerSyncConfig {
86
+ /**
87
+ * The control plane tenant ID from which resource servers are copied
88
+ */
89
+ controlPlaneTenantId: string;
90
+ /**
91
+ * Function to get adapters for the control plane.
92
+ * Used to read existing resource servers.
93
+ */
94
+ getControlPlaneAdapters: () => Promise<DataAdapters>;
95
+ /**
96
+ * Function to get adapters for the new tenant.
97
+ * Used to write resource servers to the new tenant.
98
+ */
99
+ getAdapters: (tenantId: string) => Promise<DataAdapters>;
100
+ /**
101
+ * Optional: Filter function to determine if a resource server should be synced.
102
+ * Return true to sync, false to skip.
103
+ * @default All resource servers are synced
104
+ */
105
+ shouldSync?: (resourceServer: ResourceServer) => boolean;
106
+ /**
107
+ * Optional: Transform the resource server before syncing to the new tenant.
108
+ * Useful for modifying identifiers or removing sensitive data.
109
+ */
110
+ transformForSync?: (resourceServer: ResourceServer, targetTenantId: string) => ResourceServerInsert;
111
+ }
112
+ /**
113
+ * Creates a tenant afterCreate hook that copies all resource servers from the control plane
114
+ * to a newly created tenant.
115
+ *
116
+ * This should be used with the MultiTenancyHooks.tenants.afterCreate hook.
117
+ *
118
+ * @param config - Configuration for tenant resource server sync
119
+ * @returns A TenantEntityHooks object with afterCreate implemented
120
+ *
121
+ * @example
122
+ * ```typescript
123
+ * import { createTenantResourceServerSyncHooks } from "@authhero/multi-tenancy";
124
+ *
125
+ * const resourceServerSyncHooks = createTenantResourceServerSyncHooks({
126
+ * controlPlaneTenantId: "main",
127
+ * getControlPlaneAdapters: async () => controlPlaneAdapters,
128
+ * getAdapters: async (tenantId) => createAdaptersForTenant(tenantId),
129
+ * });
130
+ *
131
+ * const multiTenancyHooks: MultiTenancyHooks = {
132
+ * tenants: {
133
+ * afterCreate: resourceServerSyncHooks.afterCreate,
134
+ * },
135
+ * };
136
+ * ```
137
+ */
138
+ export declare function createTenantResourceServerSyncHooks(config: TenantResourceServerSyncConfig): TenantEntityHooks;
139
+ export {};
140
+ //# sourceMappingURL=resource-server-sync.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resource-server-sync.d.ts","sourceRoot":"","sources":["../../../src/hooks/resource-server-sync.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,YAAY,EACZ,cAAc,EACd,oBAAoB,EAErB,MAAM,UAAU,CAAC;AAClB,OAAO,EAAE,iBAAiB,EAAqB,MAAM,UAAU,CAAC;AAEhE;;GAEG;AACH,MAAM,WAAW,wBAAwB;IACvC;;OAEG;IACH,oBAAoB,EAAE,MAAM,CAAC;IAE7B;;;OAGG;IACH,iBAAiB,EAAE,MAAM,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IAE3C;;;OAGG;IACH,WAAW,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,YAAY,CAAC,CAAC;IAEzD;;;;OAIG;IACH,UAAU,CAAC,EAAE,CAAC,cAAc,EAAE,cAAc,KAAK,OAAO,CAAC;IAEzD;;;OAGG;IACH,gBAAgB,CAAC,EAAE,CACjB,cAAc,EAAE,cAAc,EAC9B,cAAc,EAAE,MAAM,KACnB,oBAAoB,CAAC;CAC3B;AAED;;GAEG;AACH,UAAU,iBAAiB;IACzB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,YAAY,CAAC;CACxB;AAED;;GAEG;AACH,MAAM,WAAW,yBAAyB;IACxC,WAAW,CAAC,EAAE,CACZ,GAAG,EAAE,iBAAiB,EACtB,MAAM,EAAE,cAAc,KACnB,OAAO,CAAC,IAAI,CAAC,CAAC;IACnB,WAAW,CAAC,EAAE,CACZ,GAAG,EAAE,iBAAiB,EACtB,EAAE,EAAE,MAAM,EACV,MAAM,EAAE,cAAc,KACnB,OAAO,CAAC,IAAI,CAAC,CAAC;IACnB,WAAW,CAAC,EAAE,CAAC,GAAG,EAAE,iBAAiB,EAAE,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CACrE;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,wBAAgB,6BAA6B,CAC3C,MAAM,EAAE,wBAAwB,GAC/B,yBAAyB,CA2L3B;AAED;;GAEG;AACH,MAAM,WAAW,8BAA8B;IAC7C;;OAEG;IACH,oBAAoB,EAAE,MAAM,CAAC;IAE7B;;;OAGG;IACH,uBAAuB,EAAE,MAAM,OAAO,CAAC,YAAY,CAAC,CAAC;IAErD;;;OAGG;IACH,WAAW,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,YAAY,CAAC,CAAC;IAEzD;;;;OAIG;IACH,UAAU,CAAC,EAAE,CAAC,cAAc,EAAE,cAAc,KAAK,OAAO,CAAC;IAEzD;;;OAGG;IACH,gBAAgB,CAAC,EAAE,CACjB,cAAc,EAAE,cAAc,EAC9B,cAAc,EAAE,MAAM,KACnB,oBAAoB,CAAC;CAC3B;AAED;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAgB,mCAAmC,CACjD,MAAM,EAAE,8BAA8B,GACrC,iBAAiB,CAiFnB"}
@@ -0,0 +1,145 @@
1
+ import { DataAdapters, Role, RoleInsert } from "authhero";
2
+ import { TenantEntityHooks } from "../types";
3
+ /**
4
+ * Configuration for role synchronization
5
+ */
6
+ export interface RoleSyncConfig {
7
+ /**
8
+ * The control plane tenant ID from which roles are synced
9
+ */
10
+ controlPlaneTenantId: string;
11
+ /**
12
+ * Function to get the list of all tenant IDs to sync to.
13
+ * Called when a role is created/updated/deleted on the control plane.
14
+ */
15
+ getChildTenantIds: () => Promise<string[]>;
16
+ /**
17
+ * Function to get adapters for a specific tenant.
18
+ * Used to write roles to child tenants.
19
+ */
20
+ getAdapters: (tenantId: string) => Promise<DataAdapters>;
21
+ /**
22
+ * Optional: Filter function to determine if a role should be synced.
23
+ * Return true to sync, false to skip.
24
+ * @default All roles are synced
25
+ */
26
+ shouldSync?: (role: Role) => boolean;
27
+ /**
28
+ * Optional: Transform the role before syncing to child tenants.
29
+ * Useful for modifying names or removing sensitive data.
30
+ */
31
+ transformForSync?: (role: Role, targetTenantId: string) => RoleInsert;
32
+ }
33
+ /**
34
+ * Context passed to entity hooks
35
+ */
36
+ interface EntityHookContext {
37
+ tenantId: string;
38
+ adapters: DataAdapters;
39
+ }
40
+ /**
41
+ * Entity hooks for role CRUD operations
42
+ */
43
+ export interface RoleEntityHooks {
44
+ afterCreate?: (ctx: EntityHookContext, entity: Role) => Promise<void>;
45
+ afterUpdate?: (ctx: EntityHookContext, id: string, entity: Role) => Promise<void>;
46
+ afterDelete?: (ctx: EntityHookContext, id: string) => Promise<void>;
47
+ }
48
+ /**
49
+ * Creates entity hooks for syncing roles from the control plane to all child tenants.
50
+ *
51
+ * When a role is created, updated, or deleted on the control plane,
52
+ * the change is automatically propagated to all child tenants.
53
+ *
54
+ * @param config - Role sync configuration
55
+ * @returns Entity hooks for role synchronization
56
+ *
57
+ * @example
58
+ * ```typescript
59
+ * import { createRoleSyncHooks } from "@authhero/multi-tenancy";
60
+ *
61
+ * const roleHooks = createRoleSyncHooks({
62
+ * controlPlaneTenantId: "main",
63
+ * getChildTenantIds: async () => {
64
+ * const tenants = await db.tenants.list();
65
+ * return tenants.filter(t => t.id !== "main").map(t => t.id);
66
+ * },
67
+ * getAdapters: async (tenantId) => {
68
+ * return createAdaptersForTenant(tenantId);
69
+ * },
70
+ * });
71
+ *
72
+ * // Use with AuthHero config
73
+ * const config: AuthHeroConfig = {
74
+ * dataAdapter,
75
+ * entityHooks: {
76
+ * roles: roleHooks,
77
+ * },
78
+ * };
79
+ * ```
80
+ */
81
+ export declare function createRoleSyncHooks(config: RoleSyncConfig): RoleEntityHooks;
82
+ /**
83
+ * Configuration for syncing roles to new tenants
84
+ */
85
+ export interface TenantRoleSyncConfig {
86
+ /**
87
+ * The control plane tenant ID from which roles are copied
88
+ */
89
+ controlPlaneTenantId: string;
90
+ /**
91
+ * Function to get adapters for the control plane.
92
+ * Used to read existing roles.
93
+ */
94
+ getControlPlaneAdapters: () => Promise<DataAdapters>;
95
+ /**
96
+ * Function to get adapters for the new tenant.
97
+ * Used to write roles to the new tenant.
98
+ */
99
+ getAdapters: (tenantId: string) => Promise<DataAdapters>;
100
+ /**
101
+ * Optional: Filter function to determine if a role should be synced.
102
+ * Return true to sync, false to skip.
103
+ * @default All roles are synced
104
+ */
105
+ shouldSync?: (role: Role) => boolean;
106
+ /**
107
+ * Optional: Transform the role before syncing to the new tenant.
108
+ * Useful for modifying names or removing sensitive data.
109
+ */
110
+ transformForSync?: (role: Role, targetTenantId: string) => RoleInsert;
111
+ /**
112
+ * Whether to also sync role permissions (scopes from resource servers).
113
+ * @default true
114
+ */
115
+ syncPermissions?: boolean;
116
+ }
117
+ /**
118
+ * Creates a tenant afterCreate hook that copies all roles from the control plane
119
+ * to a newly created tenant.
120
+ *
121
+ * This should be used with the MultiTenancyHooks.tenants.afterCreate hook.
122
+ *
123
+ * @param config - Configuration for tenant role sync
124
+ * @returns A TenantEntityHooks object with afterCreate implemented
125
+ *
126
+ * @example
127
+ * ```typescript
128
+ * import { createTenantRoleSyncHooks } from "@authhero/multi-tenancy";
129
+ *
130
+ * const roleSyncHooks = createTenantRoleSyncHooks({
131
+ * controlPlaneTenantId: "main",
132
+ * getControlPlaneAdapters: async () => controlPlaneAdapters,
133
+ * getAdapters: async (tenantId) => createAdaptersForTenant(tenantId),
134
+ * });
135
+ *
136
+ * const multiTenancyHooks: MultiTenancyHooks = {
137
+ * tenants: {
138
+ * afterCreate: roleSyncHooks.afterCreate,
139
+ * },
140
+ * };
141
+ * ```
142
+ */
143
+ export declare function createTenantRoleSyncHooks(config: TenantRoleSyncConfig): TenantEntityHooks;
144
+ export {};
145
+ //# sourceMappingURL=role-sync.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"role-sync.d.ts","sourceRoot":"","sources":["../../../src/hooks/role-sync.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,IAAI,EAAE,UAAU,EAAY,MAAM,UAAU,CAAC;AACpE,OAAO,EAAE,iBAAiB,EAAqB,MAAM,UAAU,CAAC;AAEhE;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B;;OAEG;IACH,oBAAoB,EAAE,MAAM,CAAC;IAE7B;;;OAGG;IACH,iBAAiB,EAAE,MAAM,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IAE3C;;;OAGG;IACH,WAAW,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,YAAY,CAAC,CAAC;IAEzD;;;;OAIG;IACH,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,OAAO,CAAC;IAErC;;;OAGG;IACH,gBAAgB,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,cAAc,EAAE,MAAM,KAAK,UAAU,CAAC;CACvE;AAED;;GAEG;AACH,UAAU,iBAAiB;IACzB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,YAAY,CAAC;CACxB;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,WAAW,CAAC,EAAE,CAAC,GAAG,EAAE,iBAAiB,EAAE,MAAM,EAAE,IAAI,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACtE,WAAW,CAAC,EAAE,CACZ,GAAG,EAAE,iBAAiB,EACtB,EAAE,EAAE,MAAM,EACV,MAAM,EAAE,IAAI,KACT,OAAO,CAAC,IAAI,CAAC,CAAC;IACnB,WAAW,CAAC,EAAE,CAAC,GAAG,EAAE,iBAAiB,EAAE,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CACrE;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,cAAc,GAAG,eAAe,CAwI3E;AAED;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC;;OAEG;IACH,oBAAoB,EAAE,MAAM,CAAC;IAE7B;;;OAGG;IACH,uBAAuB,EAAE,MAAM,OAAO,CAAC,YAAY,CAAC,CAAC;IAErD;;;OAGG;IACH,WAAW,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,YAAY,CAAC,CAAC;IAEzD;;;;OAIG;IACH,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,OAAO,CAAC;IAErC;;;OAGG;IACH,gBAAgB,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,cAAc,EAAE,MAAM,KAAK,UAAU,CAAC;IAEtE;;;OAGG;IACH,eAAe,CAAC,EAAE,OAAO,CAAC;CAC3B;AAED;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAgB,yBAAyB,CACvC,MAAM,EAAE,oBAAoB,GAC3B,iBAAiB,CA4GnB"}
@@ -0,0 +1,54 @@
1
+ import { DataAdapters, Role, RoleInsert, ResourceServer, ResourceServerInsert, EntityHooks } from "authhero";
2
+ import { TenantEntityHooks } from "../types";
3
+ /**
4
+ * Configuration for entity synchronization
5
+ */
6
+ export interface EntitySyncConfig {
7
+ /**
8
+ * The control plane tenant ID from which entities are synced
9
+ */
10
+ controlPlaneTenantId: string;
11
+ /**
12
+ * Function to get the list of all tenant IDs to sync to.
13
+ */
14
+ getChildTenantIds: () => Promise<string[]>;
15
+ /**
16
+ * Function to get adapters for a specific tenant.
17
+ */
18
+ getAdapters: (tenantId: string) => Promise<DataAdapters>;
19
+ /**
20
+ * Function to get adapters for the control plane (used for tenant creation sync).
21
+ */
22
+ getControlPlaneAdapters: () => Promise<DataAdapters>;
23
+ /**
24
+ * Which entities to sync. All default to true.
25
+ * Note: Connections are NOT synced - they use runtime fallback by strategy instead.
26
+ */
27
+ sync?: {
28
+ resourceServers?: boolean;
29
+ roles?: boolean;
30
+ };
31
+ /**
32
+ * Optional filters for each entity type
33
+ */
34
+ filters?: {
35
+ resourceServers?: (entity: ResourceServer) => boolean;
36
+ roles?: (entity: Role) => boolean;
37
+ };
38
+ }
39
+ /**
40
+ * Result from createSyncHooks containing all entity and tenant hooks
41
+ *
42
+ * Note: Connections are NOT synced - they use runtime fallback by strategy instead.
43
+ * Tenants can define a connection with a strategy (e.g., "google") and leave keys blank,
44
+ * and the system will fallback to the control plane's connection with the same strategy.
45
+ */
46
+ export interface SyncHooksResult {
47
+ entityHooks: {
48
+ resourceServers?: EntityHooks<ResourceServer, ResourceServerInsert>;
49
+ roles?: EntityHooks<Role, RoleInsert>;
50
+ };
51
+ tenantHooks: TenantEntityHooks;
52
+ }
53
+ export declare function createSyncHooks(config: EntitySyncConfig): SyncHooksResult;
54
+ //# sourceMappingURL=sync.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sync.d.ts","sourceRoot":"","sources":["../../../src/hooks/sync.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,YAAY,EACZ,IAAI,EACJ,UAAU,EACV,cAAc,EACd,oBAAoB,EAGpB,WAAW,EAEZ,MAAM,UAAU,CAAC;AAClB,OAAO,EAAE,iBAAiB,EAAqB,MAAM,UAAU,CAAC;AAEhE;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B;;OAEG;IACH,oBAAoB,EAAE,MAAM,CAAC;IAE7B;;OAEG;IACH,iBAAiB,EAAE,MAAM,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IAE3C;;OAEG;IACH,WAAW,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,YAAY,CAAC,CAAC;IAEzD;;OAEG;IACH,uBAAuB,EAAE,MAAM,OAAO,CAAC,YAAY,CAAC,CAAC;IAErD;;;OAGG;IACH,IAAI,CAAC,EAAE;QACL,eAAe,CAAC,EAAE,OAAO,CAAC;QAC1B,KAAK,CAAC,EAAE,OAAO,CAAC;KACjB,CAAC;IAEF;;OAEG;IACH,OAAO,CAAC,EAAE;QACR,eAAe,CAAC,EAAE,CAAC,MAAM,EAAE,cAAc,KAAK,OAAO,CAAC;QACtD,KAAK,CAAC,EAAE,CAAC,MAAM,EAAE,IAAI,KAAK,OAAO,CAAC;KACnC,CAAC;CACH;AAoQD;;;;;;GAMG;AACH,MAAM,WAAW,eAAe;IAC9B,WAAW,EAAE;QACX,eAAe,CAAC,EAAE,WAAW,CAAC,cAAc,EAAE,oBAAoB,CAAC,CAAC;QACpE,KAAK,CAAC,EAAE,WAAW,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;KACvC,CAAC;IACF,WAAW,EAAE,iBAAiB,CAAC;CAChC;AAqCD,wBAAgB,eAAe,CAAC,MAAM,EAAE,gBAAgB,GAAG,eAAe,CAwLzE"}
@@ -0,0 +1,117 @@
1
+ import { Hono } from "hono";
2
+ import { MultiTenancyConfig, MultiTenancyHooks, MultiTenancyBindings, MultiTenancyVariables } from "./types";
3
+ export * from "./types";
4
+ export { initMultiTenant } from "./init";
5
+ export type { MultiTenantConfig, MultiTenantResult } from "./init";
6
+ export { createSyncHooks } from "./hooks/sync";
7
+ export type { EntitySyncConfig, SyncHooksResult } from "./hooks/sync";
8
+ export { createTenantsOpenAPIRouter } from "./routes";
9
+ export { createMultiTenancyMiddleware, createAccessControlMiddleware, createControlPlaneTenantMiddleware, createSubdomainMiddleware, createDatabaseMiddleware, createProtectSyncedMiddleware, createRuntimeFallbackAdapter, withRuntimeFallback, createSettingsInheritanceAdapter, withSettingsInheritance, } from "./middleware";
10
+ export type { RuntimeFallbackConfig, SettingsInheritanceConfig, } from "./middleware";
11
+ export { createMultiTenancyPlugin } from "./plugin";
12
+ export type { AuthHeroPlugin } from "./plugin";
13
+ export { createAccessControlHooks, createDatabaseHooks, createProvisioningHooks, } from "./hooks";
14
+ export { validateTenantAccess } from "./hooks/access-control";
15
+ export type { DatabaseFactory } from "./hooks/database";
16
+ /**
17
+ * Creates multi-tenancy hooks from configuration.
18
+ *
19
+ * This combines access control, database resolution, and provisioning hooks
20
+ * into a single hooks object that can be passed to AuthHero.
21
+ *
22
+ * @param config - Multi-tenancy configuration
23
+ * @returns Combined hooks for multi-tenancy support
24
+ *
25
+ * @example
26
+ * ```typescript
27
+ * import { createMultiTenancyHooks } from "@authhero/multi-tenancy";
28
+ *
29
+ * const hooks = createMultiTenancyHooks({
30
+ * accessControl: {
31
+ * controlPlaneTenantId: "control_plane",
32
+ * defaultPermissions: ["tenant:admin"],
33
+ * },
34
+ * databaseIsolation: {
35
+ * getAdapters: async (tenantId) => getDatabase(tenantId),
36
+ * },
37
+ * });
38
+ * ```
39
+ */
40
+ export declare function createMultiTenancyHooks(config: MultiTenancyConfig): MultiTenancyHooks;
41
+ /**
42
+ * Creates a complete multi-tenancy Hono app with routes and middleware.
43
+ *
44
+ * This creates a Hono app with:
45
+ * - Tenant management routes (CRUD for tenants)
46
+ * - Access control middleware
47
+ * - Subdomain routing (optional)
48
+ * - Database resolution (optional)
49
+ *
50
+ * @param config - Multi-tenancy configuration
51
+ * @returns Hono app with multi-tenancy routes
52
+ *
53
+ * @example
54
+ * ```typescript
55
+ * import { createMultiTenancy } from "@authhero/multi-tenancy";
56
+ *
57
+ * const multiTenancyApp = createMultiTenancy({
58
+ * accessControl: {
59
+ * controlPlaneTenantId: "main",
60
+ * },
61
+ * });
62
+ *
63
+ * // Mount on your main app
64
+ * app.route("/management", multiTenancyApp);
65
+ * ```
66
+ */
67
+ export declare function createMultiTenancy(config: MultiTenancyConfig): Hono<{
68
+ Bindings: MultiTenancyBindings;
69
+ Variables: MultiTenancyVariables;
70
+ }, import("hono/types").BlankSchema, "/">;
71
+ /**
72
+ * Creates a multi-tenancy setup with both hooks and middleware.
73
+ *
74
+ * This is a convenience function that returns everything needed to
75
+ * integrate multi-tenancy into an AuthHero application.
76
+ *
77
+ * @param config - Multi-tenancy configuration
78
+ * @returns Object with hooks, middleware, and routes
79
+ *
80
+ * @example
81
+ * ```typescript
82
+ * import { setupMultiTenancy } from "@authhero/multi-tenancy";
83
+ *
84
+ * const multiTenancy = setupMultiTenancy({
85
+ * accessControl: {
86
+ * controlPlaneTenantId: "main",
87
+ * },
88
+ * subdomainRouting: {
89
+ * baseDomain: "auth.example.com",
90
+ * },
91
+ * });
92
+ *
93
+ * // Use the middleware
94
+ * app.use("*", multiTenancy.middleware);
95
+ *
96
+ * // Mount the routes
97
+ * app.route("/management", multiTenancy.app);
98
+ *
99
+ * // Pass hooks to AuthHero
100
+ * const authhero = createAuthhero({
101
+ * hooks: multiTenancy.hooks,
102
+ * });
103
+ * ```
104
+ */
105
+ export declare function setupMultiTenancy(config: MultiTenancyConfig): {
106
+ hooks: MultiTenancyHooks;
107
+ middleware: import("hono").MiddlewareHandler<{
108
+ Bindings: MultiTenancyBindings;
109
+ Variables: MultiTenancyVariables;
110
+ }>;
111
+ app: Hono<{
112
+ Bindings: MultiTenancyBindings;
113
+ Variables: MultiTenancyVariables;
114
+ }, import("hono/types").BlankSchema, "/">;
115
+ config: MultiTenancyConfig;
116
+ };
117
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,EACL,kBAAkB,EAClB,iBAAiB,EACjB,oBAAoB,EACpB,qBAAqB,EACtB,MAAM,SAAS,CAAC;AAUjB,cAAc,SAAS,CAAC;AAGxB,OAAO,EAAE,eAAe,EAAE,MAAM,QAAQ,CAAC;AACzC,YAAY,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,QAAQ,CAAC;AAGnE,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAC/C,YAAY,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAEtE,OAAO,EAAE,0BAA0B,EAAE,MAAM,UAAU,CAAC;AAEtD,OAAO,EACL,4BAA4B,EAC5B,6BAA6B,EAC7B,kCAAkC,EAClC,yBAAyB,EACzB,wBAAwB,EACxB,6BAA6B,EAC7B,4BAA4B,EAC5B,mBAAmB,EAEnB,gCAAgC,EAChC,uBAAuB,GACxB,MAAM,cAAc,CAAC;AACtB,YAAY,EACV,qBAAqB,EACrB,yBAAyB,GAC1B,MAAM,cAAc,CAAC;AAEtB,OAAO,EAAE,wBAAwB,EAAE,MAAM,UAAU,CAAC;AACpD,YAAY,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAG/C,OAAO,EACL,wBAAwB,EACxB,mBAAmB,EACnB,uBAAuB,GACxB,MAAM,SAAS,CAAC;AACjB,OAAO,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAC9D,YAAY,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAExD;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,uBAAuB,CACrC,MAAM,EAAE,kBAAkB,GACzB,iBAAiB,CAgBnB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,kBAAkB;cAE/C,oBAAoB;eACnB,qBAAqB;0CASnC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,kBAAkB;;;;;;;kBA9C9C,oBAAoB;mBACnB,qBAAqB;;;EAoDnC"}