permissions-contractx 1.6.0 → 2.0.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/constants/contractx-roles.constants.d.ts +41 -23
- package/dist/constants/contractx-roles.constants.d.ts.map +1 -1
- package/dist/constants/contractx-roles.constants.js +73 -53
- package/dist/constants/security.constants.js +1 -1
- package/dist/decorators/contract-scoped.decorator.d.ts +25 -0
- package/dist/decorators/contract-scoped.decorator.d.ts.map +1 -0
- package/dist/decorators/contract-scoped.decorator.js +29 -0
- package/dist/decorators/index.d.ts +1 -0
- package/dist/decorators/index.d.ts.map +1 -1
- package/dist/decorators/index.js +1 -0
- package/dist/decorators/roles.decorator.d.ts.map +1 -1
- package/dist/decorators/roles.decorator.js +7 -6
- package/dist/guards/authorization.guard.d.ts +14 -0
- package/dist/guards/authorization.guard.d.ts.map +1 -1
- package/dist/guards/authorization.guard.js +63 -1
- package/dist/interfaces/jwt-payload.interface.d.ts +9 -0
- package/dist/interfaces/jwt-payload.interface.d.ts.map +1 -1
- package/dist/services/contractx-authorization.service.js +3 -3
- package/dist/services/user-context.service.js +1 -1
- package/package.json +1 -1
|
@@ -1,6 +1,14 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* ContractX Role Constants
|
|
3
|
-
*
|
|
3
|
+
* ------------------------------------------------------------------------
|
|
4
|
+
* FUENTE DE VERDAD: el servicio de Auth (`contractx-Auth`,
|
|
5
|
+
* `src/common/constants/security.constants.ts` → `ROLES`). Estas constantes
|
|
6
|
+
* DEBEN reflejar exactamente los `code` de rol que Auth emite en el claim
|
|
7
|
+
* `role[]` del JWT. Cualquier divergencia (p. ej. `superadmin` vs `super_admin`,
|
|
8
|
+
* `*_manager` vs `*_resp`) rompe la comparación de roles en los guards.
|
|
9
|
+
*
|
|
10
|
+
* Matriz v5 (14 roles de negocio) + `support`. Reconciliado con Auth (2026-06).
|
|
11
|
+
* ------------------------------------------------------------------------
|
|
4
12
|
*/
|
|
5
13
|
export declare enum ContractXRoleType {
|
|
6
14
|
ADMIN = "admin",
|
|
@@ -18,23 +26,24 @@ export declare enum ContractXRoleScope {
|
|
|
18
26
|
TEAM = "team"
|
|
19
27
|
}
|
|
20
28
|
export declare const CONTRACTX_ROLES: {
|
|
21
|
-
|
|
29
|
+
SUPER_ADMIN: string;
|
|
22
30
|
SUPPORT: string;
|
|
31
|
+
CLIENT_SUPERADMIN: string;
|
|
23
32
|
CLIENT_CONTRACT_ADMIN: string;
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
33
|
+
CLIENT_PERFORMANCE_RESP: string;
|
|
34
|
+
CLIENT_FINANCE_RESP: string;
|
|
35
|
+
CLIENT_REPORTS_RESP: string;
|
|
36
|
+
CLIENT_RELATIONSHIP_RESP: string;
|
|
37
|
+
CLIENT_RISK_RESP: string;
|
|
29
38
|
PROVIDER_CONTRACT_ADMIN: string;
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
39
|
+
PROVIDER_PERFORMANCE_RESP: string;
|
|
40
|
+
PROVIDER_FINANCE_RESP: string;
|
|
41
|
+
PROVIDER_REPORTS_RESP: string;
|
|
42
|
+
PROVIDER_RELATIONSHIP_RESP: string;
|
|
43
|
+
PROVIDER_RISK_RESP: string;
|
|
35
44
|
};
|
|
36
45
|
export declare const CONTRACTX_ROLE_DEFINITIONS: {
|
|
37
|
-
[CONTRACTX_ROLES.
|
|
46
|
+
[CONTRACTX_ROLES.SUPER_ADMIN]: {
|
|
38
47
|
name: string;
|
|
39
48
|
description: string;
|
|
40
49
|
type: ContractXRoleType;
|
|
@@ -52,6 +61,15 @@ export declare const CONTRACTX_ROLE_DEFINITIONS: {
|
|
|
52
61
|
isSystem: boolean;
|
|
53
62
|
tenant: string;
|
|
54
63
|
};
|
|
64
|
+
[CONTRACTX_ROLES.CLIENT_SUPERADMIN]: {
|
|
65
|
+
name: string;
|
|
66
|
+
description: string;
|
|
67
|
+
type: ContractXRoleType;
|
|
68
|
+
scope: ContractXRoleScope;
|
|
69
|
+
level: number;
|
|
70
|
+
isSystem: boolean;
|
|
71
|
+
tenant: string;
|
|
72
|
+
};
|
|
55
73
|
[CONTRACTX_ROLES.CLIENT_CONTRACT_ADMIN]: {
|
|
56
74
|
name: string;
|
|
57
75
|
description: string;
|
|
@@ -61,7 +79,7 @@ export declare const CONTRACTX_ROLE_DEFINITIONS: {
|
|
|
61
79
|
isSystem: boolean;
|
|
62
80
|
tenant: string;
|
|
63
81
|
};
|
|
64
|
-
[CONTRACTX_ROLES.
|
|
82
|
+
[CONTRACTX_ROLES.CLIENT_PERFORMANCE_RESP]: {
|
|
65
83
|
name: string;
|
|
66
84
|
description: string;
|
|
67
85
|
type: ContractXRoleType;
|
|
@@ -70,7 +88,7 @@ export declare const CONTRACTX_ROLE_DEFINITIONS: {
|
|
|
70
88
|
isSystem: boolean;
|
|
71
89
|
tenant: string;
|
|
72
90
|
};
|
|
73
|
-
[CONTRACTX_ROLES.
|
|
91
|
+
[CONTRACTX_ROLES.CLIENT_FINANCE_RESP]: {
|
|
74
92
|
name: string;
|
|
75
93
|
description: string;
|
|
76
94
|
type: ContractXRoleType;
|
|
@@ -79,7 +97,7 @@ export declare const CONTRACTX_ROLE_DEFINITIONS: {
|
|
|
79
97
|
isSystem: boolean;
|
|
80
98
|
tenant: string;
|
|
81
99
|
};
|
|
82
|
-
[CONTRACTX_ROLES.
|
|
100
|
+
[CONTRACTX_ROLES.CLIENT_REPORTS_RESP]: {
|
|
83
101
|
name: string;
|
|
84
102
|
description: string;
|
|
85
103
|
type: ContractXRoleType;
|
|
@@ -88,7 +106,7 @@ export declare const CONTRACTX_ROLE_DEFINITIONS: {
|
|
|
88
106
|
isSystem: boolean;
|
|
89
107
|
tenant: string;
|
|
90
108
|
};
|
|
91
|
-
[CONTRACTX_ROLES.
|
|
109
|
+
[CONTRACTX_ROLES.CLIENT_RELATIONSHIP_RESP]: {
|
|
92
110
|
name: string;
|
|
93
111
|
description: string;
|
|
94
112
|
type: ContractXRoleType;
|
|
@@ -97,7 +115,7 @@ export declare const CONTRACTX_ROLE_DEFINITIONS: {
|
|
|
97
115
|
isSystem: boolean;
|
|
98
116
|
tenant: string;
|
|
99
117
|
};
|
|
100
|
-
[CONTRACTX_ROLES.
|
|
118
|
+
[CONTRACTX_ROLES.CLIENT_RISK_RESP]: {
|
|
101
119
|
name: string;
|
|
102
120
|
description: string;
|
|
103
121
|
type: ContractXRoleType;
|
|
@@ -115,7 +133,7 @@ export declare const CONTRACTX_ROLE_DEFINITIONS: {
|
|
|
115
133
|
isSystem: boolean;
|
|
116
134
|
tenant: string;
|
|
117
135
|
};
|
|
118
|
-
[CONTRACTX_ROLES.
|
|
136
|
+
[CONTRACTX_ROLES.PROVIDER_PERFORMANCE_RESP]: {
|
|
119
137
|
name: string;
|
|
120
138
|
description: string;
|
|
121
139
|
type: ContractXRoleType;
|
|
@@ -124,7 +142,7 @@ export declare const CONTRACTX_ROLE_DEFINITIONS: {
|
|
|
124
142
|
isSystem: boolean;
|
|
125
143
|
tenant: string;
|
|
126
144
|
};
|
|
127
|
-
[CONTRACTX_ROLES.
|
|
145
|
+
[CONTRACTX_ROLES.PROVIDER_FINANCE_RESP]: {
|
|
128
146
|
name: string;
|
|
129
147
|
description: string;
|
|
130
148
|
type: ContractXRoleType;
|
|
@@ -133,7 +151,7 @@ export declare const CONTRACTX_ROLE_DEFINITIONS: {
|
|
|
133
151
|
isSystem: boolean;
|
|
134
152
|
tenant: string;
|
|
135
153
|
};
|
|
136
|
-
[CONTRACTX_ROLES.
|
|
154
|
+
[CONTRACTX_ROLES.PROVIDER_REPORTS_RESP]: {
|
|
137
155
|
name: string;
|
|
138
156
|
description: string;
|
|
139
157
|
type: ContractXRoleType;
|
|
@@ -142,7 +160,7 @@ export declare const CONTRACTX_ROLE_DEFINITIONS: {
|
|
|
142
160
|
isSystem: boolean;
|
|
143
161
|
tenant: string;
|
|
144
162
|
};
|
|
145
|
-
[CONTRACTX_ROLES.
|
|
163
|
+
[CONTRACTX_ROLES.PROVIDER_RELATIONSHIP_RESP]: {
|
|
146
164
|
name: string;
|
|
147
165
|
description: string;
|
|
148
166
|
type: ContractXRoleType;
|
|
@@ -151,7 +169,7 @@ export declare const CONTRACTX_ROLE_DEFINITIONS: {
|
|
|
151
169
|
isSystem: boolean;
|
|
152
170
|
tenant: string;
|
|
153
171
|
};
|
|
154
|
-
[CONTRACTX_ROLES.
|
|
172
|
+
[CONTRACTX_ROLES.PROVIDER_RISK_RESP]: {
|
|
155
173
|
name: string;
|
|
156
174
|
description: string;
|
|
157
175
|
type: ContractXRoleType;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"contractx-roles.constants.d.ts","sourceRoot":"","sources":["../../src/constants/contractx-roles.constants.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"contractx-roles.constants.d.ts","sourceRoot":"","sources":["../../src/constants/contractx-roles.constants.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,oBAAY,iBAAiB;IAC3B,KAAK,UAAU;IACf,OAAO,YAAY;IACnB,QAAQ,aAAa;IACrB,MAAM,WAAW;IACjB,MAAM,WAAW;IACjB,MAAM,WAAW;CAClB;AAED,oBAAY,kBAAkB;IAC5B,MAAM,WAAW;IACjB,YAAY,iBAAiB;IAC7B,OAAO,YAAY;IACnB,UAAU,eAAe;IACzB,IAAI,SAAS;CACd;AAED,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;CAmB3B,CAAC;AAEF,eAAO,MAAM,0BAA0B;IACnC,CAAC,eAAe,CAAC,WAAW,CAAC;;;;;;;;MAQ5B;IACD,CAAC,eAAe,CAAC,OAAO,CAAC;;;;;;;;MAQxB;IAED,CAAC,eAAe,CAAC,iBAAiB,CAAC;;;;;;;;MAQlC;IACD,CAAC,eAAe,CAAC,qBAAqB,CAAC;;;;;;;;MAQtC;IACD,CAAC,eAAe,CAAC,uBAAuB,CAAC;;;;;;;;MAQxC;IACD,CAAC,eAAe,CAAC,mBAAmB,CAAC;;;;;;;;MAQpC;IACD,CAAC,eAAe,CAAC,mBAAmB,CAAC;;;;;;;;MAQpC;IACD,CAAC,eAAe,CAAC,wBAAwB,CAAC;;;;;;;;MAQzC;IACD,CAAC,eAAe,CAAC,gBAAgB,CAAC;;;;;;;;MAQjC;IAED,CAAC,eAAe,CAAC,uBAAuB,CAAC;;;;;;;;MAQxC;IACD,CAAC,eAAe,CAAC,yBAAyB,CAAC;;;;;;;;MAQ1C;IACD,CAAC,eAAe,CAAC,qBAAqB,CAAC;;;;;;;;MAQtC;IACD,CAAC,eAAe,CAAC,qBAAqB,CAAC;;;;;;;;MAQtC;IACD,CAAC,eAAe,CAAC,0BAA0B,CAAC;;;;;;;;MAQ3C;IACD,CAAC,eAAe,CAAC,kBAAkB,CAAC;;;;;;;;MAQnC;CACJ,CAAC;AAEF,eAAO,MAAM,qBAAqB,UAAiC,CAAC;AAEpE,eAAO,MAAM,qBAAqB;;;;;;CAiCjC,CAAC;AAEF,eAAO,MAAM,YAAY,GAAI,SAAI,YAEhC,CAAC;AACF,eAAO,MAAM,YAAY,GAAI,SAAI,YAEhC,CAAC;AACF,eAAO,MAAM,cAAc,GAAI,SAAI,YAElC,CAAC;AACF,eAAO,MAAM,WAAW,GAAI,SAAI,YAE/B,CAAC;AACF,eAAO,MAAM,eAAe,GAAI,SAAI;;;;;;;;CAEnC,CAAC;AACF,eAAO,MAAM,YAAY,GAAI,SAAI,YAEhC,CAAC;AAIF,MAAM,MAAM,aAAa,GAAG,CAAC,OAAO,eAAe,CAAC,CAAC,MAAM,OAAO,eAAe,CAAC,CAAC;AACnF,MAAM,MAAM,mBAAmB,GAAG,CAAC,OAAO,qBAAqB,CAAC,YAAY,CAAC,CAAC,MAAM,CAAC,CAAC;AACtF,MAAM,MAAM,mBAAmB,GAAG,CAAC,OAAO,qBAAqB,CAAC,YAAY,CAAC,CAAC,MAAM,CAAC,CAAC;AACtF,MAAM,MAAM,qBAAqB,GAAG,CAAC,OAAO,qBAAqB,CAAC,cAAc,CAAC,CAAC,MAAM,CAAC,CAAC;AAC1F,MAAM,MAAM,kBAAkB,GAAG,CAAC,OAAO,qBAAqB,CAAC,WAAW,CAAC,CAAC,MAAM,CAAC,CAAC"}
|
|
@@ -3,7 +3,15 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.validateRole = exports.getRoleMetadata = exports.isAdminRole = exports.isProviderRole = exports.isClientRole = exports.isSystemRole = exports.CONTRACTX_ROLE_GROUPS = exports.VALID_CONTRACTX_ROLES = exports.CONTRACTX_ROLE_DEFINITIONS = exports.CONTRACTX_ROLES = exports.ContractXRoleScope = exports.ContractXRoleType = void 0;
|
|
4
4
|
/**
|
|
5
5
|
* ContractX Role Constants
|
|
6
|
-
*
|
|
6
|
+
* ------------------------------------------------------------------------
|
|
7
|
+
* FUENTE DE VERDAD: el servicio de Auth (`contractx-Auth`,
|
|
8
|
+
* `src/common/constants/security.constants.ts` → `ROLES`). Estas constantes
|
|
9
|
+
* DEBEN reflejar exactamente los `code` de rol que Auth emite en el claim
|
|
10
|
+
* `role[]` del JWT. Cualquier divergencia (p. ej. `superadmin` vs `super_admin`,
|
|
11
|
+
* `*_manager` vs `*_resp`) rompe la comparación de roles en los guards.
|
|
12
|
+
*
|
|
13
|
+
* Matriz v5 (14 roles de negocio) + `support`. Reconciliado con Auth (2026-06).
|
|
14
|
+
* ------------------------------------------------------------------------
|
|
7
15
|
*/
|
|
8
16
|
// Role Types from auth-service
|
|
9
17
|
var ContractXRoleType;
|
|
@@ -24,29 +32,30 @@ var ContractXRoleScope;
|
|
|
24
32
|
ContractXRoleScope["DEPARTMENT"] = "department";
|
|
25
33
|
ContractXRoleScope["TEAM"] = "team";
|
|
26
34
|
})(ContractXRoleScope || (exports.ContractXRoleScope = ContractXRoleScope = {}));
|
|
27
|
-
//
|
|
35
|
+
// Roles canónicos de ContractX — codes IDÉNTICOS a `ROLES` de Auth.
|
|
28
36
|
exports.CONTRACTX_ROLES = {
|
|
29
|
-
// System
|
|
30
|
-
|
|
37
|
+
// System
|
|
38
|
+
SUPER_ADMIN: 'super_admin',
|
|
31
39
|
SUPPORT: 'support',
|
|
32
|
-
// Client-Side
|
|
40
|
+
// Client-Side
|
|
41
|
+
CLIENT_SUPERADMIN: 'client_superadmin',
|
|
33
42
|
CLIENT_CONTRACT_ADMIN: 'client_contract_admin',
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
// Provider-Side
|
|
43
|
+
CLIENT_PERFORMANCE_RESP: 'client_performance_resp',
|
|
44
|
+
CLIENT_FINANCE_RESP: 'client_finance_resp',
|
|
45
|
+
CLIENT_REPORTS_RESP: 'client_reports_resp',
|
|
46
|
+
CLIENT_RELATIONSHIP_RESP: 'client_relationship_resp',
|
|
47
|
+
CLIENT_RISK_RESP: 'client_risk_resp',
|
|
48
|
+
// Provider-Side
|
|
40
49
|
PROVIDER_CONTRACT_ADMIN: 'provider_contract_admin',
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
50
|
+
PROVIDER_PERFORMANCE_RESP: 'provider_performance_resp',
|
|
51
|
+
PROVIDER_FINANCE_RESP: 'provider_finance_resp',
|
|
52
|
+
PROVIDER_REPORTS_RESP: 'provider_reports_resp',
|
|
53
|
+
PROVIDER_RELATIONSHIP_RESP: 'provider_relationship_resp',
|
|
54
|
+
PROVIDER_RISK_RESP: 'provider_risk_resp',
|
|
46
55
|
};
|
|
47
56
|
// Role Definitions with metadata
|
|
48
57
|
exports.CONTRACTX_ROLE_DEFINITIONS = {
|
|
49
|
-
[exports.CONTRACTX_ROLES.
|
|
58
|
+
[exports.CONTRACTX_ROLES.SUPER_ADMIN]: {
|
|
50
59
|
name: 'Super Administrator',
|
|
51
60
|
description: 'Full system access with all permissions',
|
|
52
61
|
type: ContractXRoleType.ADMIN,
|
|
@@ -65,6 +74,15 @@ exports.CONTRACTX_ROLE_DEFINITIONS = {
|
|
|
65
74
|
tenant: 'system'
|
|
66
75
|
},
|
|
67
76
|
// Client Roles
|
|
77
|
+
[exports.CONTRACTX_ROLES.CLIENT_SUPERADMIN]: {
|
|
78
|
+
name: 'Super Admin Cliente',
|
|
79
|
+
description: 'Administrador máximo por cliente (S-CL)',
|
|
80
|
+
type: ContractXRoleType.ADMIN,
|
|
81
|
+
scope: ContractXRoleScope.ORGANIZATION,
|
|
82
|
+
level: 9,
|
|
83
|
+
isSystem: false,
|
|
84
|
+
tenant: 'client'
|
|
85
|
+
},
|
|
68
86
|
[exports.CONTRACTX_ROLES.CLIENT_CONTRACT_ADMIN]: {
|
|
69
87
|
name: 'Client Contract Administrator',
|
|
70
88
|
description: 'Full contract management for client organization',
|
|
@@ -74,8 +92,8 @@ exports.CONTRACTX_ROLE_DEFINITIONS = {
|
|
|
74
92
|
isSystem: false,
|
|
75
93
|
tenant: 'client'
|
|
76
94
|
},
|
|
77
|
-
[exports.CONTRACTX_ROLES.
|
|
78
|
-
name: 'Client Performance
|
|
95
|
+
[exports.CONTRACTX_ROLES.CLIENT_PERFORMANCE_RESP]: {
|
|
96
|
+
name: 'Client Performance Responsible',
|
|
79
97
|
description: 'Performance monitoring and SLA management',
|
|
80
98
|
type: ContractXRoleType.OPERATOR,
|
|
81
99
|
scope: ContractXRoleScope.PROJECT,
|
|
@@ -83,8 +101,8 @@ exports.CONTRACTX_ROLE_DEFINITIONS = {
|
|
|
83
101
|
isSystem: false,
|
|
84
102
|
tenant: 'client'
|
|
85
103
|
},
|
|
86
|
-
[exports.CONTRACTX_ROLES.
|
|
87
|
-
name: 'Client Finance
|
|
104
|
+
[exports.CONTRACTX_ROLES.CLIENT_FINANCE_RESP]: {
|
|
105
|
+
name: 'Client Finance Responsible',
|
|
88
106
|
description: 'Financial management and invoice oversight',
|
|
89
107
|
type: ContractXRoleType.OPERATOR,
|
|
90
108
|
scope: ContractXRoleScope.PROJECT,
|
|
@@ -92,8 +110,8 @@ exports.CONTRACTX_ROLE_DEFINITIONS = {
|
|
|
92
110
|
isSystem: false,
|
|
93
111
|
tenant: 'client'
|
|
94
112
|
},
|
|
95
|
-
[exports.CONTRACTX_ROLES.
|
|
96
|
-
name: 'Client Reports
|
|
113
|
+
[exports.CONTRACTX_ROLES.CLIENT_REPORTS_RESP]: {
|
|
114
|
+
name: 'Client Reports Responsible',
|
|
97
115
|
description: 'Reporting and analytics access',
|
|
98
116
|
type: ContractXRoleType.VIEWER,
|
|
99
117
|
scope: ContractXRoleScope.PROJECT,
|
|
@@ -101,8 +119,8 @@ exports.CONTRACTX_ROLE_DEFINITIONS = {
|
|
|
101
119
|
isSystem: false,
|
|
102
120
|
tenant: 'client'
|
|
103
121
|
},
|
|
104
|
-
[exports.CONTRACTX_ROLES.
|
|
105
|
-
name: 'Client Relationship
|
|
122
|
+
[exports.CONTRACTX_ROLES.CLIENT_RELATIONSHIP_RESP]: {
|
|
123
|
+
name: 'Client Relationship Responsible',
|
|
106
124
|
description: 'Relationship management and meeting coordination',
|
|
107
125
|
type: ContractXRoleType.OPERATOR,
|
|
108
126
|
scope: ContractXRoleScope.PROJECT,
|
|
@@ -110,8 +128,8 @@ exports.CONTRACTX_ROLE_DEFINITIONS = {
|
|
|
110
128
|
isSystem: false,
|
|
111
129
|
tenant: 'client'
|
|
112
130
|
},
|
|
113
|
-
[exports.CONTRACTX_ROLES.
|
|
114
|
-
name: 'Client Risk
|
|
131
|
+
[exports.CONTRACTX_ROLES.CLIENT_RISK_RESP]: {
|
|
132
|
+
name: 'Client Risk Responsible',
|
|
115
133
|
description: 'Risk assessment and escalation management',
|
|
116
134
|
type: ContractXRoleType.OPERATOR,
|
|
117
135
|
scope: ContractXRoleScope.PROJECT,
|
|
@@ -129,8 +147,8 @@ exports.CONTRACTX_ROLE_DEFINITIONS = {
|
|
|
129
147
|
isSystem: false,
|
|
130
148
|
tenant: 'provider'
|
|
131
149
|
},
|
|
132
|
-
[exports.CONTRACTX_ROLES.
|
|
133
|
-
name: 'Provider Performance
|
|
150
|
+
[exports.CONTRACTX_ROLES.PROVIDER_PERFORMANCE_RESP]: {
|
|
151
|
+
name: 'Provider Performance Responsible',
|
|
134
152
|
description: 'Performance delivery and SLA compliance',
|
|
135
153
|
type: ContractXRoleType.OPERATOR,
|
|
136
154
|
scope: ContractXRoleScope.PROJECT,
|
|
@@ -138,8 +156,8 @@ exports.CONTRACTX_ROLE_DEFINITIONS = {
|
|
|
138
156
|
isSystem: false,
|
|
139
157
|
tenant: 'provider'
|
|
140
158
|
},
|
|
141
|
-
[exports.CONTRACTX_ROLES.
|
|
142
|
-
name: 'Provider Finance
|
|
159
|
+
[exports.CONTRACTX_ROLES.PROVIDER_FINANCE_RESP]: {
|
|
160
|
+
name: 'Provider Finance Responsible',
|
|
143
161
|
description: 'Financial management from provider side',
|
|
144
162
|
type: ContractXRoleType.OPERATOR,
|
|
145
163
|
scope: ContractXRoleScope.PROJECT,
|
|
@@ -147,8 +165,8 @@ exports.CONTRACTX_ROLE_DEFINITIONS = {
|
|
|
147
165
|
isSystem: false,
|
|
148
166
|
tenant: 'provider'
|
|
149
167
|
},
|
|
150
|
-
[exports.CONTRACTX_ROLES.
|
|
151
|
-
name: 'Provider Reports
|
|
168
|
+
[exports.CONTRACTX_ROLES.PROVIDER_REPORTS_RESP]: {
|
|
169
|
+
name: 'Provider Reports Responsible',
|
|
152
170
|
description: 'Provider reporting capabilities',
|
|
153
171
|
type: ContractXRoleType.VIEWER,
|
|
154
172
|
scope: ContractXRoleScope.PROJECT,
|
|
@@ -156,8 +174,8 @@ exports.CONTRACTX_ROLE_DEFINITIONS = {
|
|
|
156
174
|
isSystem: false,
|
|
157
175
|
tenant: 'provider'
|
|
158
176
|
},
|
|
159
|
-
[exports.CONTRACTX_ROLES.
|
|
160
|
-
name: 'Provider Relationship
|
|
177
|
+
[exports.CONTRACTX_ROLES.PROVIDER_RELATIONSHIP_RESP]: {
|
|
178
|
+
name: 'Provider Relationship Responsible',
|
|
161
179
|
description: 'Client relationship management from provider side',
|
|
162
180
|
type: ContractXRoleType.OPERATOR,
|
|
163
181
|
scope: ContractXRoleScope.PROJECT,
|
|
@@ -165,8 +183,8 @@ exports.CONTRACTX_ROLE_DEFINITIONS = {
|
|
|
165
183
|
isSystem: false,
|
|
166
184
|
tenant: 'provider'
|
|
167
185
|
},
|
|
168
|
-
[exports.CONTRACTX_ROLES.
|
|
169
|
-
name: 'Provider Risk
|
|
186
|
+
[exports.CONTRACTX_ROLES.PROVIDER_RISK_RESP]: {
|
|
187
|
+
name: 'Provider Risk Responsible',
|
|
170
188
|
description: 'Risk management from provider perspective',
|
|
171
189
|
type: ContractXRoleType.OPERATOR,
|
|
172
190
|
scope: ContractXRoleScope.PROJECT,
|
|
@@ -179,35 +197,37 @@ exports.CONTRACTX_ROLE_DEFINITIONS = {
|
|
|
179
197
|
exports.VALID_CONTRACTX_ROLES = Object.values(exports.CONTRACTX_ROLES);
|
|
180
198
|
// Role groups for easier management
|
|
181
199
|
exports.CONTRACTX_ROLE_GROUPS = {
|
|
182
|
-
SYSTEM_ROLES: [exports.CONTRACTX_ROLES.
|
|
200
|
+
SYSTEM_ROLES: [exports.CONTRACTX_ROLES.SUPER_ADMIN, exports.CONTRACTX_ROLES.SUPPORT],
|
|
183
201
|
CLIENT_ROLES: [
|
|
202
|
+
exports.CONTRACTX_ROLES.CLIENT_SUPERADMIN,
|
|
184
203
|
exports.CONTRACTX_ROLES.CLIENT_CONTRACT_ADMIN,
|
|
185
|
-
exports.CONTRACTX_ROLES.
|
|
186
|
-
exports.CONTRACTX_ROLES.
|
|
187
|
-
exports.CONTRACTX_ROLES.
|
|
188
|
-
exports.CONTRACTX_ROLES.
|
|
189
|
-
exports.CONTRACTX_ROLES.
|
|
204
|
+
exports.CONTRACTX_ROLES.CLIENT_PERFORMANCE_RESP,
|
|
205
|
+
exports.CONTRACTX_ROLES.CLIENT_FINANCE_RESP,
|
|
206
|
+
exports.CONTRACTX_ROLES.CLIENT_REPORTS_RESP,
|
|
207
|
+
exports.CONTRACTX_ROLES.CLIENT_RELATIONSHIP_RESP,
|
|
208
|
+
exports.CONTRACTX_ROLES.CLIENT_RISK_RESP,
|
|
190
209
|
],
|
|
191
210
|
PROVIDER_ROLES: [
|
|
192
211
|
exports.CONTRACTX_ROLES.PROVIDER_CONTRACT_ADMIN,
|
|
193
|
-
exports.CONTRACTX_ROLES.
|
|
194
|
-
exports.CONTRACTX_ROLES.
|
|
195
|
-
exports.CONTRACTX_ROLES.
|
|
196
|
-
exports.CONTRACTX_ROLES.
|
|
197
|
-
exports.CONTRACTX_ROLES.
|
|
212
|
+
exports.CONTRACTX_ROLES.PROVIDER_PERFORMANCE_RESP,
|
|
213
|
+
exports.CONTRACTX_ROLES.PROVIDER_FINANCE_RESP,
|
|
214
|
+
exports.CONTRACTX_ROLES.PROVIDER_REPORTS_RESP,
|
|
215
|
+
exports.CONTRACTX_ROLES.PROVIDER_RELATIONSHIP_RESP,
|
|
216
|
+
exports.CONTRACTX_ROLES.PROVIDER_RISK_RESP,
|
|
198
217
|
],
|
|
199
218
|
ADMIN_ROLES: [
|
|
200
|
-
exports.CONTRACTX_ROLES.
|
|
219
|
+
exports.CONTRACTX_ROLES.SUPER_ADMIN,
|
|
220
|
+
exports.CONTRACTX_ROLES.CLIENT_SUPERADMIN,
|
|
201
221
|
exports.CONTRACTX_ROLES.CLIENT_CONTRACT_ADMIN,
|
|
202
222
|
exports.CONTRACTX_ROLES.PROVIDER_CONTRACT_ADMIN,
|
|
203
223
|
],
|
|
204
224
|
MANAGER_ROLES: [
|
|
205
225
|
exports.CONTRACTX_ROLES.CLIENT_CONTRACT_ADMIN,
|
|
206
226
|
exports.CONTRACTX_ROLES.PROVIDER_CONTRACT_ADMIN,
|
|
207
|
-
exports.CONTRACTX_ROLES.
|
|
208
|
-
exports.CONTRACTX_ROLES.
|
|
209
|
-
exports.CONTRACTX_ROLES.
|
|
210
|
-
exports.CONTRACTX_ROLES.
|
|
227
|
+
exports.CONTRACTX_ROLES.CLIENT_PERFORMANCE_RESP,
|
|
228
|
+
exports.CONTRACTX_ROLES.PROVIDER_PERFORMANCE_RESP,
|
|
229
|
+
exports.CONTRACTX_ROLES.CLIENT_FINANCE_RESP,
|
|
230
|
+
exports.CONTRACTX_ROLES.PROVIDER_FINANCE_RESP,
|
|
211
231
|
],
|
|
212
232
|
};
|
|
213
233
|
// Helper functions
|
|
@@ -19,7 +19,7 @@ exports.MODULE_CONSTANTS = exports.ROLE_GROUPS = exports.PERMISSION_CATEGORIES =
|
|
|
19
19
|
*/
|
|
20
20
|
exports.CONTRACTX_ROLES = {
|
|
21
21
|
// === SYSTEM ROLE ===
|
|
22
|
-
SUPERADMIN: '
|
|
22
|
+
SUPERADMIN: 'super_admin', // ID: 1 - Full access to all modules
|
|
23
23
|
// === CLIENT-SIDE ROLES ===
|
|
24
24
|
CLIENT_CONTRACT_ADMIN: 'client_contract_admin', // ID: 2 - Full contract management for assigned client
|
|
25
25
|
CLIENT_PERFORMANCE_RESP: 'client_performance_resp', // ID: 3 - Performance responsibility role
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* [Permisos por contrato] Marca un endpoint como SCOPED a un contrato.
|
|
3
|
+
*
|
|
4
|
+
* El `AuthorizationGuard` exige que el contrato sobre el que opera la petición
|
|
5
|
+
* coincida con el `currentContractId` del JWT (el contrato activo que el usuario
|
|
6
|
+
* seleccionó en Auth). Si no coincide → 403. Esto evita usar un token scopeado al
|
|
7
|
+
* contrato A para operar sobre el contrato B.
|
|
8
|
+
*
|
|
9
|
+
* `path` indica de dónde extraer el contractId de la request, en formato
|
|
10
|
+
* `<fuente>.<campo>` (p. ej. `'params.id'`, `'params.contractId'`,
|
|
11
|
+
* `'body.contractId'`, `'query.contractId'`). Si se omite, el guard prueba en orden:
|
|
12
|
+
* `params.contractId` → `params.id` → `body.contractId` → `query.contractId`.
|
|
13
|
+
*
|
|
14
|
+
* Roles de sistema/globales (`tenantContext='system'` o `super_admin`) hacen bypass
|
|
15
|
+
* del binding (pueden operar sin contrato activo).
|
|
16
|
+
*
|
|
17
|
+
* @example
|
|
18
|
+
* @RequirePermissions(CONTRATOS_PERMISSIONS.CONTRACTS_APPROVE)
|
|
19
|
+
* @ContractScoped('params.id')
|
|
20
|
+
* @Patch(':id/approve')
|
|
21
|
+
* approve(@Param('id') id: string) { ... }
|
|
22
|
+
*/
|
|
23
|
+
export declare const CONTRACT_SCOPED_KEY = "contract_scoped";
|
|
24
|
+
export declare const ContractScoped: (path?: string) => import("@nestjs/common").CustomDecorator<string>;
|
|
25
|
+
//# sourceMappingURL=contract-scoped.decorator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"contract-scoped.decorator.d.ts","sourceRoot":"","sources":["../../src/decorators/contract-scoped.decorator.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,eAAO,MAAM,mBAAmB,oBAAoB,CAAC;AAErD,eAAO,MAAM,cAAc,GAAI,OAAO,MAAM,qDAAiD,CAAC"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ContractScoped = exports.CONTRACT_SCOPED_KEY = void 0;
|
|
4
|
+
const common_1 = require("@nestjs/common");
|
|
5
|
+
/**
|
|
6
|
+
* [Permisos por contrato] Marca un endpoint como SCOPED a un contrato.
|
|
7
|
+
*
|
|
8
|
+
* El `AuthorizationGuard` exige que el contrato sobre el que opera la petición
|
|
9
|
+
* coincida con el `currentContractId` del JWT (el contrato activo que el usuario
|
|
10
|
+
* seleccionó en Auth). Si no coincide → 403. Esto evita usar un token scopeado al
|
|
11
|
+
* contrato A para operar sobre el contrato B.
|
|
12
|
+
*
|
|
13
|
+
* `path` indica de dónde extraer el contractId de la request, en formato
|
|
14
|
+
* `<fuente>.<campo>` (p. ej. `'params.id'`, `'params.contractId'`,
|
|
15
|
+
* `'body.contractId'`, `'query.contractId'`). Si se omite, el guard prueba en orden:
|
|
16
|
+
* `params.contractId` → `params.id` → `body.contractId` → `query.contractId`.
|
|
17
|
+
*
|
|
18
|
+
* Roles de sistema/globales (`tenantContext='system'` o `super_admin`) hacen bypass
|
|
19
|
+
* del binding (pueden operar sin contrato activo).
|
|
20
|
+
*
|
|
21
|
+
* @example
|
|
22
|
+
* @RequirePermissions(CONTRATOS_PERMISSIONS.CONTRACTS_APPROVE)
|
|
23
|
+
* @ContractScoped('params.id')
|
|
24
|
+
* @Patch(':id/approve')
|
|
25
|
+
* approve(@Param('id') id: string) { ... }
|
|
26
|
+
*/
|
|
27
|
+
exports.CONTRACT_SCOPED_KEY = 'contract_scoped';
|
|
28
|
+
const ContractScoped = (path) => (0, common_1.SetMetadata)(exports.CONTRACT_SCOPED_KEY, path ?? '');
|
|
29
|
+
exports.ContractScoped = ContractScoped;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/decorators/index.ts"],"names":[],"mappings":"AAAA,cAAc,oBAAoB,CAAC;AACnC,cAAc,mBAAmB,CAAC;AAClC,cAAc,yBAAyB,CAAC;AACxC,cAAc,0BAA0B,CAAC;AACzC,cAAc,+BAA+B,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/decorators/index.ts"],"names":[],"mappings":"AAAA,cAAc,oBAAoB,CAAC;AACnC,cAAc,mBAAmB,CAAC;AAClC,cAAc,yBAAyB,CAAC;AACxC,cAAc,0BAA0B,CAAC;AACzC,cAAc,+BAA+B,CAAC;AAC9C,cAAc,6BAA6B,CAAC"}
|
package/dist/decorators/index.js
CHANGED
|
@@ -19,3 +19,4 @@ __exportStar(require("./roles.decorator"), exports);
|
|
|
19
19
|
__exportStar(require("./permissions.decorator"), exports);
|
|
20
20
|
__exportStar(require("./current-user.decorator"), exports);
|
|
21
21
|
__exportStar(require("./permission-writes.decorator"), exports);
|
|
22
|
+
__exportStar(require("./contract-scoped.decorator"), exports);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"roles.decorator.d.ts","sourceRoot":"","sources":["../../src/decorators/roles.decorator.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"roles.decorator.d.ts","sourceRoot":"","sources":["../../src/decorators/roles.decorator.ts"],"names":[],"mappings":"AAGA;;GAEG;AACH,eAAO,MAAM,SAAS,UAAU,CAAC;AAEjC;;;;;;GAMG;AACH,eAAO,MAAM,KAAK,GAAI,GAAG,OAAO,MAAM,EAAE,qDAAkC,CAAC;AAK3E,mDAAmD;AACnD,eAAO,MAAM,SAAS,wDAAoD,CAAC;AAE3E,2CAA2C;AAC3C,eAAO,MAAM,UAAU,wDAAqD,CAAC;AAE7E,6CAA6C;AAC7C,eAAO,MAAM,YAAY,wDAAuD,CAAC;AAEjF,2CAA2C;AAC3C,eAAO,MAAM,cAAc,wDAA2C,CAAC;AAEvE;;;GAGG;AACH,eAAO,MAAM,YAAY,aArBO,MAAM,EAAE,qDAqBP,CAAC"}
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.RequireRoles = exports.SuperAdminOnly = exports.ProviderOnly = exports.ClientOnly = exports.AdminOnly = exports.Roles = exports.ROLES_KEY = void 0;
|
|
4
4
|
const common_1 = require("@nestjs/common");
|
|
5
|
+
const contractx_roles_constants_1 = require("../constants/contractx-roles.constants");
|
|
5
6
|
/**
|
|
6
7
|
* Metadata key for required roles
|
|
7
8
|
*/
|
|
@@ -15,19 +16,19 @@ exports.ROLES_KEY = 'roles';
|
|
|
15
16
|
*/
|
|
16
17
|
const Roles = (...roles) => (0, common_1.SetMetadata)(exports.ROLES_KEY, roles);
|
|
17
18
|
exports.Roles = Roles;
|
|
18
|
-
//
|
|
19
|
-
//
|
|
19
|
+
// Los helpers derivan de CONTRACTX_ROLES / CONTRACTX_ROLE_GROUPS (fuente única reconciliada
|
|
20
|
+
// con los codes de rol de Auth). NO hardcodear literales aquí.
|
|
20
21
|
/** Decorator for ContractX specific admin roles */
|
|
21
|
-
const AdminOnly = () => (0, exports.Roles)(
|
|
22
|
+
const AdminOnly = () => (0, exports.Roles)(...contractx_roles_constants_1.CONTRACTX_ROLE_GROUPS.ADMIN_ROLES);
|
|
22
23
|
exports.AdminOnly = AdminOnly;
|
|
23
24
|
/** Decorator for client-side roles only */
|
|
24
|
-
const ClientOnly = () => (0, exports.Roles)(
|
|
25
|
+
const ClientOnly = () => (0, exports.Roles)(...contractx_roles_constants_1.CONTRACTX_ROLE_GROUPS.CLIENT_ROLES);
|
|
25
26
|
exports.ClientOnly = ClientOnly;
|
|
26
27
|
/** Decorator for provider-side roles only */
|
|
27
|
-
const ProviderOnly = () => (0, exports.Roles)(
|
|
28
|
+
const ProviderOnly = () => (0, exports.Roles)(...contractx_roles_constants_1.CONTRACTX_ROLE_GROUPS.PROVIDER_ROLES);
|
|
28
29
|
exports.ProviderOnly = ProviderOnly;
|
|
29
30
|
/** Decorator for superadmin access only */
|
|
30
|
-
const SuperAdminOnly = () => (0, exports.Roles)(
|
|
31
|
+
const SuperAdminOnly = () => (0, exports.Roles)(contractx_roles_constants_1.CONTRACTX_ROLES.SUPER_ADMIN);
|
|
31
32
|
exports.SuperAdminOnly = SuperAdminOnly;
|
|
32
33
|
/**
|
|
33
34
|
* Alias for Roles decorator for backward compatibility
|
|
@@ -33,5 +33,19 @@ export declare class AuthorizationGuard implements CanActivate {
|
|
|
33
33
|
* (GET/HEAD/OPTIONS = lectura; el resto = escritura).
|
|
34
34
|
*/
|
|
35
35
|
private isWriteRequest;
|
|
36
|
+
/**
|
|
37
|
+
* [Permisos por contrato] Verifica que el contrato sobre el que opera la petición
|
|
38
|
+
* coincida con el `currentContractId` del token. Lanza ForbiddenException si no hay
|
|
39
|
+
* contrato activo, no se puede resolver el contrato de la request, o no coinciden.
|
|
40
|
+
*/
|
|
41
|
+
private assertContractBinding;
|
|
42
|
+
/** Roles de sistema/globales que pueden operar sin contrato activo (bypass del binding). */
|
|
43
|
+
private isGlobalBypass;
|
|
44
|
+
/**
|
|
45
|
+
* Extrae el contractId de la request. `path` en formato '<fuente>.<campo>'
|
|
46
|
+
* (params/body/query). Si está vacío, prueba ubicaciones comunes en orden:
|
|
47
|
+
* params.contractId → params.id → body.contractId → query.contractId.
|
|
48
|
+
*/
|
|
49
|
+
private extractContractId;
|
|
36
50
|
}
|
|
37
51
|
//# sourceMappingURL=authorization.guard.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"authorization.guard.d.ts","sourceRoot":"","sources":["../../src/guards/authorization.guard.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,WAAW,EACX,gBAAgB,EAGjB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"authorization.guard.d.ts","sourceRoot":"","sources":["../../src/guards/authorization.guard.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,WAAW,EACX,gBAAgB,EAGjB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAazC;;;;;;;;;;;;;;;;GAgBG;AACH,qBACa,kBAAmB,YAAW,WAAW;IAGxC,OAAO,CAAC,SAAS;IAF7B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAuC;gBAE1C,SAAS,EAAE,SAAS;IAExC,WAAW,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO;IA6H/C;;;OAGG;IACH,OAAO,CAAC,sBAAsB;IAK9B;;;;OAIG;IACH,OAAO,CAAC,cAAc;IAWtB;;;;OAIG;IACH,OAAO,CAAC,qBAAqB;IAqB7B,4FAA4F;IAC5F,OAAO,CAAC,cAAc;IAQtB;;;;OAIG;IACH,OAAO,CAAC,iBAAiB;CAe1B"}
|
|
@@ -14,6 +14,8 @@ exports.AuthorizationGuard = void 0;
|
|
|
14
14
|
const common_1 = require("@nestjs/common");
|
|
15
15
|
const core_1 = require("@nestjs/core");
|
|
16
16
|
const permission_writes_decorator_1 = require("../decorators/permission-writes.decorator");
|
|
17
|
+
const contract_scoped_decorator_1 = require("../decorators/contract-scoped.decorator");
|
|
18
|
+
const contractx_roles_constants_1 = require("../constants/contractx-roles.constants");
|
|
17
19
|
const READ_METHODS = new Set(['GET', 'HEAD', 'OPTIONS']);
|
|
18
20
|
/**
|
|
19
21
|
* [ADR-004] AuthorizationGuard — guard de 4 estados portado desde Auth.
|
|
@@ -46,7 +48,14 @@ let AuthorizationGuard = AuthorizationGuard_1 = class AuthorizationGuard {
|
|
|
46
48
|
context.getHandler(),
|
|
47
49
|
context.getClass(),
|
|
48
50
|
]);
|
|
49
|
-
|
|
51
|
+
// [Permisos por contrato] ¿el endpoint está scopeado a un contrato? (metadata presente)
|
|
52
|
+
const contractScopedPath = this.reflector.getAllAndOverride(contract_scoped_decorator_1.CONTRACT_SCOPED_KEY, [
|
|
53
|
+
context.getHandler(),
|
|
54
|
+
context.getClass(),
|
|
55
|
+
]);
|
|
56
|
+
const isContractScoped = contractScopedPath !== undefined;
|
|
57
|
+
if (!isContractScoped &&
|
|
58
|
+
(!requiredRoles || requiredRoles.length === 0) &&
|
|
50
59
|
(!requiredPermissions || requiredPermissions.length === 0)) {
|
|
51
60
|
return true;
|
|
52
61
|
}
|
|
@@ -56,6 +65,11 @@ let AuthorizationGuard = AuthorizationGuard_1 = class AuthorizationGuard {
|
|
|
56
65
|
this.logger.warn('No user found in request context for authorization');
|
|
57
66
|
throw new common_1.ForbiddenException('Authentication required for access');
|
|
58
67
|
}
|
|
68
|
+
// [Permisos por contrato] Binding síncrono: el contrato de la request debe coincidir
|
|
69
|
+
// con el contrato activo del token. Roles de sistema/globales (super_admin / system): bypass.
|
|
70
|
+
if (isContractScoped && !this.isGlobalBypass(user)) {
|
|
71
|
+
this.assertContractBinding(user, request, contractScopedPath ?? '');
|
|
72
|
+
}
|
|
59
73
|
const userId = user.sub;
|
|
60
74
|
const userRoles = user.role || [];
|
|
61
75
|
// Dos conjuntos resueltos en la carga del JWT: permissions = acceso pleno;
|
|
@@ -142,6 +156,54 @@ let AuthorizationGuard = AuthorizationGuard_1 = class AuthorizationGuard {
|
|
|
142
156
|
}
|
|
143
157
|
return !READ_METHODS.has((method ?? '').toUpperCase());
|
|
144
158
|
}
|
|
159
|
+
/**
|
|
160
|
+
* [Permisos por contrato] Verifica que el contrato sobre el que opera la petición
|
|
161
|
+
* coincida con el `currentContractId` del token. Lanza ForbiddenException si no hay
|
|
162
|
+
* contrato activo, no se puede resolver el contrato de la request, o no coinciden.
|
|
163
|
+
*/
|
|
164
|
+
assertContractBinding(user, request, path) {
|
|
165
|
+
const tokenContract = typeof user.currentContractId === 'string' ? user.currentContractId : undefined;
|
|
166
|
+
if (!tokenContract) {
|
|
167
|
+
this.logger.warn(`Contract-scoped access denied: user ${user.sub} has no active contract in token`);
|
|
168
|
+
throw new common_1.ForbiddenException('No active contract selected. Select a contract first.');
|
|
169
|
+
}
|
|
170
|
+
const reqContract = this.extractContractId(request, path);
|
|
171
|
+
if (!reqContract) {
|
|
172
|
+
this.logger.warn(`Contract-scoped access denied: could not resolve contract id from request (path='${path}')`);
|
|
173
|
+
throw new common_1.ForbiddenException('Could not resolve contract id from request');
|
|
174
|
+
}
|
|
175
|
+
if (reqContract !== tokenContract) {
|
|
176
|
+
this.logger.warn(`Contract-scoped access denied: token scoped to ${tokenContract} but request targets ${reqContract}`);
|
|
177
|
+
throw new common_1.ForbiddenException('Token is not scoped to the requested contract');
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
/** Roles de sistema/globales que pueden operar sin contrato activo (bypass del binding). */
|
|
181
|
+
isGlobalBypass(user) {
|
|
182
|
+
if (user.tenantContext === 'system') {
|
|
183
|
+
return true;
|
|
184
|
+
}
|
|
185
|
+
const roles = (user.role || []);
|
|
186
|
+
return roles.includes(contractx_roles_constants_1.CONTRACTX_ROLES.SUPER_ADMIN);
|
|
187
|
+
}
|
|
188
|
+
/**
|
|
189
|
+
* Extrae el contractId de la request. `path` en formato '<fuente>.<campo>'
|
|
190
|
+
* (params/body/query). Si está vacío, prueba ubicaciones comunes en orden:
|
|
191
|
+
* params.contractId → params.id → body.contractId → query.contractId.
|
|
192
|
+
*/
|
|
193
|
+
extractContractId(request, path) {
|
|
194
|
+
const candidates = path
|
|
195
|
+
? [path]
|
|
196
|
+
: ['params.contractId', 'params.id', 'body.contractId', 'query.contractId'];
|
|
197
|
+
const bags = request;
|
|
198
|
+
for (const candidate of candidates) {
|
|
199
|
+
const [source, key] = candidate.split('.');
|
|
200
|
+
const value = source && key ? bags[source]?.[key] : undefined;
|
|
201
|
+
if (typeof value === 'string' && value.length > 0) {
|
|
202
|
+
return value;
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
return undefined;
|
|
206
|
+
}
|
|
145
207
|
};
|
|
146
208
|
exports.AuthorizationGuard = AuthorizationGuard;
|
|
147
209
|
exports.AuthorizationGuard = AuthorizationGuard = AuthorizationGuard_1 = __decorate([
|
|
@@ -35,6 +35,15 @@ export interface JwtPayload {
|
|
|
35
35
|
* no se afectan. El AuthorizationGuard usa este conjunto para bloquear escrituras.
|
|
36
36
|
*/
|
|
37
37
|
permissionsView?: string[];
|
|
38
|
+
/**
|
|
39
|
+
* [Permisos por contrato] Contrato activo que el usuario seleccionó en Auth. Cuando
|
|
40
|
+
* está presente, `role`/`permissions`/`permissionsView` reflejan el rol del usuario
|
|
41
|
+
* EN ese contrato. Ausente ⇒ modo global (retrocompatible). El AuthorizationGuard usa
|
|
42
|
+
* este valor para el binding de los endpoints marcados con `@ContractScoped`.
|
|
43
|
+
*/
|
|
44
|
+
currentContractId?: string;
|
|
45
|
+
/** [Permisos por contrato] Código del rol del usuario en `currentContractId`. */
|
|
46
|
+
currentContractRoleCode?: string;
|
|
38
47
|
/** User's full name */
|
|
39
48
|
fullName: string;
|
|
40
49
|
/** User's email */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"jwt-payload.interface.d.ts","sourceRoot":"","sources":["../../src/interfaces/jwt-payload.interface.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,cAAc;IACd,GAAG,EAAE,MAAM,GAAG,MAAM,CAAC;IACrB,gCAAgC;IAChC,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,uBAAuB;IACvB,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,sDAAsD;IACtD,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB;;;;OAIG;IACH,eAAe,CAAC,EAAE,MAAM,EAAE,CAAC;IAC3B,uBAAuB;IACvB,QAAQ,EAAE,MAAM,CAAC;IACjB,mBAAmB;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;OAGG;IACH,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,uCAAuC;IACvC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,kCAAkC;IAClC,aAAa,CAAC,EAAE,QAAQ,GAAG,UAAU,GAAG,QAAQ,CAAC;IACjD,gEAAgE;IAChE,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,8BAA8B;IAC9B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,gCAAgC;IAChC,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,iCAAiC;IACjC,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,mBAAmB;IACnB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,qBAAqB;IACrB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,wFAAwF;IACxF,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED;;;GAGG;AACH,MAAM,WAAW,oBAAqB,SAAQ,OAAO;IACnD,IAAI,EAAE,UAAU,CAAC;CAClB;AAED;;;GAGG;AACH,MAAM,WAAW,aAAa;IAC5B,qBAAqB;IACrB,MAAM,EAAE,MAAM,CAAC;IACf,mBAAmB;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,qBAAqB;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,4BAA4B;IAC5B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,2BAA2B;IAC3B,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,oCAAoC;IACpC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,2CAA2C;IAC3C,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,wCAAwC;IACxC,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC5B;AAED;;;GAGG;AACH,MAAM,WAAW,wBAAwB;IACvC,wBAAwB;IACxB,GAAG,EAAE,aAAa,CAAC;IACnB,kCAAkC;IAClC,MAAM,CAAC,EAAE;QACP,0CAA0C;QAC1C,gBAAgB,CAAC,EAAE,OAAO,CAAC;QAC3B,iCAAiC;QACjC,iBAAiB,CAAC,EAAE,OAAO,CAAC;QAC5B,uCAAuC;QACvC,uBAAuB,CAAC,EAAE,OAAO,CAAC;KACnC,CAAC;IACF,6BAA6B;IAC7B,QAAQ,CAAC,EAAE;QACT,6BAA6B;QAC7B,aAAa,CAAC,EAAE,OAAO,CAAC;QACxB,2BAA2B;QAC3B,eAAe,CAAC,EAAE,OAAO,CAAC;QAC1B,wCAAwC;QACxC,eAAe,CAAC,EAAE,MAAM,CAAC;QACzB,kCAAkC;QAClC,YAAY,CAAC,EAAE,MAAM,CAAC;KACvB,CAAC;IACF,gCAAgC;IAChC,WAAW,CAAC,EAAE;QACZ,4CAA4C;QAC5C,WAAW,CAAC,EAAE,OAAO,CAAC;QACtB,gCAAgC;QAChC,QAAQ,CAAC,EAAE,UAAU,CAAC;KACvB,CAAC;CACH"}
|
|
1
|
+
{"version":3,"file":"jwt-payload.interface.d.ts","sourceRoot":"","sources":["../../src/interfaces/jwt-payload.interface.ts"],"names":[],"mappings":"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"}
|
|
@@ -89,7 +89,7 @@ let ContractXAuthorizationService = class ContractXAuthorizationService {
|
|
|
89
89
|
* Check if user has system-level access
|
|
90
90
|
*/
|
|
91
91
|
hasSystemLevelAccess(userRoles) {
|
|
92
|
-
return userRoles.some(role => role === contractx_roles_constants_1.CONTRACTX_ROLES.
|
|
92
|
+
return userRoles.some(role => role === contractx_roles_constants_1.CONTRACTX_ROLES.SUPER_ADMIN ||
|
|
93
93
|
role === contractx_roles_constants_1.CONTRACTX_ROLES.SUPPORT ||
|
|
94
94
|
(0, contractx_roles_constants_1.isSystemRole)(role));
|
|
95
95
|
}
|
|
@@ -325,14 +325,14 @@ let ContractXAuthorizationService = class ContractXAuthorizationService {
|
|
|
325
325
|
contracts: {
|
|
326
326
|
create: [contractx_roles_constants_1.CONTRACTX_ROLES.CLIENT_CONTRACT_ADMIN, contractx_roles_constants_1.CONTRACTX_ROLES.PROVIDER_CONTRACT_ADMIN],
|
|
327
327
|
delete: [contractx_roles_constants_1.CONTRACTX_ROLES.CLIENT_CONTRACT_ADMIN, contractx_roles_constants_1.CONTRACTX_ROLES.PROVIDER_CONTRACT_ADMIN],
|
|
328
|
-
admin: [contractx_roles_constants_1.CONTRACTX_ROLES.
|
|
328
|
+
admin: [contractx_roles_constants_1.CONTRACTX_ROLES.SUPER_ADMIN, contractx_roles_constants_1.CONTRACTX_ROLES.SUPPORT],
|
|
329
329
|
},
|
|
330
330
|
projects: {
|
|
331
331
|
create: [contractx_roles_constants_1.CONTRACTX_ROLES.CLIENT_CONTRACT_ADMIN, contractx_roles_constants_1.CONTRACTX_ROLES.PROVIDER_CONTRACT_ADMIN],
|
|
332
332
|
delete: [contractx_roles_constants_1.CONTRACTX_ROLES.CLIENT_CONTRACT_ADMIN, contractx_roles_constants_1.CONTRACTX_ROLES.PROVIDER_CONTRACT_ADMIN],
|
|
333
333
|
},
|
|
334
334
|
security_control: {
|
|
335
|
-
'*': [contractx_roles_constants_1.CONTRACTX_ROLES.
|
|
335
|
+
'*': [contractx_roles_constants_1.CONTRACTX_ROLES.SUPER_ADMIN, contractx_roles_constants_1.CONTRACTX_ROLES.SUPPORT],
|
|
336
336
|
},
|
|
337
337
|
};
|
|
338
338
|
return resourceRoleMap[resource]?.[action] || resourceRoleMap[resource]?.['*'] || [];
|
|
@@ -272,7 +272,7 @@ let UserContextService = class UserContextService {
|
|
|
272
272
|
* Check if user is a superadmin
|
|
273
273
|
*/
|
|
274
274
|
isSuperAdmin() {
|
|
275
|
-
return this.hasRole(contractx_roles_constants_1.CONTRACTX_ROLES.
|
|
275
|
+
return this.hasRole(contractx_roles_constants_1.CONTRACTX_ROLES.SUPER_ADMIN);
|
|
276
276
|
}
|
|
277
277
|
/**
|
|
278
278
|
* Check if user has admin privileges (superadmin or contract admin)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "permissions-contractx",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.0",
|
|
4
4
|
"description": "Enterprise-grade authentication and authorization package for NestJS microservices with role-based and permission-based access control",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|