@authhero/multi-tenancy 15.1.1 → 15.2.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 +758 -357
- package/dist/types/index.d.ts +1 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/inheritance/chain.d.ts +18 -0
- package/dist/types/inheritance/chain.d.ts.map +1 -0
- package/dist/types/inheritance/index.d.ts +10 -0
- package/dist/types/inheritance/index.d.ts.map +1 -0
- package/dist/types/inheritance/legacy.d.ts +7 -0
- package/dist/types/inheritance/legacy.d.ts.map +1 -0
- package/dist/types/inheritance/merge.d.ts +39 -0
- package/dist/types/inheritance/merge.d.ts.map +1 -0
- package/dist/types/inheritance/read.d.ts +5 -0
- package/dist/types/inheritance/read.d.ts.map +1 -0
- package/dist/types/inheritance/report.d.ts +20 -0
- package/dist/types/inheritance/report.d.ts.map +1 -0
- package/dist/types/inheritance/shadow.d.ts +30 -0
- package/dist/types/inheritance/shadow.d.ts.map +1 -0
- package/dist/types/inheritance/types.d.ts +22 -0
- package/dist/types/inheritance/types.d.ts.map +1 -0
- package/dist/types/init.d.ts +10 -0
- package/dist/types/init.d.ts.map +1 -1
- package/dist/types/middleware/settings-inheritance.d.ts +31 -1
- package/dist/types/middleware/settings-inheritance.d.ts.map +1 -1
- package/dist/types/routes/tenants.d.ts.map +1 -1
- package/dist/types/utils/index.d.ts +1 -0
- package/dist/types/utils/index.d.ts.map +1 -1
- package/dist/types/utils/tenant-tree.d.ts +32 -0
- package/dist/types/utils/tenant-tree.d.ts.map +1 -0
- package/package.json +5 -5
package/dist/types/index.d.ts
CHANGED
|
@@ -11,6 +11,7 @@ export type { EntitySyncConfig, SyncHooksResult } from "./hooks/sync";
|
|
|
11
11
|
export { createTenantsOpenAPIRouter } from "./routes";
|
|
12
12
|
export { createMultiTenancyMiddleware, createAccessControlMiddleware, createControlPlaneTenantMiddleware, createSubdomainMiddleware, createDatabaseMiddleware, createProtectSyncedMiddleware, createRuntimeFallbackAdapter, withRuntimeFallback, withSystemResourceServerInheritance, mergeClientWithFallback, } from "./middleware";
|
|
13
13
|
export type { RuntimeFallbackConfig, ControlPlaneResolver } from "./middleware";
|
|
14
|
+
export * from "./inheritance";
|
|
14
15
|
export { createMultiTenancyPlugin } from "./plugin";
|
|
15
16
|
export type { AuthHeroPlugin } from "./plugin";
|
|
16
17
|
export { createAccessControlHooks, createDatabaseHooks, createProvisioningHooks, } from "./hooks";
|
|
@@ -1 +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;AAajB,cAAc,SAAS,CAAC;AAGxB,OAAO,EAAE,eAAe,EAAE,MAAM,QAAQ,CAAC;AACzC,YAAY,EACV,iBAAiB,EACjB,iBAAiB,EACjB,kBAAkB,GACnB,MAAM,QAAQ,CAAC;AAKhB,OAAO,EACL,0BAA0B,EAC1B,2BAA2B,EAC3B,gCAAgC,EAChC,gCAAgC,GACjC,MAAM,WAAW,CAAC;AACnB,YAAY,EACV,0BAA0B,EAC1B,wBAAwB,EACxB,0BAA0B,EAC1B,wBAAwB,EACxB,uBAAuB,EACvB,mBAAmB,EACnB,2BAA2B,EAC3B,+BAA+B,EAC/B,sBAAsB,EACtB,uBAAuB,GACxB,MAAM,WAAW,CAAC;AAMnB,cAAc,cAAc,CAAC;AAG7B,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,EACnB,mCAAmC,EACnC,uBAAuB,GACxB,MAAM,cAAc,CAAC;AACtB,YAAY,EAAE,qBAAqB,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;
|
|
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;AAajB,cAAc,SAAS,CAAC;AAGxB,OAAO,EAAE,eAAe,EAAE,MAAM,QAAQ,CAAC;AACzC,YAAY,EACV,iBAAiB,EACjB,iBAAiB,EACjB,kBAAkB,GACnB,MAAM,QAAQ,CAAC;AAKhB,OAAO,EACL,0BAA0B,EAC1B,2BAA2B,EAC3B,gCAAgC,EAChC,gCAAgC,GACjC,MAAM,WAAW,CAAC;AACnB,YAAY,EACV,0BAA0B,EAC1B,wBAAwB,EACxB,0BAA0B,EAC1B,wBAAwB,EACxB,uBAAuB,EACvB,mBAAmB,EACnB,2BAA2B,EAC3B,+BAA+B,EAC/B,sBAAsB,EACtB,uBAAuB,GACxB,MAAM,WAAW,CAAC;AAMnB,cAAc,cAAc,CAAC;AAG7B,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,EACnB,mCAAmC,EACnC,uBAAuB,GACxB,MAAM,cAAc,CAAC;AACtB,YAAY,EAAE,qBAAqB,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AAChF,cAAc,eAAe,CAAC;AAE9B,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;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,kBAAkB;;;;;;;kBAnD9C,oBAAoB;mBACnB,qBAAqB;;;IAwDhC;;;;;;;OAOG;6BAES,OAAO,UAAU,EAAE,YAAY,qBACtB;QAAE,oBAAoB,CAAC,EAAE,MAAM,CAAA;KAAE;EAOzD"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Resolves a tenant's ancestors, nearest first.
|
|
3
|
+
*
|
|
4
|
+
* A tenant with `parent_tenant_id` follows that chain. A tenant without one
|
|
5
|
+
* falls back to the legacy control plane as an implicit single parent, so the
|
|
6
|
+
* result matches what read-time inheritance does today. `legacyControlPlane`
|
|
7
|
+
* is `undefined` when the tenant opts out of inheritance.
|
|
8
|
+
*/
|
|
9
|
+
export declare function resolveTenantChain(params: {
|
|
10
|
+
tenantId: string;
|
|
11
|
+
getTenant: (id: string) => Promise<{
|
|
12
|
+
id: string;
|
|
13
|
+
parent_tenant_id?: string | null;
|
|
14
|
+
} | null>;
|
|
15
|
+
legacyControlPlane?: string;
|
|
16
|
+
maxDepth?: number;
|
|
17
|
+
}): Promise<string[]>;
|
|
18
|
+
//# sourceMappingURL=chain.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"chain.d.ts","sourceRoot":"","sources":["../../../src/inheritance/chain.ts"],"names":[],"mappings":"AAGA;;;;;;;GAOG;AACH,wBAAsB,kBAAkB,CAAC,MAAM,EAAE;IAC/C,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,CACT,EAAE,EAAE,MAAM,KACP,OAAO,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,gBAAgB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,GAAG,IAAI,CAAC,CAAC;IACtE,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAgCpB"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export { resolveTenantChain } from "./chain";
|
|
2
|
+
export { effectiveOverride, effectiveScope, mergeConfig } from "./merge";
|
|
3
|
+
export { computeLegacyConfig } from "./legacy";
|
|
4
|
+
export { readConfigRows } from "./read";
|
|
5
|
+
export { compareShadow, diffConfig } from "./shadow";
|
|
6
|
+
export type { ShadowDiff } from "./shadow";
|
|
7
|
+
export { createShadowReporter } from "./report";
|
|
8
|
+
export type { InheritanceShadowOptions, ShadowReporter } from "./report";
|
|
9
|
+
export type { ConfigRows, ConfigEntity, ResolvedConfig } from "./types";
|
|
10
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/inheritance/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAC;AAC7C,OAAO,EAAE,iBAAiB,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AACzE,OAAO,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAC;AAC/C,OAAO,EAAE,cAAc,EAAE,MAAM,QAAQ,CAAC;AACxC,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AACrD,YAAY,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAC3C,OAAO,EAAE,oBAAoB,EAAE,MAAM,UAAU,CAAC;AAChD,YAAY,EAAE,wBAAwB,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AACzE,YAAY,EAAE,UAAU,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { ConfigRows } from "./types";
|
|
2
|
+
/**
|
|
3
|
+
* What read-time inheritance returns for a tenant today, computed from plain
|
|
4
|
+
* rows with the very helpers the runtime fallback adapter uses.
|
|
5
|
+
*/
|
|
6
|
+
export declare function computeLegacyConfig(tenant: ConfigRows, controlPlane: ConfigRows | undefined): ConfigRows;
|
|
7
|
+
//# sourceMappingURL=legacy.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"legacy.d.ts","sourceRoot":"","sources":["../../../src/inheritance/legacy.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAiCrC;;;GAGG;AACH,wBAAgB,mBAAmB,CACjC,MAAM,EAAE,UAAU,EAClB,YAAY,EAAE,UAAU,GAAG,SAAS,GACnC,UAAU,CAiCZ"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import type { ConfigOverride, ConfigScope } from "authhero";
|
|
2
|
+
import { ConfigEntity, ConfigRows, ResolvedConfig } from "./types";
|
|
3
|
+
type Publishable = {
|
|
4
|
+
scope?: ConfigScope | null;
|
|
5
|
+
override?: ConfigOverride | null;
|
|
6
|
+
is_system?: boolean;
|
|
7
|
+
metadata?: unknown;
|
|
8
|
+
};
|
|
9
|
+
/**
|
|
10
|
+
* Scope of a row. An explicit `scope` wins. Unset falls back to what
|
|
11
|
+
* read-time inheritance does today for that entity, so rows nobody has
|
|
12
|
+
* annotated behave as before.
|
|
13
|
+
*/
|
|
14
|
+
export declare function effectiveScope(entity: ConfigEntity, row: Publishable): ConfigScope;
|
|
15
|
+
/**
|
|
16
|
+
* What a child may change on a row. Unset is "fields" because that is how the
|
|
17
|
+
* legacy merge behaves: the tenant's values win.
|
|
18
|
+
*/
|
|
19
|
+
export declare function effectiveOverride(row: Publishable): ConfigOverride;
|
|
20
|
+
type Layer = ConfigRows;
|
|
21
|
+
/**
|
|
22
|
+
* Merges the config of a parent chain with the tenant's own, with no I/O.
|
|
23
|
+
*
|
|
24
|
+
* `chain` is the ancestors' rows **nearest first** (the same order as
|
|
25
|
+
* `resolveTenantChain`); `tenant` is the tenant's own rows. Rules
|
|
26
|
+
* (docs/design/tenant-config-inheritance.md, 3.3):
|
|
27
|
+
* - rows merge by a stable key and the nearest layer wins, limited by the
|
|
28
|
+
* `override` of the layer above;
|
|
29
|
+
* - hooks and actions add up: an ancestor's shared rows appear in addition to
|
|
30
|
+
* the tenant's own;
|
|
31
|
+
* - `local` rows of an ancestor are not visible; `platform` rows are merged
|
|
32
|
+
* but listed in `hidden`.
|
|
33
|
+
*
|
|
34
|
+
* `enforce` does not affect the merged result yet; it constrains edits and
|
|
35
|
+
* deletes, which come with the management API changes.
|
|
36
|
+
*/
|
|
37
|
+
export declare function mergeConfig(chain: Layer[], tenant: Layer): ResolvedConfig;
|
|
38
|
+
export {};
|
|
39
|
+
//# sourceMappingURL=merge.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"merge.d.ts","sourceRoot":"","sources":["../../../src/inheritance/merge.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAEV,cAAc,EACd,WAAW,EAIZ,MAAM,UAAU,CAAC;AAKlB,OAAO,EACL,YAAY,EACZ,UAAU,EACV,cAAc,EAEf,MAAM,SAAS,CAAC;AAEjB,KAAK,WAAW,GAAG;IACjB,KAAK,CAAC,EAAE,WAAW,GAAG,IAAI,CAAC;IAC3B,QAAQ,CAAC,EAAE,cAAc,GAAG,IAAI,CAAC;IACjC,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB,CAAC;AAEF;;;;GAIG;AACH,wBAAgB,cAAc,CAC5B,MAAM,EAAE,YAAY,EACpB,GAAG,EAAE,WAAW,GACf,WAAW,CAcb;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,WAAW,GAAG,cAAc,CAElE;AA4ED,KAAK,KAAK,GAAG,UAAU,CAAC;AAExB;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,KAAK,GAAG,cAAc,CA0GzE"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { DataAdapters } from "authhero";
|
|
2
|
+
import { ConfigRows } from "./types";
|
|
3
|
+
/** Reads every config entity of one tenant as plain rows. */
|
|
4
|
+
export declare function readConfigRows(adapters: DataAdapters, tenantId: string): Promise<ConfigRows>;
|
|
5
|
+
//# sourceMappingURL=read.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"read.d.ts","sourceRoot":"","sources":["../../../src/inheritance/read.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAoB,MAAM,UAAU,CAAC;AAE1D,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAErC,6DAA6D;AAC7D,wBAAsB,cAAc,CAClC,QAAQ,EAAE,YAAY,EACtB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,UAAU,CAAC,CAerB"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { DataAdapters } from "authhero";
|
|
2
|
+
/**
|
|
3
|
+
* Options for config inheritance shadow mode. Shadow mode compares the parent
|
|
4
|
+
* chain resolver with read-time inheritance and logs differences; it never
|
|
5
|
+
* changes what a request sees.
|
|
6
|
+
*/
|
|
7
|
+
export interface InheritanceShadowOptions {
|
|
8
|
+
/** Fraction of reads (0..1) that may start a comparison. @default 1 */
|
|
9
|
+
sample?: number;
|
|
10
|
+
/** Minimum time between comparisons of the same tenant. @default 60000 */
|
|
11
|
+
intervalMs?: number;
|
|
12
|
+
/** Also log differences that are expected (inherited rows the tenant lacks). @default false */
|
|
13
|
+
includeExpected?: boolean;
|
|
14
|
+
}
|
|
15
|
+
export interface ShadowReporter {
|
|
16
|
+
/** Starts a comparison for `tenantId` in the background, if due. */
|
|
17
|
+
schedule(tenantId: string, legacyControlPlane: string | undefined): void;
|
|
18
|
+
}
|
|
19
|
+
export declare function createShadowReporter(adapters: DataAdapters, options: InheritanceShadowOptions): ShadowReporter;
|
|
20
|
+
//# sourceMappingURL=report.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"report.d.ts","sourceRoot":"","sources":["../../../src/inheritance/report.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAY,MAAM,UAAU,CAAC;AAGlD;;;;GAIG;AACH,MAAM,WAAW,wBAAwB;IACvC,uEAAuE;IACvE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,0EAA0E;IAC1E,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,+FAA+F;IAC/F,eAAe,CAAC,EAAE,OAAO,CAAC;CAC3B;AAKD,MAAM,WAAW,cAAc;IAC7B,oEAAoE;IACpE,QAAQ,CAAC,QAAQ,EAAE,MAAM,EAAE,kBAAkB,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,CAAC;CAC1E;AAED,wBAAgB,oBAAoB,CAClC,QAAQ,EAAE,YAAY,EACtB,OAAO,EAAE,wBAAwB,GAChC,cAAc,CAiDhB"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { DataAdapters } from "authhero";
|
|
2
|
+
import { ConfigEntity, ConfigRows } from "./types";
|
|
3
|
+
export interface ShadowDiff {
|
|
4
|
+
entity: ConfigEntity;
|
|
5
|
+
key: string;
|
|
6
|
+
kind: "missing" | "extra" | "changed";
|
|
7
|
+
/** Top-level fields that differ (`changed` only). Values are never logged. */
|
|
8
|
+
fields: string[];
|
|
9
|
+
/**
|
|
10
|
+
* The new model materialises inherited rows into the tenant, where
|
|
11
|
+
* read-time inheritance only overlays rows the tenant already has. A row
|
|
12
|
+
* that is `extra` for that reason is expected and not a bug.
|
|
13
|
+
*/
|
|
14
|
+
expected: boolean;
|
|
15
|
+
legacy_hash?: string;
|
|
16
|
+
new_hash?: string;
|
|
17
|
+
}
|
|
18
|
+
export declare function sha256(input: string): Promise<string>;
|
|
19
|
+
export declare function diffConfig(legacy: ConfigRows, next: ConfigRows): Promise<ShadowDiff[]>;
|
|
20
|
+
/**
|
|
21
|
+
* Computes the new resolver's result and the legacy result for a tenant and
|
|
22
|
+
* returns their differences. Reads only; the resolver result is never used.
|
|
23
|
+
*/
|
|
24
|
+
export declare function compareShadow(params: {
|
|
25
|
+
adapters: DataAdapters;
|
|
26
|
+
tenantId: string;
|
|
27
|
+
legacyControlPlane?: string;
|
|
28
|
+
maxDepth?: number;
|
|
29
|
+
}): Promise<ShadowDiff[]>;
|
|
30
|
+
//# sourceMappingURL=shadow.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shadow.d.ts","sourceRoot":"","sources":["../../../src/inheritance/shadow.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAK7C,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAEnD,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,YAAY,CAAC;IACrB,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,SAAS,GAAG,OAAO,GAAG,SAAS,CAAC;IACtC,8EAA8E;IAC9E,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB;;;;OAIG;IACH,QAAQ,EAAE,OAAO,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAgBD,wBAAsB,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAS3D;AA2FD,wBAAsB,UAAU,CAC9B,MAAM,EAAE,UAAU,EAClB,IAAI,EAAE,UAAU,GACf,OAAO,CAAC,UAAU,EAAE,CAAC,CA+CvB;AAED;;;GAGG;AACH,wBAAsB,aAAa,CAAC,MAAM,EAAE;IAC1C,QAAQ,EAAE,YAAY,CAAC;IACvB,QAAQ,EAAE,MAAM,CAAC;IACjB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC,CA0BxB"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { Action, Branding, Connection, EmailProvider, Hook, PromptSetting, ResourceServer } from "authhero";
|
|
2
|
+
/** Plain config rows for one tenant. Singletons are `null` when unset. */
|
|
3
|
+
export interface ConfigRows {
|
|
4
|
+
connections: Connection[];
|
|
5
|
+
resourceServers: ResourceServer[];
|
|
6
|
+
hooks: Hook[];
|
|
7
|
+
actions: Action[];
|
|
8
|
+
emailProvider: EmailProvider | null;
|
|
9
|
+
branding: Branding | null;
|
|
10
|
+
promptSettings: PromptSetting | null;
|
|
11
|
+
}
|
|
12
|
+
export declare const emptyConfigRows: () => ConfigRows;
|
|
13
|
+
export type ConfigEntity = "connection" | "resourceServer" | "hook" | "action" | "emailProvider" | "branding" | "promptSettings";
|
|
14
|
+
/** Result of merging a parent chain into one tenant's config. */
|
|
15
|
+
export interface ResolvedConfig extends ConfigRows {
|
|
16
|
+
/**
|
|
17
|
+
* Keys (`<entity>:<key>`) of rows that came from a `platform`-scoped
|
|
18
|
+
* ancestor row: merged so they can run, but hidden from the tenant.
|
|
19
|
+
*/
|
|
20
|
+
hidden: string[];
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/inheritance/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,MAAM,EACN,QAAQ,EACR,UAAU,EACV,aAAa,EACb,IAAI,EACJ,aAAa,EACb,cAAc,EACf,MAAM,UAAU,CAAC;AAElB,0EAA0E;AAC1E,MAAM,WAAW,UAAU;IACzB,WAAW,EAAE,UAAU,EAAE,CAAC;IAC1B,eAAe,EAAE,cAAc,EAAE,CAAC;IAClC,KAAK,EAAE,IAAI,EAAE,CAAC;IACd,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,aAAa,EAAE,aAAa,GAAG,IAAI,CAAC;IACpC,QAAQ,EAAE,QAAQ,GAAG,IAAI,CAAC;IAC1B,cAAc,EAAE,aAAa,GAAG,IAAI,CAAC;CACtC;AAED,eAAO,MAAM,eAAe,QAAO,UAQjC,CAAC;AAEH,MAAM,MAAM,YAAY,GACpB,YAAY,GACZ,gBAAgB,GAChB,MAAM,GACN,QAAQ,GACR,eAAe,GACf,UAAU,GACV,gBAAgB,CAAC;AAErB,iEAAiE;AACjE,MAAM,WAAW,cAAe,SAAQ,UAAU;IAChD;;;OAGG;IACH,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB"}
|
package/dist/types/init.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { init, AuthHeroConfig, DataAdapters } from "authhero";
|
|
2
2
|
import type { ControlPlaneResolver } from "./middleware";
|
|
3
|
+
import type { InheritanceShadowOptions } from "./inheritance";
|
|
3
4
|
/**
|
|
4
5
|
* Control plane configuration for multi-tenancy.
|
|
5
6
|
*/
|
|
@@ -53,6 +54,15 @@ export interface MultiTenantConfig extends Omit<AuthHeroConfig, "entityHooks" |
|
|
|
53
54
|
* ```
|
|
54
55
|
*/
|
|
55
56
|
resolveControlPlane?: ControlPlaneResolver;
|
|
57
|
+
/**
|
|
58
|
+
* Shadow mode for config inheritance: compares the parent chain resolver
|
|
59
|
+
* with read-time inheritance in the background and logs differences as log
|
|
60
|
+
* type `cfgdiff`, queryable per tenant. Never affects a response.
|
|
61
|
+
* `true` uses the defaults.
|
|
62
|
+
*
|
|
63
|
+
* @default false
|
|
64
|
+
*/
|
|
65
|
+
inheritanceShadow?: boolean | InheritanceShadowOptions;
|
|
56
66
|
/**
|
|
57
67
|
* Control which entities to sync from control plane to child tenants.
|
|
58
68
|
* Set to `false` to disable all syncing.
|
package/dist/types/init.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/init.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,IAAI,EACJ,cAAc,EAEd,YAAY,EAGb,MAAM,UAAU,CAAC;AAUlB,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/init.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,IAAI,EACJ,cAAc,EAEd,YAAY,EAGb,MAAM,UAAU,CAAC;AAUlB,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AACzD,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,eAAe,CAAC;AAG9D;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC;;OAEG;IACH,QAAQ,EAAE,MAAM,CAAC;IAEjB;;;;OAIG;IACH,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED;;GAEG;AACH,MAAM,WAAW,iBAAkB,SAAQ,IAAI,CAC7C,cAAc,EACd,aAAa,GAAG,yBAAyB,CAC1C;IACC;;;;;OAKG;IACH,YAAY,CAAC,EAAE,kBAAkB,CAAC;IAElC;;;;;;;;;;;;;;;;;;;;;;;;;OAyBG;IACH,mBAAmB,CAAC,EAAE,oBAAoB,CAAC;IAE3C;;;;;;;OAOG;IACH,iBAAiB,CAAC,EAAE,OAAO,GAAG,wBAAwB,CAAC;IAEvD;;;;OAIG;IACH,IAAI,CAAC,EACD;QACE,eAAe,CAAC,EAAE,OAAO,CAAC;QAC1B,KAAK,CAAC,EAAE,OAAO,CAAC;KACjB,GACD,KAAK,CAAC;IAEV;;;OAGG;IACH,kBAAkB,CAAC,EAAE,MAAM,EAAE,CAAC;IAE9B;;;OAGG;IACH,wBAAwB,CAAC,EAAE,OAAO,CAAC;IAEnC;;;OAGG;IACH,uBAAuB,CAAC,EAAE,cAAc,CAAC,yBAAyB,CAAC,CAAC;IAEpE;;;OAGG;IACH,WAAW,CAAC,EAAE,cAAc,CAAC,aAAa,CAAC,CAAC;IAE5C;;;OAGG;IACH,iBAAiB,CAAC,EAAE,MAAM,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IAE5C;;;;OAIG;IACH,WAAW,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,YAAY,CAAC,CAAC;CAC3D;AAED;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,8BAA8B;IAC9B,GAAG,EAAE,UAAU,CAAC,OAAO,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC;IACpC,kCAAkC;IAClC,oBAAoB,EAAE,MAAM,CAAC;CAC9B;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0DG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,iBAAiB,GAAG,iBAAiB,CA8N5E"}
|
|
@@ -1,4 +1,18 @@
|
|
|
1
|
-
import { DataAdapters, Client } from "authhero";
|
|
1
|
+
import { DataAdapters, Connection, Client, ResourceServer, ResourceServerScope } from "authhero";
|
|
2
|
+
import { InheritanceShadowOptions } from "../inheritance/report";
|
|
3
|
+
/**
|
|
4
|
+
* Merges a connection with control plane fallback options.
|
|
5
|
+
*/
|
|
6
|
+
export declare function mergeConnectionWithFallback(connection: Connection, controlPlaneConnections: Connection[]): Connection;
|
|
7
|
+
/**
|
|
8
|
+
* Merges resource server scopes with control plane fallback.
|
|
9
|
+
* Tenant-specific scopes override control plane scopes with the same value.
|
|
10
|
+
*/
|
|
11
|
+
export declare function mergeResourceServerScopes(tenantScopes: ResourceServerScope[] | undefined, controlPlaneScopes: ResourceServerScope[] | undefined): ResourceServerScope[];
|
|
12
|
+
/**
|
|
13
|
+
* Merges a resource server with control plane fallback scopes.
|
|
14
|
+
*/
|
|
15
|
+
export declare function mergeResourceServerWithFallback(resourceServer: ResourceServer, controlPlaneResourceServer: ResourceServer | null): ResourceServer;
|
|
2
16
|
/**
|
|
3
17
|
* Merges a client with control plane fallback URLs.
|
|
4
18
|
*
|
|
@@ -75,6 +89,15 @@ export interface RuntimeFallbackConfig {
|
|
|
75
89
|
* control plane id.
|
|
76
90
|
*/
|
|
77
91
|
resolveControlPlane?: ControlPlaneResolver;
|
|
92
|
+
/**
|
|
93
|
+
* Shadow mode for config inheritance. When set, reads also start a
|
|
94
|
+
* background comparison of the parent chain resolver against the result of
|
|
95
|
+
* this adapter and log differences with log type `cfgdiff`. The comparison
|
|
96
|
+
* never changes what a request sees. `true` uses the defaults.
|
|
97
|
+
*
|
|
98
|
+
* @default false
|
|
99
|
+
*/
|
|
100
|
+
inheritanceShadow?: boolean | InheritanceShadowOptions;
|
|
78
101
|
}
|
|
79
102
|
/**
|
|
80
103
|
* Creates a data adapter wrapper that provides runtime settings fallback from a control plane tenant.
|
|
@@ -112,6 +135,13 @@ export interface RuntimeFallbackConfig {
|
|
|
112
135
|
* ```
|
|
113
136
|
*/
|
|
114
137
|
export declare function createRuntimeFallbackAdapter(baseAdapters: DataAdapters, config: RuntimeFallbackConfig): DataAdapters;
|
|
138
|
+
/**
|
|
139
|
+
* Returns true when a hook is marked as inheritable by the control plane.
|
|
140
|
+
* Inheritable hooks surface on every sub-tenant's `hooks.list` so a single
|
|
141
|
+
* control-plane row drives behaviour fleet-wide. Reads `metadata.inheritable`
|
|
142
|
+
* on any hook variant (web/form/template/code).
|
|
143
|
+
*/
|
|
144
|
+
export declare function isInheritableHook(hook: unknown): boolean;
|
|
115
145
|
/**
|
|
116
146
|
* Helper function to wrap data adapters with runtime fallback from control plane.
|
|
117
147
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"settings-inheritance.d.ts","sourceRoot":"","sources":["../../../src/middleware/settings-inheritance.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,YAAY,
|
|
1
|
+
{"version":3,"file":"settings-inheritance.d.ts","sourceRoot":"","sources":["../../../src/middleware/settings-inheritance.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,YAAY,EACZ,UAAU,EACV,MAAM,EACN,cAAc,EACd,mBAAmB,EAGpB,MAAM,UAAU,CAAC;AAClB,OAAO,EACL,wBAAwB,EAEzB,MAAM,uBAAuB,CAAC;AAE/B;;GAEG;AACH,wBAAgB,2BAA2B,CACzC,UAAU,EAAE,UAAU,EACtB,uBAAuB,EAAE,UAAU,EAAE,GACpC,UAAU,CAwBZ;AAcD;;;GAGG;AACH,wBAAgB,yBAAyB,CACvC,YAAY,EAAE,mBAAmB,EAAE,GAAG,SAAS,EAC/C,kBAAkB,EAAE,mBAAmB,EAAE,GAAG,SAAS,GACpD,mBAAmB,EAAE,CAmBvB;AAED;;GAEG;AACH,wBAAgB,+BAA+B,CAC7C,cAAc,EAAE,cAAc,EAC9B,0BAA0B,EAAE,cAAc,GAAG,IAAI,GAChD,cAAc,CAYhB;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,uBAAuB,CACrC,MAAM,EAAE,MAAM,EACd,kBAAkB,EAAE,MAAM,GAAG,IAAI,GAChC,MAAM,CAqBR;AAED;;;GAGG;AACH,KAAK,oBAAoB,GAAG;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,SAAS,CAAC;AAEhF;;;;;;;GAOG;AACH,MAAM,MAAM,oBAAoB,GAAG,CAAC,MAAM,EAAE;IAC1C,SAAS,EAAE,MAAM,CAAC;CACnB,KAAK,oBAAoB,GAAG,OAAO,CAAC,oBAAoB,CAAC,CAAC;AAyH3D;;;;;;;;GAQG;AACH,wBAAgB,mCAAmC,CACjD,YAAY,EAAE,YAAY,EAC1B,MAAM,EAAE;IACN,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,mBAAmB,CAAC,EAAE,oBAAoB,CAAC;CAC5C,GACA,YAAY,CAYd;AAED;;;;GAIG;AACH,MAAM,WAAW,qBAAqB;IACpC;;;;OAIG;IACH,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAE9B;;;;OAIG;IACH,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAE9B;;;;;;;;;;;OAWG;IACH,mBAAmB,CAAC,EAAE,oBAAoB,CAAC;IAE3C;;;;;;;OAOG;IACH,iBAAiB,CAAC,EAAE,OAAO,GAAG,wBAAwB,CAAC;CACxD;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AACH,wBAAgB,4BAA4B,CAC1C,YAAY,EAAE,YAAY,EAC1B,MAAM,EAAE,qBAAqB,GAC5B,YAAY,CA8Kd;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO,CAKxD;AA8ED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,mBAAmB,CACjC,YAAY,EAAE,YAAY,EAC1B,MAAM,EAAE,qBAAqB,GAC5B,YAAY,CAEd"}
|
|
@@ -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;AA0ClB;;;;;;;;;;GAUG;AACH,wBAAgB,0BAA0B,CACxC,MAAM,EAAE,kBAAkB,EAC1B,KAAK,EAAE,iBAAiB;cAGZ,oBAAoB;eACnB,qBAAqB;YAujBnC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/utils/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AACpC,YAAY,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/utils/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AACpC,YAAY,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAChD,OAAO,EAAE,oBAAoB,EAAE,wBAAwB,EAAE,MAAM,eAAe,CAAC"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Default maximum number of ancestors a tenant may have. The tree is limited
|
|
3
|
+
* to two levels above a tenant to begin with, but callers pass the limit so it
|
|
4
|
+
* is not hard-coded in the model (docs/design/tenant-config-inheritance.md,
|
|
5
|
+
* section 3.1).
|
|
6
|
+
*/
|
|
7
|
+
export declare const DEFAULT_MAX_TENANT_DEPTH = 2;
|
|
8
|
+
/**
|
|
9
|
+
* Validates `parent_tenant_id` for a tenant that is being created or
|
|
10
|
+
* re-parented. Throws a 400 when the parent does not exist, when the new
|
|
11
|
+
* parent would create a cycle, or when the resulting chain of ancestors is
|
|
12
|
+
* longer than `maxDepth`.
|
|
13
|
+
*
|
|
14
|
+
* Pure with respect to storage: ancestors are read through `getTenant`.
|
|
15
|
+
* Nothing reads the parent yet; this only keeps the stored tree valid.
|
|
16
|
+
*/
|
|
17
|
+
export declare function validateTenantParent(params: {
|
|
18
|
+
tenantId: string | undefined;
|
|
19
|
+
parentTenantId: string | null | undefined;
|
|
20
|
+
getTenant: (id: string) => Promise<{
|
|
21
|
+
id: string;
|
|
22
|
+
parent_tenant_id?: string | null;
|
|
23
|
+
} | null>;
|
|
24
|
+
/**
|
|
25
|
+
* Returns the ids of a tenant's direct children. When given, the subtree
|
|
26
|
+
* below `tenantId` is validated too: re-parenting pushes every descendant
|
|
27
|
+
* down, so each resulting chain must still fit within `maxDepth`.
|
|
28
|
+
*/
|
|
29
|
+
getChildren?: (id: string) => Promise<string[]>;
|
|
30
|
+
maxDepth?: number;
|
|
31
|
+
}): Promise<void>;
|
|
32
|
+
//# sourceMappingURL=tenant-tree.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tenant-tree.d.ts","sourceRoot":"","sources":["../../../src/utils/tenant-tree.ts"],"names":[],"mappings":"AAEA;;;;;GAKG;AACH,eAAO,MAAM,wBAAwB,IAAI,CAAC;AAE1C;;;;;;;;GAQG;AACH,wBAAsB,oBAAoB,CAAC,MAAM,EAAE;IACjD,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAC;IAC7B,cAAc,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IAC1C,SAAS,EAAE,CACT,EAAE,EAAE,MAAM,KACP,OAAO,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,gBAAgB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,GAAG,IAAI,CAAC,CAAC;IACtE;;;;OAIG;IACH,WAAW,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;IAChD,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,GAAG,OAAO,CAAC,IAAI,CAAC,CAkEhB"}
|
package/package.json
CHANGED
|
@@ -9,9 +9,9 @@
|
|
|
9
9
|
"homepage": "https://authhero.net",
|
|
10
10
|
"repository": {
|
|
11
11
|
"type": "git",
|
|
12
|
-
"url": "https://github.com/
|
|
12
|
+
"url": "https://github.com/sesamyab/authhero"
|
|
13
13
|
},
|
|
14
|
-
"version": "15.
|
|
14
|
+
"version": "15.2.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/adapter-interfaces": "4.
|
|
40
|
-
"@authhero/kysely-adapter": "12.
|
|
41
|
-
"authhero": "9.
|
|
39
|
+
"@authhero/adapter-interfaces": "4.22.0",
|
|
40
|
+
"@authhero/kysely-adapter": "12.16.0",
|
|
41
|
+
"authhero": "9.25.0"
|
|
42
42
|
},
|
|
43
43
|
"dependencies": {
|
|
44
44
|
"zod": "^4.4.3"
|