permissions-contractx 1.0.1 → 1.0.2

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.
@@ -3,13 +3,24 @@ import { JwtPayload } from '../interfaces';
3
3
  * Request-scoped service to manage current user context
4
4
  * Provides convenient methods to access user information and check permissions
5
5
  */
6
+ interface RequestWithUser {
7
+ user?: any;
8
+ tenant?: any;
9
+ }
6
10
  export declare class UserContextService {
11
+ private readonly request;
7
12
  private user;
13
+ private autoInitialized;
14
+ constructor(request: RequestWithUser);
8
15
  /**
9
16
  * Set the current user context
10
17
  * This is typically called by the authentication guard
11
18
  */
12
19
  setUser(user: JwtPayload): void;
20
+ /**
21
+ * Auto-initialize user from request if not manually set
22
+ */
23
+ private tryAutoInitialize;
13
24
  /**
14
25
  * Get the current authenticated user
15
26
  */
@@ -30,6 +41,11 @@ export declare class UserContextService {
30
41
  * Get the current user's client ID
31
42
  */
32
43
  getClientId(): string | null;
44
+ /**
45
+ * Get the tenant key (key_client) for multi-tenant operations
46
+ * Tries multiple sources: user.key_client, user.clientId, tenant.key_client
47
+ */
48
+ getTenantKey(): string | null;
33
49
  /**
34
50
  * Get the current user's session ID
35
51
  */
@@ -111,4 +127,5 @@ export declare class UserContextService {
111
127
  clientId: string | null;
112
128
  };
113
129
  }
130
+ export {};
114
131
  //# sourceMappingURL=user-context.service.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"user-context.service.d.ts","sourceRoot":"","sources":["../../src/services/user-context.service.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAG3C;;;GAGG;AACH,qBACa,kBAAkB;IAC7B,OAAO,CAAC,IAAI,CAA2B;IAEvC;;;OAGG;IACH,OAAO,CAAC,IAAI,EAAE,UAAU,GAAG,IAAI;IAI/B;;OAEG;IACH,OAAO,IAAI,UAAU,GAAG,IAAI;IAI5B;;OAEG;IACH,SAAS,IAAI,MAAM,GAAG,IAAI;IAK1B;;OAEG;IACH,eAAe,IAAI,MAAM,GAAG,IAAI;IAKhC;;OAEG;IACH,YAAY,IAAI,MAAM,GAAG,IAAI;IAK7B;;OAEG;IACH,WAAW,IAAI,MAAM,GAAG,IAAI;IAK5B;;OAEG;IACH,YAAY,IAAI,MAAM,GAAG,IAAI;IAK7B;;OAEG;IACH,YAAY,IAAI,MAAM,EAAE;IAIxB;;OAEG;IACH,kBAAkB,IAAI,MAAM,EAAE;IAI9B;;OAEG;IACH,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAI9B;;OAEG;IACH,UAAU,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,EAAE,GAAG,OAAO;IAKxD;;OAEG;IACH,WAAW,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,EAAE,GAAG,OAAO;IAKzD;;OAEG;IACH,aAAa,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO;IAI1C;;OAEG;IACH,gBAAgB,CAAC,WAAW,EAAE,MAAM,EAAE,GAAG,OAAO;IAKhD;;OAEG;IACH,iBAAiB,CAAC,WAAW,EAAE,MAAM,EAAE,GAAG,OAAO;IAKjD;;OAEG;IACH,eAAe,IAAI,OAAO;IAI1B;;OAEG;IACH,YAAY,IAAI,OAAO;IAIvB;;OAEG;IACH,OAAO,IAAI,OAAO;IAIlB;;OAEG;IACH,YAAY,IAAI,OAAO;IAIvB;;OAEG;IACH,cAAc,IAAI,OAAO;IAIzB;;OAEG;IACH,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO;IAOxC;;OAEG;IACH,oBAAoB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE;IAM9C;;OAEG;IACH,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO;IAIzD;;OAEG;IACH,cAAc,IAAI;QAChB,EAAE,EAAE,MAAM,GAAG,IAAI,CAAC;QAClB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;QACpB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;QACrB,KAAK,EAAE,MAAM,EAAE,CAAC;QAChB,eAAe,EAAE,MAAM,CAAC;QACxB,OAAO,EAAE,OAAO,CAAC;QACjB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;KACzB;CAWF"}
1
+ {"version":3,"file":"user-context.service.d.ts","sourceRoot":"","sources":["../../src/services/user-context.service.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAG3C;;;GAGG;AACH,UAAU,eAAe;IACvB,IAAI,CAAC,EAAE,GAAG,CAAC;IACX,MAAM,CAAC,EAAE,GAAG,CAAC;CACd;AAED,qBACa,kBAAkB;IAKV,OAAO,CAAC,QAAQ,CAAC,OAAO;IAJ3C,OAAO,CAAC,IAAI,CAA2B;IACvC,OAAO,CAAC,eAAe,CAAS;gBAGI,OAAO,EAAE,eAAe;IAG5D;;;OAGG;IACH,OAAO,CAAC,IAAI,EAAE,UAAU,GAAG,IAAI;IAI/B;;OAEG;IACH,OAAO,CAAC,iBAAiB;IA4EzB;;OAEG;IACH,OAAO,IAAI,UAAU,GAAG,IAAI;IAK5B;;OAEG;IACH,SAAS,IAAI,MAAM,GAAG,IAAI;IAM1B;;OAEG;IACH,eAAe,IAAI,MAAM,GAAG,IAAI;IAMhC;;OAEG;IACH,YAAY,IAAI,MAAM,GAAG,IAAI;IAM7B;;OAEG;IACH,WAAW,IAAI,MAAM,GAAG,IAAI;IAM5B;;;OAGG;IACH,YAAY,IAAI,MAAM,GAAG,IAAI;IAsC7B;;OAEG;IACH,YAAY,IAAI,MAAM,GAAG,IAAI;IAM7B;;OAEG;IACH,YAAY,IAAI,MAAM,EAAE;IAKxB;;OAEG;IACH,kBAAkB,IAAI,MAAM,EAAE;IAK9B;;OAEG;IACH,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAI9B;;OAEG;IACH,UAAU,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,EAAE,GAAG,OAAO;IAKxD;;OAEG;IACH,WAAW,CAAC,KAAK,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,EAAE,GAAG,OAAO;IAKzD;;OAEG;IACH,aAAa,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO;IAI1C;;OAEG;IACH,gBAAgB,CAAC,WAAW,EAAE,MAAM,EAAE,GAAG,OAAO;IAKhD;;OAEG;IACH,iBAAiB,CAAC,WAAW,EAAE,MAAM,EAAE,GAAG,OAAO;IAKjD;;OAEG;IACH,eAAe,IAAI,OAAO;IAK1B;;OAEG;IACH,YAAY,IAAI,OAAO;IAIvB;;OAEG;IACH,OAAO,IAAI,OAAO;IAIlB;;OAEG;IACH,YAAY,IAAI,OAAO;IAIvB;;OAEG;IACH,cAAc,IAAI,OAAO;IAIzB;;OAEG;IACH,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO;IAOxC;;OAEG;IACH,oBAAoB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE;IAM9C;;OAEG;IACH,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO;IAIzD;;OAEG;IACH,cAAc,IAAI;QAChB,EAAE,EAAE,MAAM,GAAG,IAAI,CAAC;QAClB,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;QACpB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;QACrB,KAAK,EAAE,MAAM,EAAE,CAAC;QAChB,eAAe,EAAE,MAAM,CAAC;QACxB,OAAO,EAAE,OAAO,CAAC;QACjB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;KACzB;CAWF"}
@@ -5,17 +5,22 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
5
5
  else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
6
  return c > 3 && r && Object.defineProperty(target, key, r), r;
7
7
  };
8
+ var __metadata = (this && this.__metadata) || function (k, v) {
9
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
+ };
11
+ var __param = (this && this.__param) || function (paramIndex, decorator) {
12
+ return function (target, key) { decorator(target, key, paramIndex); }
13
+ };
8
14
  Object.defineProperty(exports, "__esModule", { value: true });
9
15
  exports.UserContextService = void 0;
10
16
  const common_1 = require("@nestjs/common");
17
+ const core_1 = require("@nestjs/core");
11
18
  const contractx_roles_constants_1 = require("../constants/contractx-roles.constants");
12
- /**
13
- * Request-scoped service to manage current user context
14
- * Provides convenient methods to access user information and check permissions
15
- */
16
19
  let UserContextService = class UserContextService {
17
- constructor() {
20
+ constructor(request) {
21
+ this.request = request;
18
22
  this.user = null;
23
+ this.autoInitialized = false;
19
24
  }
20
25
  /**
21
26
  * Set the current user context
@@ -24,16 +29,89 @@ let UserContextService = class UserContextService {
24
29
  setUser(user) {
25
30
  this.user = user;
26
31
  }
32
+ /**
33
+ * Auto-initialize user from request if not manually set
34
+ */
35
+ tryAutoInitialize() {
36
+ if (this.autoInitialized || this.user !== null) {
37
+ return;
38
+ }
39
+ this.autoInitialized = true;
40
+ // Try to get user from request.user (populated by JWT middleware)
41
+ if (this.request?.user) {
42
+ try {
43
+ // Handle different user object formats
44
+ const requestUser = this.request.user;
45
+ // Convert to JwtPayload format
46
+ const payload = {
47
+ sub: requestUser.sub || requestUser.id || requestUser.user_id,
48
+ role: requestUser.role || requestUser.roles || [],
49
+ permissions: requestUser.permissions || [],
50
+ fullName: requestUser.fullName || requestUser.full_name || requestUser.username || '',
51
+ email: requestUser.email,
52
+ clientId: Array.isArray(requestUser.clientId)
53
+ ? requestUser.clientId[0]
54
+ : (requestUser.clientId || requestUser.client_id),
55
+ sessionId: requestUser.sessionId || requestUser.session_id,
56
+ iat: requestUser.iat,
57
+ exp: requestUser.exp,
58
+ iss: requestUser.iss,
59
+ aud: requestUser.aud,
60
+ };
61
+ // Copy any additional properties
62
+ Object.keys(requestUser).forEach(key => {
63
+ if (!(key in payload)) {
64
+ payload[key] = requestUser[key];
65
+ }
66
+ });
67
+ this.user = payload;
68
+ return;
69
+ }
70
+ catch (error) {
71
+ // If parsing fails, continue to try request.tenant
72
+ }
73
+ }
74
+ // Fallback: try to get user from request.tenant (if populated by custom middleware)
75
+ if (this.request?.tenant) {
76
+ try {
77
+ const tenant = this.request.tenant;
78
+ const payload = {
79
+ sub: tenant.user_id || tenant.sub || tenant.id,
80
+ role: tenant.roles || [tenant.role].filter(Boolean),
81
+ permissions: tenant.permissions || [],
82
+ fullName: tenant.fullName || tenant.full_name || tenant.username || '',
83
+ email: tenant.email,
84
+ clientId: Array.isArray(tenant.clientId)
85
+ ? tenant.clientId[0]
86
+ : (tenant.clientId || tenant.client_id),
87
+ sessionId: tenant.sessionId || tenant.session_id,
88
+ };
89
+ // Copy additional properties
90
+ Object.keys(tenant).forEach(key => {
91
+ if (!(key in payload)) {
92
+ payload[key] = tenant[key];
93
+ }
94
+ });
95
+ this.user = payload;
96
+ return;
97
+ }
98
+ catch (error) {
99
+ // If parsing fails, user remains null
100
+ }
101
+ }
102
+ }
27
103
  /**
28
104
  * Get the current authenticated user
29
105
  */
30
106
  getUser() {
107
+ this.tryAutoInitialize();
31
108
  return this.user;
32
109
  }
33
110
  /**
34
111
  * Get the current user's ID
35
112
  */
36
113
  getUserId() {
114
+ this.tryAutoInitialize();
37
115
  if (this.user?.sub === undefined || this.user?.sub === null)
38
116
  return null;
39
117
  return String(this.user.sub);
@@ -42,6 +120,7 @@ let UserContextService = class UserContextService {
42
120
  * Get the current user's full name
43
121
  */
44
122
  getUserFullName() {
123
+ this.tryAutoInitialize();
45
124
  if (this.user?.fullName === undefined || this.user?.fullName === null)
46
125
  return null;
47
126
  return this.user.fullName;
@@ -50,6 +129,7 @@ let UserContextService = class UserContextService {
50
129
  * Get the current user's email
51
130
  */
52
131
  getUserEmail() {
132
+ this.tryAutoInitialize();
53
133
  if (this.user?.email === undefined || this.user?.email === null)
54
134
  return null;
55
135
  return this.user.email;
@@ -58,14 +138,51 @@ let UserContextService = class UserContextService {
58
138
  * Get the current user's client ID
59
139
  */
60
140
  getClientId() {
141
+ this.tryAutoInitialize();
61
142
  if (this.user?.clientId === undefined || this.user?.clientId === null)
62
143
  return null;
63
- return this.user.clientId;
144
+ return Array.isArray(this.user.clientId) ? this.user.clientId[0] : this.user.clientId;
145
+ }
146
+ /**
147
+ * Get the tenant key (key_client) for multi-tenant operations
148
+ * Tries multiple sources: user.key_client, user.clientId, tenant.key_client
149
+ */
150
+ getTenantKey() {
151
+ this.tryAutoInitialize();
152
+ // Try to get from user object first
153
+ if (this.user) {
154
+ // Check for key_client property
155
+ const keyClient = this.user.key_client;
156
+ if (keyClient) {
157
+ return Array.isArray(keyClient) ? keyClient[0] : keyClient;
158
+ }
159
+ // Fallback to clientId
160
+ if (this.user.clientId) {
161
+ return Array.isArray(this.user.clientId) ? this.user.clientId[0] : this.user.clientId;
162
+ }
163
+ }
164
+ // Try to get from request.tenant directly
165
+ if (this.request?.tenant?.key_client) {
166
+ const tenantKeyClient = this.request.tenant.key_client;
167
+ return Array.isArray(tenantKeyClient) ? tenantKeyClient[0] : tenantKeyClient;
168
+ }
169
+ // Try to get from request.user directly (in case of format differences)
170
+ if (this.request?.user?.key_client) {
171
+ const userKeyClient = this.request.user.key_client;
172
+ return Array.isArray(userKeyClient) ? userKeyClient[0] : userKeyClient;
173
+ }
174
+ // Try to get clientId from request.user directly
175
+ if (this.request?.user?.clientId) {
176
+ const userClientId = this.request.user.clientId;
177
+ return Array.isArray(userClientId) ? userClientId[0] : userClientId;
178
+ }
179
+ return null;
64
180
  }
65
181
  /**
66
182
  * Get the current user's session ID
67
183
  */
68
184
  getSessionId() {
185
+ this.tryAutoInitialize();
69
186
  if (this.user?.sessionId === undefined || this.user?.sessionId === null)
70
187
  return null;
71
188
  return this.user.sessionId;
@@ -74,12 +191,14 @@ let UserContextService = class UserContextService {
74
191
  * Get all user roles
75
192
  */
76
193
  getUserRoles() {
194
+ this.tryAutoInitialize();
77
195
  return this.user?.role || [];
78
196
  }
79
197
  /**
80
198
  * Get all user permissions
81
199
  */
82
200
  getUserPermissions() {
201
+ this.tryAutoInitialize();
83
202
  return this.user?.permissions || [];
84
203
  }
85
204
  /**
@@ -126,6 +245,7 @@ let UserContextService = class UserContextService {
126
245
  * Check if user is authenticated
127
246
  */
128
247
  isAuthenticated() {
248
+ this.tryAutoInitialize();
129
249
  return this.user !== null;
130
250
  }
131
251
  /**
@@ -188,5 +308,7 @@ let UserContextService = class UserContextService {
188
308
  };
189
309
  exports.UserContextService = UserContextService;
190
310
  exports.UserContextService = UserContextService = __decorate([
191
- (0, common_1.Injectable)({ scope: common_1.Scope.REQUEST })
311
+ (0, common_1.Injectable)({ scope: common_1.Scope.REQUEST }),
312
+ __param(0, (0, common_1.Inject)(core_1.REQUEST)),
313
+ __metadata("design:paramtypes", [Object])
192
314
  ], UserContextService);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "permissions-contractx",
3
- "version": "1.0.1",
3
+ "version": "1.0.2",
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",