@discover-cloud/shared 1.0.11 → 1.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/authorization/permission-cache.service.d.ts +14 -1
- package/dist/authorization/permission-cache.service.js +84 -16
- package/dist/authorization/permissions.d.ts +19 -15
- package/dist/authorization/permissions.js +24 -21
- package/dist/dtos/auth-service.dto.d.ts +13 -0
- package/dist/dtos/cloud-service.dto.d.ts +25 -10
- package/dist/dtos/insights-service.dto.d.ts +24 -8
- package/dist/dtos/response.dto.d.ts +80 -10
- package/dist/dtos/response.dto.js +23 -4
- package/dist/dtos/user-service.dto.d.ts +7 -0
- package/dist/enums/domain.enums.d.ts +45 -14
- package/dist/enums/domain.enums.js +40 -6
- package/dist/enums/permissions.enums.d.ts +12 -52
- package/dist/enums/permissions.enums.js +55 -59
- package/dist/errors/app-error.d.ts +17 -14
- package/dist/errors/app-error.js +19 -15
- package/dist/errors/http-errors.d.ts +12 -5
- package/dist/errors/http-errors.js +27 -5
- package/dist/http/service-client.d.ts +37 -12
- package/dist/http/service-client.js +43 -17
- package/dist/jwt/internal-jwt-verifier.d.ts +9 -3
- package/dist/jwt/internal-jwt-verifier.js +49 -26
- package/dist/middleware/authorize.middleware.d.ts +38 -6
- package/dist/middleware/authorize.middleware.js +62 -37
- package/dist/middleware/error-handler.middleware.d.ts +21 -7
- package/dist/middleware/error-handler.middleware.js +42 -14
- package/dist/middleware/request-id.middleware.d.ts +12 -10
- package/dist/middleware/request-id.middleware.js +15 -15
- package/dist/middleware/validate.middleware.d.ts +22 -13
- package/dist/middleware/validate.middleware.js +25 -16
- package/dist/middleware/validated-merge.middleware.js +1 -2
- package/dist/types/express.types.d.ts +37 -32
- package/dist/types/express.types.js +13 -11
- package/dist/utils/date.utils.d.ts +18 -4
- package/dist/utils/date.utils.js +18 -4
- package/dist/utils/env.d.ts +46 -0
- package/dist/utils/env.js +61 -0
- package/dist/utils/logger.utils.d.ts +31 -16
- package/dist/utils/logger.utils.js +55 -20
- package/dist/utils/response.utils.d.ts +47 -5
- package/dist/utils/response.utils.js +50 -7
- package/package.json +1 -1
|
@@ -1,6 +1,25 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
2
|
+
/**
|
|
3
|
+
* RESPONSE DTOs (@discover-cloud/shared)
|
|
4
|
+
* ─────────────────────────────────────────
|
|
5
|
+
* Shared HTTP response shapes used across all services.
|
|
6
|
+
* Every response — success or error — is wrapped in the ApiSuccessResponse
|
|
7
|
+
* or ApiErrorResponse envelope so clients have a consistent shape to key on.
|
|
8
|
+
*
|
|
9
|
+
* Envelope shape:
|
|
10
|
+
* {
|
|
11
|
+
* success: true,
|
|
12
|
+
* data: T,
|
|
13
|
+
* meta: { requestId, timestamp }
|
|
14
|
+
* }
|
|
15
|
+
* or
|
|
16
|
+
* {
|
|
17
|
+
* success: false,
|
|
18
|
+
* error: { code, message, details? },
|
|
19
|
+
* meta: { requestId, timestamp }
|
|
20
|
+
* }
|
|
21
|
+
*
|
|
22
|
+
* The success() and failure() utils in shared/utils construct these
|
|
23
|
+
* envelopes — don't build them manually in controllers.
|
|
24
|
+
*/
|
|
6
25
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
@@ -1,4 +1,11 @@
|
|
|
1
1
|
import { OrganizationRole, MembershipStatus, OrganizationStatus, Theme, Currency } from "../enums";
|
|
2
|
+
/**
|
|
3
|
+
* USER SERVICE DTOs (@discover-cloud/shared)
|
|
4
|
+
* ─────────────────────────────────────────────
|
|
5
|
+
* Shapes returned by the user service over HTTP.
|
|
6
|
+
* All timestamps are ISO 8601 strings — JSON has no Date type.
|
|
7
|
+
* Domain models use Date internally; mappers convert at the boundary.
|
|
8
|
+
*/
|
|
2
9
|
export interface UserDto {
|
|
3
10
|
id: string;
|
|
4
11
|
email: string;
|
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* DOMAIN STATUS & CONFIGURATION ENUMS
|
|
3
|
-
*
|
|
2
|
+
* DOMAIN STATUS & CONFIGURATION ENUMS (@discover-cloud/shared)
|
|
3
|
+
* ───────────────────────────────────────────────────────────────
|
|
4
4
|
* General-purpose enums for entity lifecycle, UI preferences, and
|
|
5
|
-
*
|
|
5
|
+
* cloud provider configuration.
|
|
6
|
+
*
|
|
7
|
+
* Permission-related enums (AccountRole, GlobalPermission, OrganizationRole,
|
|
8
|
+
* OrgPermission) live in permissions.enums.ts, not here.
|
|
6
9
|
*/
|
|
7
10
|
export declare enum AccountStatus {
|
|
8
11
|
ACTIVE = "ACTIVE",
|
|
@@ -40,17 +43,45 @@ export declare enum CloudProvider {
|
|
|
40
43
|
GCP = "GCP",
|
|
41
44
|
AZURE = "AZURE"
|
|
42
45
|
}
|
|
46
|
+
/**
|
|
47
|
+
* AWS auth methods.
|
|
48
|
+
*
|
|
49
|
+
* ACCESS_KEY — Long-lived Access Key ID + Secret Access Key.
|
|
50
|
+
* Simplest to set up; least preferred for production.
|
|
51
|
+
* IAM_ROLE — Cross-account role assumption via Role ARN + External ID.
|
|
52
|
+
* Recommended for production AWS integrations.
|
|
53
|
+
* IAM_IDENTITY_CENTER — AWS SSO / IAM Identity Center (formerly AWS SSO).
|
|
54
|
+
* Used in organisations with centralised identity.
|
|
55
|
+
* IAM_ROLES_ANYWHERE — Certificate-based role assumption for non-AWS workloads.
|
|
56
|
+
*/
|
|
43
57
|
export declare enum AwsAuthMethod {
|
|
44
|
-
ACCESS_KEY = "ACCESS_KEY"
|
|
45
|
-
IAM_ROLE = "IAM_ROLE"
|
|
46
|
-
IAM_IDENTITY_CENTER = "IAM_IDENTITY_CENTER"
|
|
58
|
+
ACCESS_KEY = "ACCESS_KEY",
|
|
59
|
+
IAM_ROLE = "IAM_ROLE",
|
|
60
|
+
IAM_IDENTITY_CENTER = "IAM_IDENTITY_CENTER",
|
|
47
61
|
IAM_ROLES_ANYWHERE = "IAM_ROLES_ANYWHERE"
|
|
48
62
|
}
|
|
63
|
+
/**
|
|
64
|
+
* GCP auth methods.
|
|
65
|
+
*
|
|
66
|
+
* SERVICE_ACCOUNT_KEY — JSON key file for a GCP service account.
|
|
67
|
+
* Simpler but requires secure key storage.
|
|
68
|
+
* WORKLOAD_IDENTITY — Keyless auth using Workload Identity Federation.
|
|
69
|
+
* Preferred for production.
|
|
70
|
+
* SERVICE_ACCOUNT_IMPERSONATION — Short-lived tokens via service account impersonation.
|
|
71
|
+
*/
|
|
49
72
|
export declare enum GcpAuthMethod {
|
|
50
73
|
SERVICE_ACCOUNT_KEY = "SERVICE_ACCOUNT_KEY",
|
|
51
74
|
WORKLOAD_IDENTITY = "WORKLOAD_IDENTITY",
|
|
52
75
|
SERVICE_ACCOUNT_IMPERSONATION = "SERVICE_ACCOUNT_IMPERSONATION"
|
|
53
76
|
}
|
|
77
|
+
/**
|
|
78
|
+
* Azure auth methods.
|
|
79
|
+
*
|
|
80
|
+
* SERVICE_PRINCIPAL_SECRET — Client ID + Client Secret for an app registration.
|
|
81
|
+
* SERVICE_PRINCIPAL_CERTIFICATE — Client ID + certificate (more secure than secret).
|
|
82
|
+
* MANAGED_IDENTITY_USER — User-assigned managed identity.
|
|
83
|
+
* MANAGED_IDENTITY_SYSTEM — System-assigned managed identity (tied to the resource).
|
|
84
|
+
*/
|
|
54
85
|
export declare enum AzureAuthMethod {
|
|
55
86
|
SERVICE_PRINCIPAL_SECRET = "SERVICE_PRINCIPAL_SECRET",
|
|
56
87
|
SERVICE_PRINCIPAL_CERTIFICATE = "SERVICE_PRINCIPAL_CERTIFICATE",
|
|
@@ -58,20 +89,20 @@ export declare enum AzureAuthMethod {
|
|
|
58
89
|
MANAGED_IDENTITY_SYSTEM = "MANAGED_IDENTITY_SYSTEM"
|
|
59
90
|
}
|
|
60
91
|
export declare enum CloudAccountStatus {
|
|
61
|
-
PENDING = "PENDING",// Connected
|
|
62
|
-
ACTIVE = "ACTIVE",// Last sync
|
|
63
|
-
ERROR = "ERROR",// Last sync failed
|
|
92
|
+
PENDING = "PENDING",// Connected but never successfully synced
|
|
93
|
+
ACTIVE = "ACTIVE",// Last sync completed successfully
|
|
94
|
+
ERROR = "ERROR",// Last sync failed — check lastErrorMsg
|
|
64
95
|
INACTIVE = "INACTIVE"
|
|
65
96
|
}
|
|
66
97
|
export declare enum SyncStatus {
|
|
67
|
-
PENDING = "PENDING",
|
|
68
|
-
RUNNING = "RUNNING"
|
|
69
|
-
SUCCESS = "SUCCESS"
|
|
70
|
-
FAILED = "FAILED"
|
|
98
|
+
PENDING = "PENDING",// Queued, not yet picked up by the scheduler
|
|
99
|
+
RUNNING = "RUNNING",// Currently in progress
|
|
100
|
+
SUCCESS = "SUCCESS",// All fetches completed without error
|
|
101
|
+
FAILED = "FAILED",// All fetches failed; no data was written
|
|
71
102
|
PARTIAL = "PARTIAL"
|
|
72
103
|
}
|
|
73
104
|
export declare enum SyncType {
|
|
74
|
-
FULL = "FULL",// All data types
|
|
105
|
+
FULL = "FULL",// All data types in one job
|
|
75
106
|
COSTS = "COSTS",// Cost records only
|
|
76
107
|
RESOURCES = "RESOURCES",// Resource inventory only
|
|
77
108
|
BUDGETS = "BUDGETS"
|
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
/**
|
|
3
|
-
* DOMAIN STATUS & CONFIGURATION ENUMS
|
|
4
|
-
*
|
|
3
|
+
* DOMAIN STATUS & CONFIGURATION ENUMS (@discover-cloud/shared)
|
|
4
|
+
* ───────────────────────────────────────────────────────────────
|
|
5
5
|
* General-purpose enums for entity lifecycle, UI preferences, and
|
|
6
|
-
*
|
|
6
|
+
* cloud provider configuration.
|
|
7
|
+
*
|
|
8
|
+
* Permission-related enums (AccountRole, GlobalPermission, OrganizationRole,
|
|
9
|
+
* OrgPermission) live in permissions.enums.ts, not here.
|
|
7
10
|
*/
|
|
8
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
12
|
exports.SyncType = exports.SyncStatus = exports.CloudAccountStatus = exports.AzureAuthMethod = exports.GcpAuthMethod = exports.AwsAuthMethod = exports.CloudProvider = exports.Currency = exports.Theme = exports.MembershipStatus = exports.OrganizationStatus = exports.AccountStatus = void 0;
|
|
@@ -54,8 +57,8 @@ var Currency;
|
|
|
54
57
|
})(Currency || (exports.Currency = Currency = {}));
|
|
55
58
|
/* ====================================================================
|
|
56
59
|
CLOUD PROVIDERS
|
|
57
|
-
Used by cloud-service for account connections and insights-service
|
|
58
|
-
for
|
|
60
|
+
Used by cloud-service for account connections, and by insights-service
|
|
61
|
+
for normalising cost/resource data across providers.
|
|
59
62
|
==================================================================== */
|
|
60
63
|
var CloudProvider;
|
|
61
64
|
(function (CloudProvider) {
|
|
@@ -66,8 +69,20 @@ var CloudProvider;
|
|
|
66
69
|
/* ====================================================================
|
|
67
70
|
CLOUD ACCOUNT AUTH METHODS
|
|
68
71
|
Discriminator for which credential shape is stored per provider.
|
|
69
|
-
Each provider has its own enum —
|
|
72
|
+
Each provider has its own enum — exactly one is set per CloudAccount
|
|
73
|
+
and determines how the credential cipher stores + retrieves secrets.
|
|
70
74
|
==================================================================== */
|
|
75
|
+
/**
|
|
76
|
+
* AWS auth methods.
|
|
77
|
+
*
|
|
78
|
+
* ACCESS_KEY — Long-lived Access Key ID + Secret Access Key.
|
|
79
|
+
* Simplest to set up; least preferred for production.
|
|
80
|
+
* IAM_ROLE — Cross-account role assumption via Role ARN + External ID.
|
|
81
|
+
* Recommended for production AWS integrations.
|
|
82
|
+
* IAM_IDENTITY_CENTER — AWS SSO / IAM Identity Center (formerly AWS SSO).
|
|
83
|
+
* Used in organisations with centralised identity.
|
|
84
|
+
* IAM_ROLES_ANYWHERE — Certificate-based role assumption for non-AWS workloads.
|
|
85
|
+
*/
|
|
71
86
|
var AwsAuthMethod;
|
|
72
87
|
(function (AwsAuthMethod) {
|
|
73
88
|
AwsAuthMethod["ACCESS_KEY"] = "ACCESS_KEY";
|
|
@@ -75,12 +90,29 @@ var AwsAuthMethod;
|
|
|
75
90
|
AwsAuthMethod["IAM_IDENTITY_CENTER"] = "IAM_IDENTITY_CENTER";
|
|
76
91
|
AwsAuthMethod["IAM_ROLES_ANYWHERE"] = "IAM_ROLES_ANYWHERE";
|
|
77
92
|
})(AwsAuthMethod || (exports.AwsAuthMethod = AwsAuthMethod = {}));
|
|
93
|
+
/**
|
|
94
|
+
* GCP auth methods.
|
|
95
|
+
*
|
|
96
|
+
* SERVICE_ACCOUNT_KEY — JSON key file for a GCP service account.
|
|
97
|
+
* Simpler but requires secure key storage.
|
|
98
|
+
* WORKLOAD_IDENTITY — Keyless auth using Workload Identity Federation.
|
|
99
|
+
* Preferred for production.
|
|
100
|
+
* SERVICE_ACCOUNT_IMPERSONATION — Short-lived tokens via service account impersonation.
|
|
101
|
+
*/
|
|
78
102
|
var GcpAuthMethod;
|
|
79
103
|
(function (GcpAuthMethod) {
|
|
80
104
|
GcpAuthMethod["SERVICE_ACCOUNT_KEY"] = "SERVICE_ACCOUNT_KEY";
|
|
81
105
|
GcpAuthMethod["WORKLOAD_IDENTITY"] = "WORKLOAD_IDENTITY";
|
|
82
106
|
GcpAuthMethod["SERVICE_ACCOUNT_IMPERSONATION"] = "SERVICE_ACCOUNT_IMPERSONATION";
|
|
83
107
|
})(GcpAuthMethod || (exports.GcpAuthMethod = GcpAuthMethod = {}));
|
|
108
|
+
/**
|
|
109
|
+
* Azure auth methods.
|
|
110
|
+
*
|
|
111
|
+
* SERVICE_PRINCIPAL_SECRET — Client ID + Client Secret for an app registration.
|
|
112
|
+
* SERVICE_PRINCIPAL_CERTIFICATE — Client ID + certificate (more secure than secret).
|
|
113
|
+
* MANAGED_IDENTITY_USER — User-assigned managed identity.
|
|
114
|
+
* MANAGED_IDENTITY_SYSTEM — System-assigned managed identity (tied to the resource).
|
|
115
|
+
*/
|
|
84
116
|
var AzureAuthMethod;
|
|
85
117
|
(function (AzureAuthMethod) {
|
|
86
118
|
AzureAuthMethod["SERVICE_PRINCIPAL_SECRET"] = "SERVICE_PRINCIPAL_SECRET";
|
|
@@ -90,6 +122,7 @@ var AzureAuthMethod;
|
|
|
90
122
|
})(AzureAuthMethod || (exports.AzureAuthMethod = AzureAuthMethod = {}));
|
|
91
123
|
/* ====================================================================
|
|
92
124
|
CLOUD ACCOUNT STATUS
|
|
125
|
+
Lifecycle state of a connected cloud account.
|
|
93
126
|
==================================================================== */
|
|
94
127
|
var CloudAccountStatus;
|
|
95
128
|
(function (CloudAccountStatus) {
|
|
@@ -100,6 +133,7 @@ var CloudAccountStatus;
|
|
|
100
133
|
})(CloudAccountStatus || (exports.CloudAccountStatus = CloudAccountStatus = {}));
|
|
101
134
|
/* ====================================================================
|
|
102
135
|
SYNC JOB
|
|
136
|
+
Tracks the lifecycle and scope of a single sync run.
|
|
103
137
|
==================================================================== */
|
|
104
138
|
var SyncStatus;
|
|
105
139
|
(function (SyncStatus) {
|
|
@@ -1,9 +1,17 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
* Platform-level roles
|
|
5
|
-
*
|
|
2
|
+
* PERMISSION ENUMS (@discover-cloud/shared)
|
|
3
|
+
* ────────────────────────────────────────────
|
|
4
|
+
* Platform-level roles and permissions. These are the single source of
|
|
5
|
+
* truth for the entire permission system — the Redis permission cache,
|
|
6
|
+
* JWT payloads, and route guards all derive from these definitions.
|
|
6
7
|
*
|
|
8
|
+
* File layout:
|
|
9
|
+
* AccountRole — platform-level account roles (highest → lowest privilege)
|
|
10
|
+
* GlobalPermission — platform-wide permissions derived from AccountRole
|
|
11
|
+
* OrganizationRole — per-org roles (future)
|
|
12
|
+
* OrgPermission — per-org permissions checked by tenant middleware (future)
|
|
13
|
+
*/
|
|
14
|
+
/**
|
|
7
15
|
* SUPERADMIN — Full platform control. Internal engineering / founders only.
|
|
8
16
|
* Can impersonate users, access all data, manage platform config.
|
|
9
17
|
*
|
|
@@ -26,40 +34,6 @@ export declare enum AccountRole {
|
|
|
26
34
|
MODERATOR = "MODERATOR",
|
|
27
35
|
USER = "USER"
|
|
28
36
|
}
|
|
29
|
-
/**
|
|
30
|
-
* GLOBAL PERMISSIONS
|
|
31
|
-
* ───────────────────
|
|
32
|
-
* Platform-wide permissions derived from AccountRole.
|
|
33
|
-
* These are checked at the gateway / service middleware level.
|
|
34
|
-
*
|
|
35
|
-
* Naming convention: VERB_NOUN or VERB_SCOPE_NOUN
|
|
36
|
-
*
|
|
37
|
-
* Account management
|
|
38
|
-
* MANAGE_ACCOUNTS — Create, update, suspend, delete any account
|
|
39
|
-
* VIEW_ANY_ACCOUNT — Read any account's profile and metadata
|
|
40
|
-
* IMPERSONATE_ACCOUNT — Act as another user (SUPERADMIN only — support tooling)
|
|
41
|
-
* SUSPEND_ACCOUNT — Suspend / unsuspend an account without full delete
|
|
42
|
-
* DELETE_ACCOUNT — Hard delete an account and all associated data
|
|
43
|
-
*
|
|
44
|
-
* Cloud cost data (platform-level, not per-org)
|
|
45
|
-
* VIEW_ANY_COST_DATA — Read any user's cloud cost reports (support/admin use)
|
|
46
|
-
* EXPORT_ANY_COST_DATA — Export cost data for any user (compliance, support)
|
|
47
|
-
* MANAGE_COST_ALERTS — Create/edit/delete cost alert rules platform-wide
|
|
48
|
-
*
|
|
49
|
-
* Platform operations
|
|
50
|
-
* VIEW_SYSTEM_LOGS — Access platform audit logs and system events
|
|
51
|
-
* VIEW_SYSTEM_HEALTH — Read service health, metrics dashboards
|
|
52
|
-
* MANAGE_PLATFORM_CONFIG — Modify platform-wide settings (limits, features)
|
|
53
|
-
*
|
|
54
|
-
* Support tooling
|
|
55
|
-
* SUPPORT_VIEW — Read-only access to user data for support purposes
|
|
56
|
-
* SUPPORT_WRITE — Ability to make support-sanctioned changes on behalf of users
|
|
57
|
-
*
|
|
58
|
-
* Future-proofing (define now, assign later)
|
|
59
|
-
* MANAGE_BILLING — Access to subscription and billing management
|
|
60
|
-
* MODERATE_CONTENT — Moderate user-generated content (alerts, comments, etc.)
|
|
61
|
-
* MANAGE_INTEGRATIONS — Manage platform-level cloud provider integrations
|
|
62
|
-
*/
|
|
63
37
|
export declare enum GlobalPermission {
|
|
64
38
|
MANAGE_ACCOUNTS = "MANAGE_ACCOUNTS",
|
|
65
39
|
VIEW_ANY_ACCOUNT = "VIEW_ANY_ACCOUNT",
|
|
@@ -79,11 +53,6 @@ export declare enum GlobalPermission {
|
|
|
79
53
|
MANAGE_INTEGRATIONS = "MANAGE_INTEGRATIONS"
|
|
80
54
|
}
|
|
81
55
|
/**
|
|
82
|
-
* ORGANIZATION ROLES (future work)
|
|
83
|
-
* ────────────────────────────────────
|
|
84
|
-
* Defined now so the type system is ready when org support ships.
|
|
85
|
-
* No permissions are assigned yet — see orgRolePermissions below.
|
|
86
|
-
*
|
|
87
56
|
* OWNER — Created the org. Full control, including deletion and billing.
|
|
88
57
|
* ADMIN — Manages members and org settings. Cannot delete the org.
|
|
89
58
|
* EDITOR — Can create/edit cost reports and dashboards within the org.
|
|
@@ -97,15 +66,6 @@ export declare enum OrganizationRole {
|
|
|
97
66
|
VIEWER = "VIEWER",
|
|
98
67
|
BILLING = "BILLING"
|
|
99
68
|
}
|
|
100
|
-
/**
|
|
101
|
-
* ORG PERMISSIONS (future work)
|
|
102
|
-
* ────────────────────────────────
|
|
103
|
-
* Granular org-scoped permissions. Checked by tenant middleware in each
|
|
104
|
-
* service via DB lookup — NOT in the JWT (org membership changes too
|
|
105
|
-
* frequently to embed reliably).
|
|
106
|
-
*
|
|
107
|
-
* Naming: VERB_RESOURCE
|
|
108
|
-
*/
|
|
109
69
|
export declare enum OrgPermission {
|
|
110
70
|
DELETE_ORG = "DELETE_ORG",
|
|
111
71
|
MANAGE_ORG_SETTINGS = "MANAGE_ORG_SETTINGS",
|
|
@@ -1,12 +1,24 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* PERMISSION ENUMS (@discover-cloud/shared)
|
|
4
|
+
* ────────────────────────────────────────────
|
|
5
|
+
* Platform-level roles and permissions. These are the single source of
|
|
6
|
+
* truth for the entire permission system — the Redis permission cache,
|
|
7
|
+
* JWT payloads, and route guards all derive from these definitions.
|
|
8
|
+
*
|
|
9
|
+
* File layout:
|
|
10
|
+
* AccountRole — platform-level account roles (highest → lowest privilege)
|
|
11
|
+
* GlobalPermission — platform-wide permissions derived from AccountRole
|
|
12
|
+
* OrganizationRole — per-org roles (future)
|
|
13
|
+
* OrgPermission — per-org permissions checked by tenant middleware (future)
|
|
14
|
+
*/
|
|
2
15
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
16
|
exports.OrgPermission = exports.OrganizationRole = exports.GlobalPermission = exports.AccountRole = void 0;
|
|
17
|
+
/* ====================================================================
|
|
18
|
+
ACCOUNT ROLES
|
|
19
|
+
Ordered from highest to lowest privilege.
|
|
20
|
+
==================================================================== */
|
|
4
21
|
/**
|
|
5
|
-
* ACCOUNT ROLES
|
|
6
|
-
* ──────────────
|
|
7
|
-
* Platform-level roles assigned to every account.
|
|
8
|
-
* Ordered from highest to lowest privilege.
|
|
9
|
-
*
|
|
10
22
|
* SUPERADMIN — Full platform control. Internal engineering / founders only.
|
|
11
23
|
* Can impersonate users, access all data, manage platform config.
|
|
12
24
|
*
|
|
@@ -30,70 +42,55 @@ var AccountRole;
|
|
|
30
42
|
AccountRole["MODERATOR"] = "MODERATOR";
|
|
31
43
|
AccountRole["USER"] = "USER";
|
|
32
44
|
})(AccountRole || (exports.AccountRole = AccountRole = {}));
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
*
|
|
41
|
-
* Account management
|
|
42
|
-
* MANAGE_ACCOUNTS — Create, update, suspend, delete any account
|
|
43
|
-
* VIEW_ANY_ACCOUNT — Read any account's profile and metadata
|
|
44
|
-
* IMPERSONATE_ACCOUNT — Act as another user (SUPERADMIN only — support tooling)
|
|
45
|
-
* SUSPEND_ACCOUNT — Suspend / unsuspend an account without full delete
|
|
46
|
-
* DELETE_ACCOUNT — Hard delete an account and all associated data
|
|
47
|
-
*
|
|
48
|
-
* Cloud cost data (platform-level, not per-org)
|
|
49
|
-
* VIEW_ANY_COST_DATA — Read any user's cloud cost reports (support/admin use)
|
|
50
|
-
* EXPORT_ANY_COST_DATA — Export cost data for any user (compliance, support)
|
|
51
|
-
* MANAGE_COST_ALERTS — Create/edit/delete cost alert rules platform-wide
|
|
52
|
-
*
|
|
53
|
-
* Platform operations
|
|
54
|
-
* VIEW_SYSTEM_LOGS — Access platform audit logs and system events
|
|
55
|
-
* VIEW_SYSTEM_HEALTH — Read service health, metrics dashboards
|
|
56
|
-
* MANAGE_PLATFORM_CONFIG — Modify platform-wide settings (limits, features)
|
|
57
|
-
*
|
|
58
|
-
* Support tooling
|
|
59
|
-
* SUPPORT_VIEW — Read-only access to user data for support purposes
|
|
60
|
-
* SUPPORT_WRITE — Ability to make support-sanctioned changes on behalf of users
|
|
61
|
-
*
|
|
62
|
-
* Future-proofing (define now, assign later)
|
|
63
|
-
* MANAGE_BILLING — Access to subscription and billing management
|
|
64
|
-
* MODERATE_CONTENT — Moderate user-generated content (alerts, comments, etc.)
|
|
65
|
-
* MANAGE_INTEGRATIONS — Manage platform-level cloud provider integrations
|
|
66
|
-
*/
|
|
45
|
+
/* ====================================================================
|
|
46
|
+
GLOBAL PERMISSIONS
|
|
47
|
+
Platform-wide permissions derived from AccountRole.
|
|
48
|
+
Checked at the gateway / service middleware level via Redis cache.
|
|
49
|
+
|
|
50
|
+
Naming convention: VERB_NOUN or VERB_SCOPE_NOUN
|
|
51
|
+
==================================================================== */
|
|
67
52
|
var GlobalPermission;
|
|
68
53
|
(function (GlobalPermission) {
|
|
69
|
-
// Account management
|
|
54
|
+
// ── Account management ────────────────────────────────────────────
|
|
55
|
+
// MANAGE_ACCOUNTS — Create, update, suspend, delete any account
|
|
56
|
+
// VIEW_ANY_ACCOUNT — Read any account's profile and metadata
|
|
57
|
+
// IMPERSONATE_ACCOUNT — Act as another user (SUPERADMIN only)
|
|
58
|
+
// SUSPEND_ACCOUNT — Suspend / unsuspend without full delete
|
|
59
|
+
// DELETE_ACCOUNT — Hard delete an account and all associated data
|
|
70
60
|
GlobalPermission["MANAGE_ACCOUNTS"] = "MANAGE_ACCOUNTS";
|
|
71
61
|
GlobalPermission["VIEW_ANY_ACCOUNT"] = "VIEW_ANY_ACCOUNT";
|
|
72
62
|
GlobalPermission["IMPERSONATE_ACCOUNT"] = "IMPERSONATE_ACCOUNT";
|
|
73
63
|
GlobalPermission["SUSPEND_ACCOUNT"] = "SUSPEND_ACCOUNT";
|
|
74
64
|
GlobalPermission["DELETE_ACCOUNT"] = "DELETE_ACCOUNT";
|
|
75
|
-
// Cloud cost data (platform-level)
|
|
65
|
+
// ── Cloud cost data (platform-level, not per-org) ─────────────────
|
|
66
|
+
// VIEW_ANY_COST_DATA — Read any user's cloud cost reports
|
|
67
|
+
// EXPORT_ANY_COST_DATA — Export cost data for any user (compliance)
|
|
68
|
+
// MANAGE_COST_ALERTS — Create/edit/delete alert rules platform-wide
|
|
76
69
|
GlobalPermission["VIEW_ANY_COST_DATA"] = "VIEW_ANY_COST_DATA";
|
|
77
70
|
GlobalPermission["EXPORT_ANY_COST_DATA"] = "EXPORT_ANY_COST_DATA";
|
|
78
71
|
GlobalPermission["MANAGE_COST_ALERTS"] = "MANAGE_COST_ALERTS";
|
|
79
|
-
// Platform operations
|
|
72
|
+
// ── Platform operations ───────────────────────────────────────────
|
|
73
|
+
// VIEW_SYSTEM_LOGS — Access platform audit logs and system events
|
|
74
|
+
// VIEW_SYSTEM_HEALTH — Read service health and metrics dashboards
|
|
75
|
+
// MANAGE_PLATFORM_CONFIG — Modify platform-wide settings (limits, features)
|
|
80
76
|
GlobalPermission["VIEW_SYSTEM_LOGS"] = "VIEW_SYSTEM_LOGS";
|
|
81
77
|
GlobalPermission["VIEW_SYSTEM_HEALTH"] = "VIEW_SYSTEM_HEALTH";
|
|
82
78
|
GlobalPermission["MANAGE_PLATFORM_CONFIG"] = "MANAGE_PLATFORM_CONFIG";
|
|
83
|
-
// Support tooling
|
|
79
|
+
// ── Support tooling ───────────────────────────────────────────────
|
|
80
|
+
// SUPPORT_VIEW — Read-only access to user data for support purposes
|
|
81
|
+
// SUPPORT_WRITE — Support-sanctioned changes on behalf of users
|
|
84
82
|
GlobalPermission["SUPPORT_VIEW"] = "SUPPORT_VIEW";
|
|
85
83
|
GlobalPermission["SUPPORT_WRITE"] = "SUPPORT_WRITE";
|
|
86
|
-
// Future —
|
|
84
|
+
// ── Future — defined now so they exist in the type system ─────────
|
|
87
85
|
GlobalPermission["MANAGE_BILLING"] = "MANAGE_BILLING";
|
|
88
86
|
GlobalPermission["MODERATE_CONTENT"] = "MODERATE_CONTENT";
|
|
89
87
|
GlobalPermission["MANAGE_INTEGRATIONS"] = "MANAGE_INTEGRATIONS";
|
|
90
88
|
})(GlobalPermission || (exports.GlobalPermission = GlobalPermission = {}));
|
|
89
|
+
/* ====================================================================
|
|
90
|
+
ORGANIZATION ROLES (future work)
|
|
91
|
+
Defined now so the type system is ready when org support ships.
|
|
92
|
+
==================================================================== */
|
|
91
93
|
/**
|
|
92
|
-
* ORGANIZATION ROLES (future work)
|
|
93
|
-
* ────────────────────────────────────
|
|
94
|
-
* Defined now so the type system is ready when org support ships.
|
|
95
|
-
* No permissions are assigned yet — see orgRolePermissions below.
|
|
96
|
-
*
|
|
97
94
|
* OWNER — Created the org. Full control, including deletion and billing.
|
|
98
95
|
* ADMIN — Manages members and org settings. Cannot delete the org.
|
|
99
96
|
* EDITOR — Can create/edit cost reports and dashboards within the org.
|
|
@@ -108,15 +105,14 @@ var OrganizationRole;
|
|
|
108
105
|
OrganizationRole["VIEWER"] = "VIEWER";
|
|
109
106
|
OrganizationRole["BILLING"] = "BILLING";
|
|
110
107
|
})(OrganizationRole || (exports.OrganizationRole = OrganizationRole = {}));
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
*/
|
|
108
|
+
/* ====================================================================
|
|
109
|
+
ORG PERMISSIONS (future work)
|
|
110
|
+
Granular org-scoped permissions checked by tenant middleware in each
|
|
111
|
+
service via DB lookup — NOT embedded in the JWT (org membership changes
|
|
112
|
+
too frequently to embed reliably).
|
|
113
|
+
|
|
114
|
+
Naming: VERB_RESOURCE
|
|
115
|
+
==================================================================== */
|
|
120
116
|
var OrgPermission;
|
|
121
117
|
(function (OrgPermission) {
|
|
122
118
|
// Org management
|
|
@@ -132,7 +128,7 @@ var OrgPermission;
|
|
|
132
128
|
OrgPermission["EXPORT_COST_DATA"] = "EXPORT_COST_DATA";
|
|
133
129
|
OrgPermission["MANAGE_COST_REPORTS"] = "MANAGE_COST_REPORTS";
|
|
134
130
|
OrgPermission["MANAGE_ALERTS"] = "MANAGE_ALERTS";
|
|
135
|
-
//
|
|
131
|
+
// Cloud account integrations within org
|
|
136
132
|
OrgPermission["MANAGE_CLOUD_ACCOUNTS"] = "MANAGE_CLOUD_ACCOUNTS";
|
|
137
133
|
OrgPermission["VIEW_CLOUD_ACCOUNTS"] = "VIEW_CLOUD_ACCOUNTS";
|
|
138
134
|
// Billing within org
|
|
@@ -1,19 +1,22 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* APP ERROR
|
|
3
|
-
*
|
|
4
|
-
* Base class for all known operational errors.
|
|
5
|
-
* Subclasses map to specific HTTP status codes and
|
|
2
|
+
* APP ERROR (@discover-cloud/shared)
|
|
3
|
+
* ─────────────────────────────────────
|
|
4
|
+
* Base class for all known operational errors across every service.
|
|
5
|
+
* Subclasses (see http-errors.ts) map to specific HTTP status codes and
|
|
6
|
+
* error codes that the global error handler serialises into responses.
|
|
6
7
|
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
8
|
+
* Design decisions:
|
|
9
|
+
* - GlobalErrorHandler catches `instanceof AppError` — no duck-typing,
|
|
10
|
+
* no accidental matches on arbitrary thrown objects.
|
|
11
|
+
* - details?: unknown (not any) — TypeScript's type checking is preserved
|
|
12
|
+
* on the most variable field. Callers that need a specific details shape
|
|
13
|
+
* should cast after an instanceof guard.
|
|
14
|
+
* - Object.freeze(this) — prevents accidental post-construction mutation of
|
|
15
|
+
* a thrown error. Freeze is shallow: if details is an object, its contents
|
|
16
|
+
* remain mutable. This is acceptable — details is for logging/response
|
|
17
|
+
* context, not program logic.
|
|
18
|
+
* - captureStackTrace — strips the AppError constructor frame from the stack
|
|
19
|
+
* so the trace points to the throw site, not the base class constructor.
|
|
17
20
|
*/
|
|
18
21
|
export declare class AppError extends Error {
|
|
19
22
|
readonly code: string;
|
package/dist/errors/app-error.js
CHANGED
|
@@ -2,21 +2,24 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.AppError = void 0;
|
|
4
4
|
/**
|
|
5
|
-
* APP ERROR
|
|
6
|
-
*
|
|
7
|
-
* Base class for all known operational errors.
|
|
8
|
-
* Subclasses map to specific HTTP status codes and
|
|
5
|
+
* APP ERROR (@discover-cloud/shared)
|
|
6
|
+
* ─────────────────────────────────────
|
|
7
|
+
* Base class for all known operational errors across every service.
|
|
8
|
+
* Subclasses (see http-errors.ts) map to specific HTTP status codes and
|
|
9
|
+
* error codes that the global error handler serialises into responses.
|
|
9
10
|
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
11
|
+
* Design decisions:
|
|
12
|
+
* - GlobalErrorHandler catches `instanceof AppError` — no duck-typing,
|
|
13
|
+
* no accidental matches on arbitrary thrown objects.
|
|
14
|
+
* - details?: unknown (not any) — TypeScript's type checking is preserved
|
|
15
|
+
* on the most variable field. Callers that need a specific details shape
|
|
16
|
+
* should cast after an instanceof guard.
|
|
17
|
+
* - Object.freeze(this) — prevents accidental post-construction mutation of
|
|
18
|
+
* a thrown error. Freeze is shallow: if details is an object, its contents
|
|
19
|
+
* remain mutable. This is acceptable — details is for logging/response
|
|
20
|
+
* context, not program logic.
|
|
21
|
+
* - captureStackTrace — strips the AppError constructor frame from the stack
|
|
22
|
+
* so the trace points to the throw site, not the base class constructor.
|
|
20
23
|
*/
|
|
21
24
|
class AppError extends Error {
|
|
22
25
|
constructor(code, statusCode, message, details) {
|
|
@@ -24,7 +27,8 @@ class AppError extends Error {
|
|
|
24
27
|
this.code = code;
|
|
25
28
|
this.statusCode = statusCode;
|
|
26
29
|
this.details = details;
|
|
27
|
-
this.name = this.constructor.name;
|
|
30
|
+
this.name = this.constructor.name; // "NotFoundError", "ConflictError", etc.
|
|
31
|
+
// Available in V8 (Node.js / Chrome) — no-ops gracefully in other engines.
|
|
28
32
|
if (typeof Error.captureStackTrace === "function") {
|
|
29
33
|
Error.captureStackTrace(this, this.constructor);
|
|
30
34
|
}
|
|
@@ -1,15 +1,22 @@
|
|
|
1
1
|
import { AppError } from "./app-error";
|
|
2
2
|
/**
|
|
3
|
-
* HTTP ERRORS
|
|
4
|
-
*
|
|
3
|
+
* HTTP ERRORS (@discover-cloud/shared)
|
|
4
|
+
* ───────────────────────────────────────
|
|
5
5
|
* Typed subclasses of AppError for every common HTTP error status.
|
|
6
|
-
*
|
|
7
|
-
*
|
|
6
|
+
*
|
|
7
|
+
* GlobalErrorHandler catches these via `instanceof AppError` and maps
|
|
8
|
+
* statusCode + code directly to the response — no additional switch/if needed.
|
|
8
9
|
*
|
|
9
10
|
* Usage:
|
|
10
11
|
* throw new NotFoundError("Account not found");
|
|
11
12
|
* throw new ConflictError("Email already in use");
|
|
12
|
-
* throw new BadRequestError("
|
|
13
|
+
* throw new BadRequestError("Validation failed", { field: "email" });
|
|
14
|
+
*
|
|
15
|
+
* Adding a new error type:
|
|
16
|
+
* 1. Add a subclass here following the existing pattern.
|
|
17
|
+
* 2. Pick the correct HTTP status code.
|
|
18
|
+
* 3. Choose a SCREAMING_SNAKE_CASE code that is stable across versions
|
|
19
|
+
* (clients may key on it for error handling).
|
|
13
20
|
*/
|
|
14
21
|
export declare class BadRequestError extends AppError {
|
|
15
22
|
constructor(message?: string, details?: unknown);
|