@memberjunction/server 5.12.0 → 5.13.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,39 @@
1
+ /**
2
+ * MJ's built-in multi-tenancy middleware.
3
+ *
4
+ * Registers with key 'mj:tenantFilter' so that downstream layers (e.g., BCSaaS)
5
+ * can replace it by registering with the same key at higher ClassFactory priority.
6
+ *
7
+ * Conditionally enabled via configInfo.multiTenancy?.enabled.
8
+ */
9
+
10
+ import { RegisterClass } from '@memberjunction/global';
11
+ import { BaseServerMiddleware } from './BaseServerMiddleware.js';
12
+ import { configInfo } from '../config.js';
13
+ import { createTenantMiddleware, createTenantPreRunViewHook, createTenantPreSaveHook } from '../multiTenancy/index.js';
14
+ import type { RequestHandler } from 'express';
15
+ import type { RunViewParams, UserInfo, BaseEntity } from '@memberjunction/core';
16
+
17
+ @RegisterClass(BaseServerMiddleware, 'mj:tenantFilter')
18
+ export class MJTenantFilterMiddleware extends BaseServerMiddleware {
19
+ get Label(): string { return 'mj:tenantFilter'; }
20
+
21
+ /**
22
+ * Only active when multiTenancy is enabled in config.
23
+ */
24
+ get Enabled(): boolean {
25
+ return configInfo.multiTenancy?.enabled ?? false;
26
+ }
27
+
28
+ GetPostAuthMiddleware(): RequestHandler[] {
29
+ return [createTenantMiddleware(configInfo.multiTenancy!)];
30
+ }
31
+
32
+ PreRunView(params: RunViewParams, contextUser: UserInfo | undefined): RunViewParams | Promise<RunViewParams> {
33
+ return createTenantPreRunViewHook(configInfo.multiTenancy!)(params, contextUser);
34
+ }
35
+
36
+ PreSave(entity: BaseEntity, contextUser: UserInfo | undefined): boolean | string | Promise<boolean | string> {
37
+ return createTenantPreSaveHook(configInfo.multiTenancy!)(entity, contextUser);
38
+ }
39
+ }
@@ -0,0 +1,2 @@
1
+ export * from './BaseServerMiddleware.js';
2
+ export * from './MJTenantFilterMiddleware.js';
package/dist/hooks.d.ts DELETED
@@ -1,65 +0,0 @@
1
- /**
2
- * Server-level extensibility types for MJServer.
3
- *
4
- * Provider-level hook types (PreRunViewHook, PostRunViewHook, PreSaveHook)
5
- * are defined and exported from @memberjunction/core (hookRegistry.ts) so
6
- * that ProviderBase and BaseEntity can reference them without depending
7
- * on @memberjunction/server.
8
- *
9
- * This file re-exports those types for convenience and adds the
10
- * server-specific extensibility options (Express middleware, Apollo plugins,
11
- * schema transformers).
12
- */
13
- export type { PreRunViewHook, PostRunViewHook, PreSaveHook, HookName, HookRegistrationOptions } from '@memberjunction/core';
14
- import type { PreRunViewHook, PostRunViewHook, PreSaveHook } from '@memberjunction/core';
15
- import type { RequestHandler, ErrorRequestHandler, Application } from 'express';
16
- import type { ApolloServerPlugin } from '@apollo/server';
17
- import type { GraphQLSchema } from 'graphql';
18
- /**
19
- * A hook entry that includes the hook function plus optional registration metadata.
20
- * Dynamic packages use this format to declare hooks with priority and namespace.
21
- */
22
- export interface HookWithOptions<T> {
23
- hook: T;
24
- Priority?: number;
25
- Namespace?: string;
26
- }
27
- /** A hook value is either a plain function or a function with registration options */
28
- export type HookOrEntry<T> = T | HookWithOptions<T>;
29
- /**
30
- * Extensibility options that can be passed to `serve()` (via MJServerOptions)
31
- * or to `createMJServer()` (via MJServerConfig).
32
- *
33
- * All properties are optional — when omitted, zero behavior change (backward compatible).
34
- */
35
- export interface ServerExtensibilityOptions {
36
- /** Express middleware applied after compression but before OAuth/REST/GraphQL routes */
37
- ExpressMiddlewareBefore?: RequestHandler[];
38
- /** Express middleware/error handlers applied after all routes (catch-alls, error handlers) */
39
- ExpressMiddlewareAfter?: (RequestHandler | ErrorRequestHandler)[];
40
- /** Escape hatch for advanced Express app configuration (CORS, trust proxy, etc.) */
41
- ConfigureExpressApp?: (app: Application) => void | Promise<void>;
42
- /** Additional Apollo Server plugins merged with the built-in drain/cleanup plugins */
43
- ApolloPlugins?: ApolloServerPlugin[];
44
- /** Schema transformers applied after built-in directive transformers */
45
- SchemaTransformers?: ((schema: GraphQLSchema) => GraphQLSchema)[];
46
- /**
47
- * Express middleware that runs AFTER authentication has resolved UserInfo
48
- * onto the request. Use this for middleware that needs the authenticated
49
- * user (e.g., tenant context resolution, org membership loading).
50
- *
51
- * The authenticated user payload is available at `req.userPayload`.
52
- * Middleware in this array runs in registration order.
53
- */
54
- ExpressMiddlewarePostAuth?: RequestHandler[];
55
- /** Hooks that modify RunViewParams before query execution (e.g., tenant filter injection).
56
- * Each entry can be a plain hook function or a `{ hook, Priority, Namespace }` object. */
57
- PreRunViewHooks?: HookOrEntry<PreRunViewHook>[];
58
- /** Hooks that modify RunViewResult after query execution (e.g., data masking).
59
- * Each entry can be a plain hook function or a `{ hook, Priority, Namespace }` object. */
60
- PostRunViewHooks?: HookOrEntry<PostRunViewHook>[];
61
- /** Hooks that validate/reject Save operations before they hit the database.
62
- * Each entry can be a plain hook function or a `{ hook, Priority, Namespace }` object. */
63
- PreSaveHooks?: HookOrEntry<PreSaveHook>[];
64
- }
65
- //# sourceMappingURL=hooks.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"hooks.d.ts","sourceRoot":"","sources":["../src/hooks.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,YAAY,EAAE,cAAc,EAAE,eAAe,EAAE,WAAW,EAAE,QAAQ,EAAE,uBAAuB,EAAE,MAAM,sBAAsB,CAAC;AAE5H,OAAO,KAAK,EAAE,cAAc,EAAE,eAAe,EAAE,WAAW,EAA2B,MAAM,sBAAsB,CAAC;AAClH,OAAO,KAAK,EAAE,cAAc,EAAE,mBAAmB,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAChF,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AACzD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAE7C;;;GAGG;AACH,MAAM,WAAW,eAAe,CAAC,CAAC;IAChC,IAAI,EAAE,CAAC,CAAC;IACR,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,sFAAsF;AACtF,MAAM,MAAM,WAAW,CAAC,CAAC,IAAI,CAAC,GAAG,eAAe,CAAC,CAAC,CAAC,CAAC;AAEpD;;;;;GAKG;AACH,MAAM,WAAW,0BAA0B;IACzC,wFAAwF;IACxF,uBAAuB,CAAC,EAAE,cAAc,EAAE,CAAC;IAE3C,8FAA8F;IAC9F,sBAAsB,CAAC,EAAE,CAAC,cAAc,GAAG,mBAAmB,CAAC,EAAE,CAAC;IAElE,oFAAoF;IACpF,mBAAmB,CAAC,EAAE,CAAC,GAAG,EAAE,WAAW,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEjE,sFAAsF;IACtF,aAAa,CAAC,EAAE,kBAAkB,EAAE,CAAC;IAErC,wEAAwE;IACxE,kBAAkB,CAAC,EAAE,CAAC,CAAC,MAAM,EAAE,aAAa,KAAK,aAAa,CAAC,EAAE,CAAC;IAElE;;;;;;;OAOG;IACH,yBAAyB,CAAC,EAAE,cAAc,EAAE,CAAC;IAE7C;8FAC0F;IAC1F,eAAe,CAAC,EAAE,WAAW,CAAC,cAAc,CAAC,EAAE,CAAC;IAEhD;8FAC0F;IAC1F,gBAAgB,CAAC,EAAE,WAAW,CAAC,eAAe,CAAC,EAAE,CAAC;IAElD;8FAC0F;IAC1F,YAAY,CAAC,EAAE,WAAW,CAAC,WAAW,CAAC,EAAE,CAAC;CAC3C"}
package/dist/hooks.js DELETED
@@ -1,14 +0,0 @@
1
- /**
2
- * Server-level extensibility types for MJServer.
3
- *
4
- * Provider-level hook types (PreRunViewHook, PostRunViewHook, PreSaveHook)
5
- * are defined and exported from @memberjunction/core (hookRegistry.ts) so
6
- * that ProviderBase and BaseEntity can reference them without depending
7
- * on @memberjunction/server.
8
- *
9
- * This file re-exports those types for convenience and adds the
10
- * server-specific extensibility options (Express middleware, Apollo plugins,
11
- * schema transformers).
12
- */
13
- export {};
14
- //# sourceMappingURL=hooks.js.map
package/dist/hooks.js.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"hooks.js","sourceRoot":"","sources":["../src/hooks.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG"}
@@ -1,6 +0,0 @@
1
- /**
2
- * Startup function called by DynamicPackageLoader.
3
- * Returns extensibility config that gets merged into server options.
4
- */
5
- export declare function LoadTestPlugin(): Record<string, unknown>;
6
- //# sourceMappingURL=test-dynamic-plugin.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"test-dynamic-plugin.d.ts","sourceRoot":"","sources":["../src/test-dynamic-plugin.ts"],"names":[],"mappings":"AA0BA;;;GAGG;AACH,wBAAgB,cAAc,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAKxD"}
@@ -1,18 +0,0 @@
1
- /** Post-auth middleware that logs authenticated requests */
2
- const testPostAuthMiddleware = (req, _res, next) => {
3
- const userPayload = req.userPayload;
4
- const email = userPayload?.email ?? 'unknown';
5
- console.log(`[TestPlugin] Post-auth middleware: ${req.method} ${req.path} (user: ${email})`);
6
- next();
7
- };
8
- /**
9
- * Startup function called by DynamicPackageLoader.
10
- * Returns extensibility config that gets merged into server options.
11
- */
12
- export function LoadTestPlugin() {
13
- console.log('[TestPlugin] Startup function called');
14
- return {
15
- ExpressMiddlewarePostAuth: [testPostAuthMiddleware],
16
- };
17
- }
18
- //# sourceMappingURL=test-dynamic-plugin.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"test-dynamic-plugin.js","sourceRoot":"","sources":["../src/test-dynamic-plugin.ts"],"names":[],"mappings":"AAkBA,4DAA4D;AAC5D,MAAM,sBAAsB,GAAmB,CAAC,GAAG,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE;IACjE,MAAM,WAAW,GAAI,GAAqC,CAAC,WAAW,CAAC;IACvE,MAAM,KAAK,GAAG,WAAW,EAAE,KAAK,IAAI,SAAS,CAAC;IAC9C,OAAO,CAAC,GAAG,CAAC,sCAAsC,GAAG,CAAC,MAAM,IAAI,GAAG,CAAC,IAAI,WAAW,KAAK,GAAG,CAAC,CAAC;IAC7F,IAAI,EAAE,CAAC;AACT,CAAC,CAAC;AAEF;;;GAGG;AACH,MAAM,UAAU,cAAc;IAC5B,OAAO,CAAC,GAAG,CAAC,sCAAsC,CAAC,CAAC;IACpD,OAAO;QACL,yBAAyB,EAAE,CAAC,sBAAsB,CAAC;KACpD,CAAC;AACJ,CAAC"}
package/src/hooks.ts DELETED
@@ -1,77 +0,0 @@
1
- /**
2
- * Server-level extensibility types for MJServer.
3
- *
4
- * Provider-level hook types (PreRunViewHook, PostRunViewHook, PreSaveHook)
5
- * are defined and exported from @memberjunction/core (hookRegistry.ts) so
6
- * that ProviderBase and BaseEntity can reference them without depending
7
- * on @memberjunction/server.
8
- *
9
- * This file re-exports those types for convenience and adds the
10
- * server-specific extensibility options (Express middleware, Apollo plugins,
11
- * schema transformers).
12
- */
13
-
14
- export type { PreRunViewHook, PostRunViewHook, PreSaveHook, HookName, HookRegistrationOptions } from '@memberjunction/core';
15
-
16
- import type { PreRunViewHook, PostRunViewHook, PreSaveHook, HookRegistrationOptions } from '@memberjunction/core';
17
- import type { RequestHandler, ErrorRequestHandler, Application } from 'express';
18
- import type { ApolloServerPlugin } from '@apollo/server';
19
- import type { GraphQLSchema } from 'graphql';
20
-
21
- /**
22
- * A hook entry that includes the hook function plus optional registration metadata.
23
- * Dynamic packages use this format to declare hooks with priority and namespace.
24
- */
25
- export interface HookWithOptions<T> {
26
- hook: T;
27
- Priority?: number;
28
- Namespace?: string;
29
- }
30
-
31
- /** A hook value is either a plain function or a function with registration options */
32
- export type HookOrEntry<T> = T | HookWithOptions<T>;
33
-
34
- /**
35
- * Extensibility options that can be passed to `serve()` (via MJServerOptions)
36
- * or to `createMJServer()` (via MJServerConfig).
37
- *
38
- * All properties are optional — when omitted, zero behavior change (backward compatible).
39
- */
40
- export interface ServerExtensibilityOptions {
41
- /** Express middleware applied after compression but before OAuth/REST/GraphQL routes */
42
- ExpressMiddlewareBefore?: RequestHandler[];
43
-
44
- /** Express middleware/error handlers applied after all routes (catch-alls, error handlers) */
45
- ExpressMiddlewareAfter?: (RequestHandler | ErrorRequestHandler)[];
46
-
47
- /** Escape hatch for advanced Express app configuration (CORS, trust proxy, etc.) */
48
- ConfigureExpressApp?: (app: Application) => void | Promise<void>;
49
-
50
- /** Additional Apollo Server plugins merged with the built-in drain/cleanup plugins */
51
- ApolloPlugins?: ApolloServerPlugin[];
52
-
53
- /** Schema transformers applied after built-in directive transformers */
54
- SchemaTransformers?: ((schema: GraphQLSchema) => GraphQLSchema)[];
55
-
56
- /**
57
- * Express middleware that runs AFTER authentication has resolved UserInfo
58
- * onto the request. Use this for middleware that needs the authenticated
59
- * user (e.g., tenant context resolution, org membership loading).
60
- *
61
- * The authenticated user payload is available at `req.userPayload`.
62
- * Middleware in this array runs in registration order.
63
- */
64
- ExpressMiddlewarePostAuth?: RequestHandler[];
65
-
66
- /** Hooks that modify RunViewParams before query execution (e.g., tenant filter injection).
67
- * Each entry can be a plain hook function or a `{ hook, Priority, Namespace }` object. */
68
- PreRunViewHooks?: HookOrEntry<PreRunViewHook>[];
69
-
70
- /** Hooks that modify RunViewResult after query execution (e.g., data masking).
71
- * Each entry can be a plain hook function or a `{ hook, Priority, Namespace }` object. */
72
- PostRunViewHooks?: HookOrEntry<PostRunViewHook>[];
73
-
74
- /** Hooks that validate/reject Save operations before they hit the database.
75
- * Each entry can be a plain hook function or a `{ hook, Priority, Namespace }` object. */
76
- PreSaveHooks?: HookOrEntry<PreSaveHook>[];
77
- }
@@ -1,36 +0,0 @@
1
- /**
2
- * Test Dynamic Plugin for Phase 2 DynamicPackageLoader testing.
3
- *
4
- * This simple plugin validates the DynamicPackageLoader → MJServer pipeline:
5
- * - Startup function is called and returns extensibility config
6
- * - Post-auth middleware is injected and runs on each authenticated request
7
- * - Middleware has access to the authenticated user via req.userPayload
8
- *
9
- * To enable: add to dynamicPackages.server in packages/MJAPI/mj.config.cjs
10
- * To disable: set Enabled: false or remove the entry
11
- */
12
- import type { RequestHandler } from 'express';
13
-
14
- interface UserPayload {
15
- email?: string;
16
- userRecord?: { ID?: string };
17
- }
18
-
19
- /** Post-auth middleware that logs authenticated requests */
20
- const testPostAuthMiddleware: RequestHandler = (req, _res, next) => {
21
- const userPayload = (req as { userPayload?: UserPayload }).userPayload;
22
- const email = userPayload?.email ?? 'unknown';
23
- console.log(`[TestPlugin] Post-auth middleware: ${req.method} ${req.path} (user: ${email})`);
24
- next();
25
- };
26
-
27
- /**
28
- * Startup function called by DynamicPackageLoader.
29
- * Returns extensibility config that gets merged into server options.
30
- */
31
- export function LoadTestPlugin(): Record<string, unknown> {
32
- console.log('[TestPlugin] Startup function called');
33
- return {
34
- ExpressMiddlewarePostAuth: [testPostAuthMiddleware],
35
- };
36
- }