ecrs-auth-core 1.0.65 → 1.0.66

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.
@@ -23,7 +23,7 @@ export declare class AuthController {
23
23
  parentId: number;
24
24
  referenceId: number;
25
25
  branchId: any;
26
- dispatchId: any;
26
+ dispatchCenterId: any;
27
27
  departmentId: any;
28
28
  designationId: any;
29
29
  profile_photo_url: string;
@@ -41,6 +41,7 @@ export declare class AuthService {
41
41
  * 4. If match found → Allow login (return true)
42
42
  * 5. If NO match → Deny login (return false)
43
43
  */
44
+ private normalizeIp;
44
45
  private validateIpRestriction;
45
46
  hasModuleAccess(userId: number, moduleId: number): Promise<boolean>;
46
47
  getPermissions(userId: number): Promise<PermissionsTree>;
@@ -77,7 +78,7 @@ export declare class AuthService {
77
78
  parentId: number;
78
79
  referenceId: number;
79
80
  branchId: any;
80
- dispatchId: any;
81
+ dispatchCenterId: any;
81
82
  departmentId: any;
82
83
  designationId: any;
83
84
  profile_photo_url: string;
@@ -85,6 +86,11 @@ export declare class AuthService {
85
86
  };
86
87
  access_token: string;
87
88
  }>;
89
+ /**
90
+ * Extract clean IPv4 address from request
91
+ * Handles various formats: IPv6-mapped, plain IPv4, descriptive text
92
+ */
93
+ extractUserIpv4(clientIp: string | undefined): string;
88
94
  findUserById(id: number): Promise<User | null>;
89
95
  private loadPermissions;
90
96
  }
@@ -96,12 +96,31 @@ let AuthService = class AuthService {
96
96
  * 4. If match found → Allow login (return true)
97
97
  * 5. If NO match → Deny login (return false)
98
98
  */
99
+ normalizeIp(ip) {
100
+ // Remove descriptive text if present (e.g., "IPv4 Address. . . . . . : 192.167.0.173")
101
+ let cleanIp = ip.trim();
102
+ if (cleanIp.includes(':')) {
103
+ const parts = cleanIp.split(':');
104
+ cleanIp = parts[parts.length - 1].trim();
105
+ }
106
+ // Convert IPv6-mapped IPv4 addresses (::ffff:x.x.x.x) to plain IPv4 (x.x.x.x)
107
+ if (cleanIp.startsWith('::ffff:')) {
108
+ return cleanIp.substring(7);
109
+ }
110
+ // Also handle other IPv6 prefixes
111
+ if (cleanIp.startsWith('::1')) {
112
+ return '127.0.0.1'; // IPv6 loopback to IPv4 loopback
113
+ }
114
+ return cleanIp;
115
+ }
99
116
  async validateIpRestriction(userId, requestIp) {
100
117
  if (!this.ipRestrictionsRepo) {
101
118
  // No IP restrictions repository configured - allow login
102
119
  return true;
103
120
  }
104
121
  try {
122
+ // Normalize the incoming IP
123
+ const normalizedRequestIp = this.normalizeIp(requestIp);
105
124
  // Get all active IP restrictions for this user
106
125
  const restrictions = await this.ipRestrictionsRepo.find({
107
126
  where: {
@@ -117,15 +136,19 @@ let AuthService = class AuthService {
117
136
  const ipMatches = restrictions.some((restriction) => {
118
137
  // Handle both property name variations
119
138
  const allowedIp = restriction.allowed_ip_address || restriction.ip_address;
120
- return allowedIp === requestIp;
139
+ const normalizedAllowedIp = this.normalizeIp(allowedIp);
140
+ return normalizedAllowedIp === normalizedRequestIp;
121
141
  });
122
142
  if (ipMatches) {
123
- console.log(`✅ User ${userId}: IP ${requestIp} matches allowed IP - Allow login`);
143
+ console.log(`✅ User ${userId}: IP ${requestIp} (normalized: ${normalizedRequestIp}) matches allowed IP - Allow login`);
124
144
  return true;
125
145
  }
126
146
  // IP doesn't match any allowed IP
127
- const allowedIps = restrictions.map((r) => r.allowed_ip_address || r.ip_address).join(', ');
128
- console.log(`❌ User ${userId}: IP ${requestIp} does not match allowed IPs - Deny login`);
147
+ const allowedIps = restrictions.map((r) => {
148
+ const ip = r.allowed_ip_address || r.ip_address;
149
+ return this.normalizeIp(ip);
150
+ }).join(', ');
151
+ console.log(`❌ User ${userId}: IP ${requestIp} (normalized: ${normalizedRequestIp}) does not match allowed IPs - Deny login`);
129
152
  console.log(` Allowed IPs: ${allowedIps}`);
130
153
  return false;
131
154
  }
@@ -186,7 +209,7 @@ let AuthService = class AuthService {
186
209
  const effectiveModuleId = Number.isFinite(selectedModuleId) ? selectedModuleId : user.moduleId ?? null;
187
210
  // Fetch workprofile/employee details from EmployeeWorkProfileEntity
188
211
  let branchId = null;
189
- let dispatchId = null;
212
+ let dispatchCenterId = null;
190
213
  let departmentId = null;
191
214
  let designationId = null;
192
215
  if (this.employeeWorkProfileRepo) {
@@ -196,7 +219,7 @@ let AuthService = class AuthService {
196
219
  });
197
220
  if (workProfile) {
198
221
  branchId = workProfile?.branch_id || null;
199
- dispatchId = workProfile?.dispatch_id || null;
222
+ dispatchCenterId = workProfile?.dispatch_id || null;
200
223
  departmentId = workProfile?.department_id || null;
201
224
  designationId = workProfile?.designation_id || null;
202
225
  }
@@ -222,7 +245,7 @@ let AuthService = class AuthService {
222
245
  parentId: user.parentId,
223
246
  referenceId: user.referenceId,
224
247
  branchId,
225
- dispatchId,
248
+ dispatchCenterId,
226
249
  departmentId,
227
250
  designationId,
228
251
  };
@@ -245,7 +268,7 @@ let AuthService = class AuthService {
245
268
  parentId: user.parentId,
246
269
  referenceId: user.referenceId,
247
270
  branchId,
248
- dispatchId,
271
+ dispatchCenterId,
249
272
  departmentId,
250
273
  designationId,
251
274
  profile_photo_url: `${this.uploadPhotoDir}`,
@@ -254,6 +277,15 @@ let AuthService = class AuthService {
254
277
  access_token: this.jwtService.sign(payload),
255
278
  };
256
279
  }
280
+ /**
281
+ * Extract clean IPv4 address from request
282
+ * Handles various formats: IPv6-mapped, plain IPv4, descriptive text
283
+ */
284
+ extractUserIpv4(clientIp) {
285
+ if (!clientIp)
286
+ return '';
287
+ return this.normalizeIp(clientIp);
288
+ }
257
289
  async findUserById(id) {
258
290
  return this.userRepo.findOne({ where: { id } });
259
291
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ecrs-auth-core",
3
- "version": "1.0.65",
3
+ "version": "1.0.66",
4
4
  "description": "Centralized authentication and authorization module for ECRS apps",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",