@discover-cloud/shared 1.2.9 → 1.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.
- package/dist/authorization/index.d.ts +2 -2
- package/dist/authorization/index.js +1 -1
- package/dist/authorization/permission-cache.service.d.ts +104 -16
- package/dist/authorization/permission-cache.service.js +177 -148
- package/dist/authorization/permission-checker.d.ts +30 -0
- package/dist/authorization/permission-checker.js +40 -0
- package/dist/context/index.d.ts +1 -1
- package/dist/context/index.js +1 -1
- package/dist/context/request-context.storage.d.ts +21 -0
- package/dist/context/request-context.storage.js +37 -0
- package/dist/contracts/auth-service/account.dto.d.ts +30 -0
- package/dist/contracts/auth-service/account.dto.js +7 -0
- package/dist/contracts/auth-service/auth.dto.d.ts +21 -0
- package/dist/contracts/auth-service/auth.dto.js +10 -0
- package/dist/contracts/index.d.ts +1 -0
- package/dist/{security → contracts}/index.js +1 -1
- package/dist/contracts/visibility.d.ts +63 -0
- package/dist/contracts/visibility.js +10 -0
- package/dist/dtos/audit-service.types.d.ts +42 -0
- package/dist/dtos/audit-service.types.js +31 -0
- package/dist/dtos/auth-service.dto.d.ts +87 -26
- package/dist/dtos/auth-service.dto.js +4 -0
- package/dist/dtos/cloud-service.dto.d.ts +57 -27
- package/dist/dtos/cloud-service.dto.js +5 -0
- package/dist/dtos/index.d.ts +6 -5
- package/dist/dtos/index.js +1 -0
- package/dist/dtos/insights-service.dto.d.ts +184 -32
- package/dist/dtos/insights-service.dto.js +8 -0
- package/dist/dtos/response.dto.d.ts +12 -83
- package/dist/dtos/response.dto.js +2 -21
- package/dist/dtos/user-service.dto.d.ts +163 -13
- package/dist/enums/domain.enums.d.ts +272 -75
- package/dist/enums/domain.enums.js +329 -102
- package/dist/enums/index.d.ts +2 -2
- package/dist/enums/permissions.enums.d.ts +142 -80
- package/dist/enums/permissions.enums.js +174 -133
- package/dist/errors/app-error.d.ts +13 -18
- package/dist/errors/app-error.js +15 -21
- package/dist/errors/http-errors.d.ts +106 -18
- package/dist/errors/http-errors.js +136 -51
- package/dist/errors/index.d.ts +2 -2
- package/dist/http/index.d.ts +2 -1
- package/dist/http/index.js +1 -0
- package/dist/http/request-context.d.ts +8 -0
- package/dist/http/request-context.js +37 -0
- package/dist/http/service-client.d.ts +93 -40
- package/dist/http/service-client.js +104 -55
- package/dist/index.d.ts +11 -9
- package/dist/index.js +2 -0
- package/dist/jwt/index.d.ts +3 -2
- package/dist/jwt/index.js +2 -1
- package/dist/jwt/machine-jwt-verifier.d.ts +21 -0
- package/dist/jwt/machine-jwt-verifier.js +83 -0
- package/dist/jwt/machine-token-client.d.ts +36 -5
- package/dist/jwt/machine-token-client.js +61 -27
- package/dist/jwt/user-jwt-verifier.d.ts +31 -0
- package/dist/jwt/user-jwt-verifier.js +102 -0
- package/dist/messaging/audit.publisher.d.ts +14 -0
- package/dist/messaging/audit.publisher.js +49 -0
- package/dist/messaging/index.d.ts +2 -0
- package/dist/{dto → messaging}/index.js +2 -3
- package/dist/messaging/rabbitmq.client.d.ts +15 -0
- package/dist/messaging/rabbitmq.client.js +133 -0
- package/dist/middleware/error-handler.middleware.d.ts +8 -28
- package/dist/middleware/error-handler.middleware.js +63 -54
- package/dist/middleware/index.d.ts +10 -8
- package/dist/middleware/index.js +7 -5
- package/dist/middleware/request-context.middleware.d.ts +6 -0
- package/dist/middleware/request-context.middleware.js +48 -0
- package/dist/middleware/require-auth.middleware.d.ts +7 -76
- package/dist/middleware/require-auth.middleware.js +29 -117
- package/dist/middleware/require-machine.middleware.d.ts +13 -0
- package/dist/middleware/require-machine.middleware.js +128 -0
- package/dist/middleware/require-org-permission-from-body.middleware.d.ts +10 -0
- package/dist/middleware/require-org-permission-from-body.middleware.js +23 -0
- package/dist/middleware/require-org-permission.middleware.d.ts +19 -0
- package/dist/middleware/require-org-permission.middleware.js +115 -0
- package/dist/middleware/require-platform-permission.middleware.d.ts +19 -0
- package/dist/middleware/require-platform-permission.middleware.js +91 -0
- package/dist/middleware/require-user.middleware.d.ts +14 -0
- package/dist/middleware/require-user.middleware.js +30 -0
- package/dist/middleware/require-workspace-permission.middleware.d.ts +20 -0
- package/dist/middleware/require-workspace-permission.middleware.js +114 -0
- package/dist/middleware/validate.middleware.d.ts +31 -31
- package/dist/middleware/validate.middleware.js +31 -33
- package/dist/types/audit.types.d.ts +39 -0
- package/dist/types/audit.types.js +30 -0
- package/dist/types/express.types.d.ts +92 -124
- package/dist/types/express.types.js +30 -49
- package/dist/types/index.d.ts +1 -1
- package/dist/utils/date.util.d.ts +6 -0
- package/dist/utils/date.util.js +11 -0
- package/dist/utils/env.util.d.ts +6 -0
- package/dist/utils/env.util.js +19 -0
- package/dist/utils/index.d.ts +5 -4
- package/dist/utils/index.js +5 -4
- package/dist/utils/logger.util.d.ts +31 -0
- package/dist/utils/logger.util.js +91 -0
- package/dist/utils/pagination.util.d.ts +6 -0
- package/dist/utils/pagination.util.js +20 -0
- package/dist/utils/request-context.als.d.ts +10 -0
- package/dist/utils/request-context.als.js +5 -0
- package/dist/utils/response.util.d.ts +27 -0
- package/dist/utils/response.util.js +56 -0
- package/dist/utils/slug.util.d.ts +9 -0
- package/dist/utils/slug.util.js +32 -0
- package/dist/utils/url-safety.util.d.ts +6 -0
- package/dist/utils/url-safety.util.js +75 -0
- package/package.json +3 -1
- package/dist/authorization/permissions.d.ts +0 -78
- package/dist/authorization/permissions.js +0 -174
- package/dist/context/access-context.d.ts +0 -10
- package/dist/context/access-context.js +0 -2
- package/dist/dto/auth-service.dtos.d.ts +0 -44
- package/dist/dto/auth-service.dtos.js +0 -2
- package/dist/dto/index.d.ts +0 -3
- package/dist/dto/response.dtos.d.ts +0 -55
- package/dist/dto/response.dtos.js +0 -6
- package/dist/dto/user-service.dtos.d.ts +0 -50
- package/dist/dto/user-service.dtos.js +0 -2
- package/dist/enums/auth-service.enums.d.ts +0 -12
- package/dist/enums/auth-service.enums.js +0 -17
- package/dist/enums/permissions.types.d.ts +0 -12
- package/dist/enums/permissions.types.js +0 -17
- package/dist/enums/user-service.enums.d.ts +0 -32
- package/dist/enums/user-service.enums.js +0 -41
- package/dist/internal/index.d.ts +0 -4
- package/dist/internal/index.js +0 -20
- package/dist/internal/internal-jwt.service.d.ts +0 -13
- package/dist/internal/internal-jwt.service.js +0 -88
- package/dist/internal/internal-jwt.types.d.ts +0 -7
- package/dist/internal/internal-jwt.types.js +0 -2
- package/dist/internal/internal-key-manager.d.ts +0 -16
- package/dist/internal/internal-key-manager.js +0 -67
- package/dist/internal/registry.d.ts +0 -8
- package/dist/internal/registry.js +0 -34
- package/dist/internal/service-client.d.ts +0 -9
- package/dist/internal/service-client.js +0 -94
- package/dist/jwt/internal-jwt-verifier.d.ts +0 -41
- package/dist/jwt/internal-jwt-verifier.js +0 -185
- package/dist/jwt/jwt-verifier.d.ts +0 -9
- package/dist/jwt/jwt-verifier.js +0 -36
- package/dist/jwt/service-client.d.ts +0 -7
- package/dist/jwt/service-client.js +0 -87
- package/dist/middleware/authorize.d.ts +0 -3
- package/dist/middleware/authorize.js +0 -24
- package/dist/middleware/authorize.middleware.d.ts +0 -54
- package/dist/middleware/authorize.middleware.js +0 -104
- package/dist/middleware/error-handler.d.ts +0 -4
- package/dist/middleware/error-handler.js +0 -23
- package/dist/middleware/request-id.d.ts +0 -2
- package/dist/middleware/request-id.js +0 -9
- package/dist/middleware/request-id.middleware.d.ts +0 -22
- package/dist/middleware/request-id.middleware.js +0 -34
- package/dist/middleware/require-auth.d.ts +0 -10
- package/dist/middleware/require-auth.js +0 -34
- package/dist/middleware/require-human.middleware.d.ts +0 -2
- package/dist/middleware/require-human.middleware.js +0 -18
- package/dist/middleware/require-internal.middleware.d.ts +0 -18
- package/dist/middleware/require-internal.middleware.js +0 -183
- package/dist/middleware/validate.d.ts +0 -5
- package/dist/middleware/validate.js +0 -18
- package/dist/middleware/validated-merge.middleware.d.ts +0 -20
- package/dist/middleware/validated-merge.middleware.js +0 -33
- package/dist/middleware/verify-internal-jwt.d.ts +0 -7
- package/dist/middleware/verify-internal-jwt.js +0 -25
- package/dist/security/guard.d.ts +0 -10
- package/dist/security/guard.js +0 -40
- package/dist/security/index.d.ts +0 -1
- package/dist/types/express.d.ts +0 -22
- package/dist/types/express.js +0 -3
- package/dist/utils/date.utils.d.ts +0 -25
- package/dist/utils/date.utils.js +0 -30
- package/dist/utils/env.d.ts +0 -46
- package/dist/utils/env.js +0 -61
- package/dist/utils/env.utils.d.ts +0 -46
- package/dist/utils/env.utils.js +0 -61
- package/dist/utils/logger.utils.d.ts +0 -66
- package/dist/utils/logger.utils.js +0 -97
- package/dist/utils/response.d.ts +0 -4
- package/dist/utils/response.js +0 -35
- package/dist/utils/response.utils.d.ts +0 -54
- package/dist/utils/response.utils.js +0 -85
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* @file require-platform-permission.middleware.ts
|
|
4
|
+
* @description Express middleware generator to enforce platform-scoped permission checks.
|
|
5
|
+
*/
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.createRequirePlatformPermission = void 0;
|
|
8
|
+
const permission_checker_1 = require("../authorization/permission-checker");
|
|
9
|
+
const utils_1 = require("../utils");
|
|
10
|
+
/**
|
|
11
|
+
* Creates requirePlatformPermission middleware.
|
|
12
|
+
*
|
|
13
|
+
* @param {PermissionCacheService} permissionCache - Shared Redis cache service.
|
|
14
|
+
* @param {(accountId: string) => Promise<string[]>} resolveFn - Cache miss database/API lookup function.
|
|
15
|
+
* @returns {object} Platform permission middlewares.
|
|
16
|
+
*/
|
|
17
|
+
const createRequirePlatformPermission = (permissionCache, resolveFn) => {
|
|
18
|
+
const requirePlatformPermission = (permission) => {
|
|
19
|
+
return async (req, res, next) => {
|
|
20
|
+
const ctx = req.authContext;
|
|
21
|
+
if (!ctx || ctx.type !== 'user') {
|
|
22
|
+
(0, utils_1.failure)(res, req, 'Unauthorized: No access context', 'UNAUTHORIZED', 401);
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
try {
|
|
26
|
+
const perms = await permissionCache.resolvePlatformPermissions(ctx.accountId, async () => {
|
|
27
|
+
return resolveFn(ctx.accountId);
|
|
28
|
+
});
|
|
29
|
+
if (!permission_checker_1.PermissionChecker.has(perms, permission)) {
|
|
30
|
+
(0, utils_1.failure)(res, req, `Forbidden: Missing required platform permission: ${permission}`, 'FORBIDDEN', 403);
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
next();
|
|
34
|
+
}
|
|
35
|
+
catch (err) {
|
|
36
|
+
next(err);
|
|
37
|
+
}
|
|
38
|
+
};
|
|
39
|
+
};
|
|
40
|
+
const requireAnyPlatformPermission = (...permissions) => {
|
|
41
|
+
return async (req, res, next) => {
|
|
42
|
+
const ctx = req.authContext;
|
|
43
|
+
if (!ctx || ctx.type !== 'user') {
|
|
44
|
+
(0, utils_1.failure)(res, req, 'Unauthorized: No access context', 'UNAUTHORIZED', 401);
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
try {
|
|
48
|
+
const perms = await permissionCache.resolvePlatformPermissions(ctx.accountId, async () => {
|
|
49
|
+
return resolveFn(ctx.accountId);
|
|
50
|
+
});
|
|
51
|
+
if (!permission_checker_1.PermissionChecker.hasAny(perms, permissions)) {
|
|
52
|
+
(0, utils_1.failure)(res, req, `Forbidden: Missing one of required platform permissions: [${permissions.join(', ')}]`, 'FORBIDDEN', 403);
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
55
|
+
next();
|
|
56
|
+
}
|
|
57
|
+
catch (err) {
|
|
58
|
+
next(err);
|
|
59
|
+
}
|
|
60
|
+
};
|
|
61
|
+
};
|
|
62
|
+
const requireAllPlatformPermissions = (...permissions) => {
|
|
63
|
+
return async (req, res, next) => {
|
|
64
|
+
const ctx = req.authContext;
|
|
65
|
+
if (!ctx || ctx.type !== 'user') {
|
|
66
|
+
(0, utils_1.failure)(res, req, 'Unauthorized: No access context', 'UNAUTHORIZED', 401);
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
try {
|
|
70
|
+
const perms = await permissionCache.resolvePlatformPermissions(ctx.accountId, async () => {
|
|
71
|
+
return resolveFn(ctx.accountId);
|
|
72
|
+
});
|
|
73
|
+
if (!permission_checker_1.PermissionChecker.hasAll(perms, permissions)) {
|
|
74
|
+
const missing = permissions.filter((p) => !permission_checker_1.PermissionChecker.has(perms, p));
|
|
75
|
+
(0, utils_1.failure)(res, req, `Forbidden: Missing required platform permissions: [${missing.join(', ')}]`, 'FORBIDDEN', 403);
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
next();
|
|
79
|
+
}
|
|
80
|
+
catch (err) {
|
|
81
|
+
next(err);
|
|
82
|
+
}
|
|
83
|
+
};
|
|
84
|
+
};
|
|
85
|
+
return {
|
|
86
|
+
requirePlatformPermission,
|
|
87
|
+
requireAnyPlatformPermission,
|
|
88
|
+
requireAllPlatformPermissions,
|
|
89
|
+
};
|
|
90
|
+
};
|
|
91
|
+
exports.createRequirePlatformPermission = createRequirePlatformPermission;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file require-user.middleware.ts
|
|
3
|
+
* @description Express middleware to assert that the request auth context belongs to a user (not a machine).
|
|
4
|
+
*/
|
|
5
|
+
import { Request, Response, NextFunction } from 'express';
|
|
6
|
+
/**
|
|
7
|
+
* Asserts that the current request has a valid user context, returning 401/403 otherwise.
|
|
8
|
+
*
|
|
9
|
+
* @param {Request} req - Express request object.
|
|
10
|
+
* @param {Response} res - Express response object.
|
|
11
|
+
* @param {NextFunction} next - Express next middleware function.
|
|
12
|
+
* @returns {void}
|
|
13
|
+
*/
|
|
14
|
+
export declare const requireUser: (req: Request, res: Response, next: NextFunction) => void;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* @file require-user.middleware.ts
|
|
4
|
+
* @description Express middleware to assert that the request auth context belongs to a user (not a machine).
|
|
5
|
+
*/
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.requireUser = void 0;
|
|
8
|
+
const utils_1 = require("../utils");
|
|
9
|
+
const types_1 = require("../types");
|
|
10
|
+
/**
|
|
11
|
+
* Asserts that the current request has a valid user context, returning 401/403 otherwise.
|
|
12
|
+
*
|
|
13
|
+
* @param {Request} req - Express request object.
|
|
14
|
+
* @param {Response} res - Express response object.
|
|
15
|
+
* @param {NextFunction} next - Express next middleware function.
|
|
16
|
+
* @returns {void}
|
|
17
|
+
*/
|
|
18
|
+
const requireUser = (req, res, next) => {
|
|
19
|
+
const ctx = req.authContext;
|
|
20
|
+
if (!ctx) {
|
|
21
|
+
(0, utils_1.failure)(res, req, 'Unauthorized: No auth context', 'UNAUTHORIZED', 401);
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
if (!(0, types_1.isUserContext)(ctx)) {
|
|
25
|
+
(0, utils_1.failure)(res, req, 'User token required', 'FORBIDDEN', 401);
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
next();
|
|
29
|
+
};
|
|
30
|
+
exports.requireUser = requireUser;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file require-workspace-permission.middleware.ts
|
|
3
|
+
* @description Express middleware factory to enforce workspace-scoped permission checks.
|
|
4
|
+
*/
|
|
5
|
+
import { RequestHandler } from 'express';
|
|
6
|
+
import { Permission } from '../enums';
|
|
7
|
+
import { PermissionCacheService } from '../authorization/permission-cache.service';
|
|
8
|
+
/**
|
|
9
|
+
* Creates requireWorkspacePermission middleware factory.
|
|
10
|
+
*
|
|
11
|
+
* @param {PermissionCacheService} permissionCache - Shared Redis cache service.
|
|
12
|
+
* @param {(accountId: string, workspaceId: string) => Promise<string[]>} resolveFn
|
|
13
|
+
* - Function called on a cache miss to fetch the caller's permission strings for the workspace.
|
|
14
|
+
* @returns {object} Workspace permission middlewares.
|
|
15
|
+
*/
|
|
16
|
+
export declare const createRequireWorkspacePermission: (permissionCache: PermissionCacheService, resolveFn: (accountId: string, workspaceId: string) => Promise<string[]>) => {
|
|
17
|
+
requireWorkspacePermission: (permission: Permission) => RequestHandler;
|
|
18
|
+
requireAnyWorkspacePermission: (...permissions: Permission[]) => RequestHandler;
|
|
19
|
+
requireAllWorkspacePermissions: (...permissions: Permission[]) => RequestHandler;
|
|
20
|
+
};
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* @file require-workspace-permission.middleware.ts
|
|
4
|
+
* @description Express middleware factory to enforce workspace-scoped permission checks.
|
|
5
|
+
*/
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.createRequireWorkspacePermission = void 0;
|
|
8
|
+
const permission_checker_1 = require("../authorization/permission-checker");
|
|
9
|
+
const utils_1 = require("../utils");
|
|
10
|
+
/**
|
|
11
|
+
* Creates requireWorkspacePermission middleware factory.
|
|
12
|
+
*
|
|
13
|
+
* @param {PermissionCacheService} permissionCache - Shared Redis cache service.
|
|
14
|
+
* @param {(accountId: string, workspaceId: string) => Promise<string[]>} resolveFn
|
|
15
|
+
* - Function called on a cache miss to fetch the caller's permission strings for the workspace.
|
|
16
|
+
* @returns {object} Workspace permission middlewares.
|
|
17
|
+
*/
|
|
18
|
+
const createRequireWorkspacePermission = (permissionCache, resolveFn) => {
|
|
19
|
+
const requireWorkspacePermission = (permission) => {
|
|
20
|
+
return async (req, res, next) => {
|
|
21
|
+
const ctx = req.authContext;
|
|
22
|
+
if (!ctx || ctx.type !== 'user') {
|
|
23
|
+
(0, utils_1.failure)(res, req, 'Unauthorized: No access context', 'UNAUTHORIZED', 401);
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
// Resolve workspaceId from request locations
|
|
27
|
+
const workspaceId = req.params['workspaceId'] ??
|
|
28
|
+
req.validated?.params?.['workspaceId'] ??
|
|
29
|
+
req.validated?.body?.['workspaceId'];
|
|
30
|
+
if (!workspaceId || typeof workspaceId !== 'string') {
|
|
31
|
+
(0, utils_1.failure)(res, req, 'Bad Request: Missing workspaceId', 'BAD_REQUEST', 400);
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
try {
|
|
35
|
+
const perms = await permissionCache.resolveWorkspacePermissions(ctx.accountId, workspaceId, async () => {
|
|
36
|
+
return resolveFn(ctx.accountId, workspaceId);
|
|
37
|
+
});
|
|
38
|
+
if (!permission_checker_1.PermissionChecker.has(perms, permission)) {
|
|
39
|
+
(0, utils_1.failure)(res, req, `Forbidden: Missing required workspace permission: ${permission}`, 'FORBIDDEN', 403);
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
next();
|
|
43
|
+
}
|
|
44
|
+
catch (err) {
|
|
45
|
+
next(err);
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
};
|
|
49
|
+
const requireAnyWorkspacePermission = (...permissions) => {
|
|
50
|
+
return async (req, res, next) => {
|
|
51
|
+
const ctx = req.authContext;
|
|
52
|
+
if (!ctx || ctx.type !== 'user') {
|
|
53
|
+
(0, utils_1.failure)(res, req, 'Unauthorized: No access context', 'UNAUTHORIZED', 401);
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
const workspaceId = req.params['workspaceId'] ??
|
|
57
|
+
req.validated?.params?.['workspaceId'] ??
|
|
58
|
+
req.validated?.body?.['workspaceId'];
|
|
59
|
+
if (!workspaceId || typeof workspaceId !== 'string') {
|
|
60
|
+
(0, utils_1.failure)(res, req, 'Bad Request: Missing workspaceId', 'BAD_REQUEST', 400);
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
try {
|
|
64
|
+
const perms = await permissionCache.resolveWorkspacePermissions(ctx.accountId, workspaceId, async () => {
|
|
65
|
+
return resolveFn(ctx.accountId, workspaceId);
|
|
66
|
+
});
|
|
67
|
+
if (!permission_checker_1.PermissionChecker.hasAny(perms, permissions)) {
|
|
68
|
+
(0, utils_1.failure)(res, req, `Forbidden: Missing one of required workspace permissions: [${permissions.join(', ')}]`, 'FORBIDDEN', 403);
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
next();
|
|
72
|
+
}
|
|
73
|
+
catch (err) {
|
|
74
|
+
next(err);
|
|
75
|
+
}
|
|
76
|
+
};
|
|
77
|
+
};
|
|
78
|
+
const requireAllWorkspacePermissions = (...permissions) => {
|
|
79
|
+
return async (req, res, next) => {
|
|
80
|
+
const ctx = req.authContext;
|
|
81
|
+
if (!ctx || ctx.type !== 'user') {
|
|
82
|
+
(0, utils_1.failure)(res, req, 'Unauthorized: No access context', 'UNAUTHORIZED', 401);
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
const workspaceId = req.params['workspaceId'] ??
|
|
86
|
+
req.validated?.params?.['workspaceId'] ??
|
|
87
|
+
req.validated?.body?.['workspaceId'];
|
|
88
|
+
if (!workspaceId || typeof workspaceId !== 'string') {
|
|
89
|
+
(0, utils_1.failure)(res, req, 'Bad Request: Missing workspaceId', 'BAD_REQUEST', 400);
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
try {
|
|
93
|
+
const perms = await permissionCache.resolveWorkspacePermissions(ctx.accountId, workspaceId, async () => {
|
|
94
|
+
return resolveFn(ctx.accountId, workspaceId);
|
|
95
|
+
});
|
|
96
|
+
if (!permission_checker_1.PermissionChecker.hasAll(perms, permissions)) {
|
|
97
|
+
const missing = permissions.filter((p) => !permission_checker_1.PermissionChecker.has(perms, p));
|
|
98
|
+
(0, utils_1.failure)(res, req, `Forbidden: Missing required workspace permissions: [${missing.join(', ')}]`, 'FORBIDDEN', 403);
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
101
|
+
next();
|
|
102
|
+
}
|
|
103
|
+
catch (err) {
|
|
104
|
+
next(err);
|
|
105
|
+
}
|
|
106
|
+
};
|
|
107
|
+
};
|
|
108
|
+
return {
|
|
109
|
+
requireWorkspacePermission,
|
|
110
|
+
requireAnyWorkspacePermission,
|
|
111
|
+
requireAllWorkspacePermissions,
|
|
112
|
+
};
|
|
113
|
+
};
|
|
114
|
+
exports.createRequireWorkspacePermission = createRequireWorkspacePermission;
|
|
@@ -1,35 +1,35 @@
|
|
|
1
|
-
import { Request, Response, NextFunction } from "express";
|
|
2
|
-
import { ZodType } from "zod";
|
|
3
1
|
/**
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
*
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
*
|
|
16
|
-
* Narrowing req.validated in a controller:
|
|
17
|
-
* req.validated is typed as unknown in express.d.ts — consumers must
|
|
18
|
-
* narrow it to the schema's inferred type at the call site:
|
|
19
|
-
*
|
|
20
|
-
* const body = req.validated as z.infer<typeof CreateOrderSchema>;
|
|
21
|
-
*
|
|
22
|
-
* This is intentional: the middleware is schema-agnostic and cannot
|
|
23
|
-
* carry the generic type through Express's untyped req object.
|
|
24
|
-
*
|
|
25
|
-
* Usage:
|
|
26
|
-
* router.post(
|
|
27
|
-
* "/orders",
|
|
28
|
-
* requireAuth,
|
|
29
|
-
* Validator.validate(CreateOrderSchema, "body"),
|
|
30
|
-
* controller.create,
|
|
31
|
-
* );
|
|
2
|
+
* @file validate.middleware.ts
|
|
3
|
+
* @description Request validation middleware leveraging Zod schema definitions.
|
|
4
|
+
* Supports validating multiple request sources without overwriting previous results.
|
|
5
|
+
*/
|
|
6
|
+
import { Request, Response, NextFunction } from 'express';
|
|
7
|
+
import { ZodType } from 'zod';
|
|
8
|
+
/**
|
|
9
|
+
* Supported Express request validation sources.
|
|
10
|
+
*/
|
|
11
|
+
type ValidationSource = 'body' | 'params' | 'query' | 'headers';
|
|
12
|
+
/**
|
|
13
|
+
* Validator utility class containing Express middleware generation methods.
|
|
32
14
|
*/
|
|
33
15
|
export declare class Validator {
|
|
34
|
-
|
|
16
|
+
/**
|
|
17
|
+
* Generates middleware to parse and validate request parts.
|
|
18
|
+
*
|
|
19
|
+
* Validated data is stored by source:
|
|
20
|
+
*
|
|
21
|
+
* req.validated = {
|
|
22
|
+
* params: {},
|
|
23
|
+
* query: {},
|
|
24
|
+
* body: {},
|
|
25
|
+
* headers: {}
|
|
26
|
+
* }
|
|
27
|
+
*
|
|
28
|
+
* Multiple validators can safely run on the same request.
|
|
29
|
+
*
|
|
30
|
+
* @param {ZodType<T>} schema - Zod validation schema.
|
|
31
|
+
* @param {ValidationSource} source - Request source.
|
|
32
|
+
*/
|
|
33
|
+
static validate<T>(schema: ZodType<T>, source?: ValidationSource): (req: Request, _res: Response, next: NextFunction) => void;
|
|
35
34
|
}
|
|
35
|
+
export {};
|
|
@@ -1,48 +1,46 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* @file validate.middleware.ts
|
|
4
|
+
* @description Request validation middleware leveraging Zod schema definitions.
|
|
5
|
+
* Supports validating multiple request sources without overwriting previous results.
|
|
6
|
+
*/
|
|
2
7
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
8
|
exports.Validator = void 0;
|
|
4
9
|
/**
|
|
5
|
-
*
|
|
6
|
-
* ────────────────────────────────────────────────
|
|
7
|
-
* Validates and parses request input against a Zod schema.
|
|
8
|
-
* On success, attaches the parsed (coerced + stripped) data to req.validated.
|
|
9
|
-
* On failure, passes the ZodError to next() → GlobalErrorHandler → 400.
|
|
10
|
-
*
|
|
11
|
-
* Source options:
|
|
12
|
-
* "body" — req.body (POST/PUT/PATCH payloads)
|
|
13
|
-
* "params" — req.params (URL path parameters)
|
|
14
|
-
* "query" — req.query (URL query string)
|
|
15
|
-
* "headers" — req.headers (custom header validation, e.g. API keys)
|
|
16
|
-
*
|
|
17
|
-
* Narrowing req.validated in a controller:
|
|
18
|
-
* req.validated is typed as unknown in express.d.ts — consumers must
|
|
19
|
-
* narrow it to the schema's inferred type at the call site:
|
|
20
|
-
*
|
|
21
|
-
* const body = req.validated as z.infer<typeof CreateOrderSchema>;
|
|
22
|
-
*
|
|
23
|
-
* This is intentional: the middleware is schema-agnostic and cannot
|
|
24
|
-
* carry the generic type through Express's untyped req object.
|
|
25
|
-
*
|
|
26
|
-
* Usage:
|
|
27
|
-
* router.post(
|
|
28
|
-
* "/orders",
|
|
29
|
-
* requireAuth,
|
|
30
|
-
* Validator.validate(CreateOrderSchema, "body"),
|
|
31
|
-
* controller.create,
|
|
32
|
-
* );
|
|
10
|
+
* Validator utility class containing Express middleware generation methods.
|
|
33
11
|
*/
|
|
34
12
|
class Validator {
|
|
35
|
-
|
|
13
|
+
/**
|
|
14
|
+
* Generates middleware to parse and validate request parts.
|
|
15
|
+
*
|
|
16
|
+
* Validated data is stored by source:
|
|
17
|
+
*
|
|
18
|
+
* req.validated = {
|
|
19
|
+
* params: {},
|
|
20
|
+
* query: {},
|
|
21
|
+
* body: {},
|
|
22
|
+
* headers: {}
|
|
23
|
+
* }
|
|
24
|
+
*
|
|
25
|
+
* Multiple validators can safely run on the same request.
|
|
26
|
+
*
|
|
27
|
+
* @param {ZodType<T>} schema - Zod validation schema.
|
|
28
|
+
* @param {ValidationSource} source - Request source.
|
|
29
|
+
*/
|
|
30
|
+
static validate(schema, source = 'body') {
|
|
36
31
|
return (req, _res, next) => {
|
|
37
32
|
const result = schema.safeParse(req[source]);
|
|
38
33
|
if (!result.success) {
|
|
39
|
-
// Pass the ZodError to GlobalErrorHandler — it flattens and returns 400.
|
|
40
34
|
next(result.error);
|
|
41
35
|
return;
|
|
42
36
|
}
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
37
|
+
req.validated = {
|
|
38
|
+
...(req.validated ?? {}),
|
|
39
|
+
[source]: {
|
|
40
|
+
...(req.validated?.[source] ?? {}),
|
|
41
|
+
...result.data,
|
|
42
|
+
},
|
|
43
|
+
};
|
|
46
44
|
next();
|
|
47
45
|
};
|
|
48
46
|
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
export declare enum AuditActorType {
|
|
2
|
+
USER = "USER",
|
|
3
|
+
SERVICE = "SERVICE",
|
|
4
|
+
SYSTEM = "SYSTEM",
|
|
5
|
+
ANONYMOUS = "ANONYMOUS",
|
|
6
|
+
SUPPORT = "SUPPORT",
|
|
7
|
+
INTEGRATION = "INTEGRATION",
|
|
8
|
+
API_KEY = "API_KEY"
|
|
9
|
+
}
|
|
10
|
+
export declare enum AuditResourceType {
|
|
11
|
+
ACCOUNT = "ACCOUNT",
|
|
12
|
+
USER = "USER",
|
|
13
|
+
ORGANIZATION = "ORGANIZATION",
|
|
14
|
+
WORKSPACE = "WORKSPACE",
|
|
15
|
+
ROLE = "ROLE",
|
|
16
|
+
PERMISSION = "PERMISSION",
|
|
17
|
+
PLATFORM_ROLE = "PLATFORM_ROLE",
|
|
18
|
+
PLATFORM_PERMISSION = "PLATFORM_PERMISSION",
|
|
19
|
+
SESSION = "SESSION",
|
|
20
|
+
SERVICE_CLIENT = "SERVICE_CLIENT",
|
|
21
|
+
MFA = "MFA",
|
|
22
|
+
SYSTEM = "SYSTEM",// e.g. for system cron jobs
|
|
23
|
+
INVITE = "INVITE"
|
|
24
|
+
}
|
|
25
|
+
export declare const AUDIT_SEVERITIES: readonly ["info", "warning", "error", "critical"];
|
|
26
|
+
export type AuditSeverity = (typeof AUDIT_SEVERITIES)[number];
|
|
27
|
+
export interface RecordAuditActionInput {
|
|
28
|
+
actorId?: string | null;
|
|
29
|
+
actorType?: AuditActorType;
|
|
30
|
+
action: string;
|
|
31
|
+
severity?: AuditSeverity;
|
|
32
|
+
resourceType: AuditResourceType;
|
|
33
|
+
resourceId?: string | null;
|
|
34
|
+
organizationId?: string | null;
|
|
35
|
+
workspaceId?: string | null;
|
|
36
|
+
metadata?: Record<string, any>;
|
|
37
|
+
requestId?: string | null;
|
|
38
|
+
traceId?: string | null;
|
|
39
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.AUDIT_SEVERITIES = exports.AuditResourceType = exports.AuditActorType = void 0;
|
|
4
|
+
var AuditActorType;
|
|
5
|
+
(function (AuditActorType) {
|
|
6
|
+
AuditActorType["USER"] = "USER";
|
|
7
|
+
AuditActorType["SERVICE"] = "SERVICE";
|
|
8
|
+
AuditActorType["SYSTEM"] = "SYSTEM";
|
|
9
|
+
AuditActorType["ANONYMOUS"] = "ANONYMOUS";
|
|
10
|
+
AuditActorType["SUPPORT"] = "SUPPORT";
|
|
11
|
+
AuditActorType["INTEGRATION"] = "INTEGRATION";
|
|
12
|
+
AuditActorType["API_KEY"] = "API_KEY";
|
|
13
|
+
})(AuditActorType || (exports.AuditActorType = AuditActorType = {}));
|
|
14
|
+
var AuditResourceType;
|
|
15
|
+
(function (AuditResourceType) {
|
|
16
|
+
AuditResourceType["ACCOUNT"] = "ACCOUNT";
|
|
17
|
+
AuditResourceType["USER"] = "USER";
|
|
18
|
+
AuditResourceType["ORGANIZATION"] = "ORGANIZATION";
|
|
19
|
+
AuditResourceType["WORKSPACE"] = "WORKSPACE";
|
|
20
|
+
AuditResourceType["ROLE"] = "ROLE";
|
|
21
|
+
AuditResourceType["PERMISSION"] = "PERMISSION";
|
|
22
|
+
AuditResourceType["PLATFORM_ROLE"] = "PLATFORM_ROLE";
|
|
23
|
+
AuditResourceType["PLATFORM_PERMISSION"] = "PLATFORM_PERMISSION";
|
|
24
|
+
AuditResourceType["SESSION"] = "SESSION";
|
|
25
|
+
AuditResourceType["SERVICE_CLIENT"] = "SERVICE_CLIENT";
|
|
26
|
+
AuditResourceType["MFA"] = "MFA";
|
|
27
|
+
AuditResourceType["SYSTEM"] = "SYSTEM";
|
|
28
|
+
AuditResourceType["INVITE"] = "INVITE";
|
|
29
|
+
})(AuditResourceType || (exports.AuditResourceType = AuditResourceType = {}));
|
|
30
|
+
exports.AUDIT_SEVERITIES = ["info", "warning", "error", "critical"];
|