ecrs-auth-core 1.0.81 → 1.0.83
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/auth.controller.d.ts +3 -2
- package/dist/auth.controller.js +36 -15
- package/dist/auth.service.js +47 -11
- package/dist/jwt/jwt.strategy.js +4 -0
- package/package.json +1 -1
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import { Request } from 'express';
|
|
2
|
+
import { JwtService } from '@nestjs/jwt';
|
|
2
3
|
import { AuthService } from './auth.service';
|
|
3
4
|
import { LoginDto } from './dtos/login.dto';
|
|
4
5
|
export declare class AuthController {
|
|
5
6
|
private readonly authService;
|
|
6
|
-
|
|
7
|
+
private readonly jwtService;
|
|
8
|
+
constructor(authService: AuthService, jwtService: JwtService);
|
|
7
9
|
login(request: Request, body: LoginDto): Promise<{
|
|
8
10
|
status: boolean;
|
|
9
11
|
message: string;
|
|
@@ -39,7 +41,6 @@ export declare class AuthController {
|
|
|
39
41
|
data: {
|
|
40
42
|
user: {
|
|
41
43
|
id: any;
|
|
42
|
-
email: any;
|
|
43
44
|
logoutTime: string;
|
|
44
45
|
};
|
|
45
46
|
};
|
package/dist/auth.controller.js
CHANGED
|
@@ -14,13 +14,15 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
|
14
14
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
15
|
exports.AuthController = void 0;
|
|
16
16
|
const common_1 = require("@nestjs/common");
|
|
17
|
+
const jwt_1 = require("@nestjs/jwt");
|
|
17
18
|
const auth_service_1 = require("./auth.service");
|
|
18
19
|
const login_dto_1 = require("./dtos/login.dto");
|
|
19
20
|
const login_response_dto_1 = require("./dtos/login-response.dto");
|
|
20
21
|
const swagger_1 = require("@nestjs/swagger");
|
|
21
22
|
let AuthController = class AuthController {
|
|
22
|
-
constructor(authService) {
|
|
23
|
+
constructor(authService, jwtService) {
|
|
23
24
|
this.authService = authService;
|
|
25
|
+
this.jwtService = jwtService;
|
|
24
26
|
}
|
|
25
27
|
async login(request, body) {
|
|
26
28
|
// Get client IP from socket/request
|
|
@@ -73,36 +75,48 @@ let AuthController = class AuthController {
|
|
|
73
75
|
return loginResponse;
|
|
74
76
|
}
|
|
75
77
|
async logout(request) {
|
|
76
|
-
//
|
|
77
|
-
const
|
|
78
|
-
if (!
|
|
79
|
-
throw new common_1.UnauthorizedException('
|
|
78
|
+
// Extract JWT token from Authorization header
|
|
79
|
+
const authHeader = request.headers.authorization;
|
|
80
|
+
if (!authHeader || !authHeader.startsWith('Bearer ')) {
|
|
81
|
+
throw new common_1.UnauthorizedException('Missing or invalid Authorization header. Required format: Bearer <token>');
|
|
80
82
|
}
|
|
81
|
-
|
|
83
|
+
const token = authHeader.substring(7); // Remove 'Bearer ' prefix
|
|
82
84
|
try {
|
|
85
|
+
// Decode JWT token to get user ID
|
|
86
|
+
const payload = this.jwtService.verify(token);
|
|
87
|
+
const userId = payload.id;
|
|
88
|
+
if (!userId) {
|
|
89
|
+
throw new common_1.UnauthorizedException('Invalid token - no user ID found');
|
|
90
|
+
}
|
|
91
|
+
console.log(`🚪 Logout request for user ${userId}`);
|
|
83
92
|
// Update logout details in both tables
|
|
84
93
|
await Promise.all([
|
|
85
|
-
this.authService.updateLastLoginLogout(
|
|
94
|
+
this.authService.updateLastLoginLogout(userId).catch((err) => {
|
|
86
95
|
console.error('❌ Error updating logout in tbl_user_last_login:', err.message);
|
|
87
96
|
}),
|
|
88
|
-
this.authService.updateLoginLogoutDetailsJson(
|
|
97
|
+
this.authService.updateLoginLogoutDetailsJson(userId).catch((err) => {
|
|
89
98
|
console.error('❌ Error updating logout in tbl_user_login_details:', err.message);
|
|
90
99
|
})
|
|
91
100
|
]);
|
|
92
|
-
console.log(`✅ User ${
|
|
101
|
+
console.log(`✅ User ${userId} logged out successfully`);
|
|
93
102
|
return {
|
|
94
103
|
status: true,
|
|
95
104
|
message: 'Logout successful',
|
|
96
105
|
data: {
|
|
97
106
|
user: {
|
|
98
|
-
id:
|
|
99
|
-
email: user.email,
|
|
107
|
+
id: userId,
|
|
100
108
|
logoutTime: new Date().toISOString()
|
|
101
109
|
}
|
|
102
110
|
}
|
|
103
111
|
};
|
|
104
112
|
}
|
|
105
113
|
catch (error) {
|
|
114
|
+
if (error.name === 'TokenExpiredError') {
|
|
115
|
+
throw new common_1.UnauthorizedException('JWT token has expired');
|
|
116
|
+
}
|
|
117
|
+
if (error.name === 'JsonWebTokenError') {
|
|
118
|
+
throw new common_1.UnauthorizedException('Invalid JWT token');
|
|
119
|
+
}
|
|
106
120
|
console.error('❌ Error during logout:', error?.message || error);
|
|
107
121
|
throw new common_1.UnauthorizedException('Logout failed');
|
|
108
122
|
}
|
|
@@ -260,16 +274,22 @@ __decorate([
|
|
|
260
274
|
(0, common_1.HttpCode)(200),
|
|
261
275
|
(0, swagger_1.ApiOperation)({
|
|
262
276
|
summary: 'User logout',
|
|
263
|
-
description: 'Logout user and update session end time'
|
|
277
|
+
description: 'Logout user and update session end time. Extracts user ID from JWT token in Authorization header.'
|
|
264
278
|
}),
|
|
265
279
|
(0, swagger_1.ApiOkResponse)({
|
|
266
280
|
description: 'Logout successful',
|
|
267
281
|
example: {
|
|
268
282
|
status: true,
|
|
269
|
-
message: 'Logout successful'
|
|
283
|
+
message: 'Logout successful',
|
|
284
|
+
data: {
|
|
285
|
+
user: {
|
|
286
|
+
id: 1,
|
|
287
|
+
logoutTime: '2026-01-28T10:30:00.000Z'
|
|
288
|
+
}
|
|
289
|
+
}
|
|
270
290
|
}
|
|
271
291
|
}),
|
|
272
|
-
(0, swagger_1.ApiUnauthorizedResponse)({ description: 'Unauthorized' }),
|
|
292
|
+
(0, swagger_1.ApiUnauthorizedResponse)({ description: 'Unauthorized - Invalid or missing JWT token' }),
|
|
273
293
|
__param(0, (0, common_1.Req)()),
|
|
274
294
|
__metadata("design:type", Function),
|
|
275
295
|
__metadata("design:paramtypes", [Object]),
|
|
@@ -280,5 +300,6 @@ exports.AuthController = AuthController = __decorate([
|
|
|
280
300
|
(0, swagger_1.ApiBearerAuth)(),
|
|
281
301
|
(0, swagger_1.ApiExtraModels)(login_dto_1.LoginDto, login_response_dto_1.LoginResponseDto),
|
|
282
302
|
(0, common_1.Controller)('auth'),
|
|
283
|
-
__metadata("design:paramtypes", [auth_service_1.AuthService
|
|
303
|
+
__metadata("design:paramtypes", [auth_service_1.AuthService,
|
|
304
|
+
jwt_1.JwtService])
|
|
284
305
|
], AuthController);
|
package/dist/auth.service.js
CHANGED
|
@@ -72,18 +72,24 @@ let AuthService = class AuthService {
|
|
|
72
72
|
}
|
|
73
73
|
async validateUser(email, password, clientIp) {
|
|
74
74
|
const user = await this.userRepo.findOne({ where: { email } });
|
|
75
|
-
if (!user)
|
|
76
|
-
|
|
75
|
+
if (!user) {
|
|
76
|
+
throw new common_1.UnauthorizedException('The email address is invalid or not registered.');
|
|
77
|
+
}
|
|
77
78
|
const isValid = await bcrypt.compare(password, user.password);
|
|
78
|
-
if (!isValid)
|
|
79
|
-
|
|
79
|
+
if (!isValid) {
|
|
80
|
+
throw new common_1.UnauthorizedException('The password is incorrect. Please try again.');
|
|
81
|
+
}
|
|
82
|
+
;
|
|
83
|
+
if (user.status !== 1) {
|
|
84
|
+
throw new common_1.UnauthorizedException('Your account is inactive. Please contact support.');
|
|
85
|
+
}
|
|
80
86
|
// console.log(this.ipRestrictionsRepo);
|
|
81
87
|
// Check IP restrictions if provided and repository is available
|
|
82
88
|
if (clientIp && this.ipRestrictionsRepo) {
|
|
83
89
|
const ipAllowed = await this.validateIpRestriction(user.id, clientIp);
|
|
84
90
|
if (!ipAllowed) {
|
|
85
|
-
// IP restriction exists but doesn't match -
|
|
86
|
-
|
|
91
|
+
// IP restriction exists but doesn't match - throw UnauthorizedException to block login
|
|
92
|
+
throw new common_1.UnauthorizedException('Login denied: Your IP address is not allowed.');
|
|
87
93
|
}
|
|
88
94
|
}
|
|
89
95
|
return user;
|
|
@@ -220,7 +226,14 @@ let AuthService = class AuthService {
|
|
|
220
226
|
console.log(`📝 Last login details saved for user ${user.id} (${loginStatus})`);
|
|
221
227
|
}
|
|
222
228
|
catch (error) {
|
|
223
|
-
|
|
229
|
+
if (error?.message?.includes('No metadata')) {
|
|
230
|
+
console.error('❌ ERROR: UserLastLoginEntity is not registered in your TypeORM configuration.\n' +
|
|
231
|
+
'Please see ENTITY_SETUP_GUIDE.md for setup instructions.\n' +
|
|
232
|
+
'Entity must be added to TypeOrmModule.forRoot(entities: [...]) in your app.');
|
|
233
|
+
}
|
|
234
|
+
else {
|
|
235
|
+
console.error('Error saving last login details:', error);
|
|
236
|
+
}
|
|
224
237
|
// Don't throw error - this shouldn't block login
|
|
225
238
|
}
|
|
226
239
|
}
|
|
@@ -307,7 +320,14 @@ let AuthService = class AuthService {
|
|
|
307
320
|
}
|
|
308
321
|
}
|
|
309
322
|
catch (error) {
|
|
310
|
-
|
|
323
|
+
if (error?.message?.includes('No metadata')) {
|
|
324
|
+
console.error('❌ ERROR: LoginDetailsEntity is not registered in your TypeORM configuration.\n' +
|
|
325
|
+
'Please see ENTITY_SETUP_GUIDE.md for setup instructions.\n' +
|
|
326
|
+
'Entity must be added to TypeOrmModule.forRoot(entities: [...]) in your app.');
|
|
327
|
+
}
|
|
328
|
+
else {
|
|
329
|
+
console.error('Error saving login details JSON:', error);
|
|
330
|
+
}
|
|
311
331
|
// Don't throw error - this shouldn't block login
|
|
312
332
|
}
|
|
313
333
|
}
|
|
@@ -356,7 +376,13 @@ let AuthService = class AuthService {
|
|
|
356
376
|
console.log(`🚪 Logout details updated for user ${userId} on ${today.toDateString()}`);
|
|
357
377
|
}
|
|
358
378
|
catch (error) {
|
|
359
|
-
|
|
379
|
+
if (error?.message?.includes('No metadata')) {
|
|
380
|
+
console.error('❌ ERROR: LoginDetailsEntity is not registered in your TypeORM configuration.\n' +
|
|
381
|
+
'Please see ENTITY_SETUP_GUIDE.md for setup instructions.');
|
|
382
|
+
}
|
|
383
|
+
else {
|
|
384
|
+
console.error('Error updating logout details:', error);
|
|
385
|
+
}
|
|
360
386
|
// Don't throw error - this shouldn't block logout
|
|
361
387
|
}
|
|
362
388
|
}
|
|
@@ -383,7 +409,13 @@ let AuthService = class AuthService {
|
|
|
383
409
|
console.log(`🚪 Last login logout time updated for user ${userId}`);
|
|
384
410
|
}
|
|
385
411
|
catch (error) {
|
|
386
|
-
|
|
412
|
+
if (error?.message?.includes('No metadata')) {
|
|
413
|
+
console.error('❌ ERROR: UserLastLoginEntity is not registered in your TypeORM configuration.\n' +
|
|
414
|
+
'Please see ENTITY_SETUP_GUIDE.md for setup instructions.');
|
|
415
|
+
}
|
|
416
|
+
else {
|
|
417
|
+
console.error('Error updating last login logout time:', error);
|
|
418
|
+
}
|
|
387
419
|
// Don't throw error - this shouldn't block logout
|
|
388
420
|
}
|
|
389
421
|
}
|
|
@@ -462,6 +494,10 @@ let AuthService = class AuthService {
|
|
|
462
494
|
lastLoginTime: lastLoginTime,
|
|
463
495
|
is_reset_password: is_reset_password,
|
|
464
496
|
};
|
|
497
|
+
// Generate JWT token
|
|
498
|
+
const accessToken = this.jwtService.sign(payload);
|
|
499
|
+
// Update user's apiToken in the database
|
|
500
|
+
await this.userRepo.update({ id: user.id }, { apiToken: accessToken });
|
|
465
501
|
return {
|
|
466
502
|
status: true,
|
|
467
503
|
message: 'Login successful',
|
|
@@ -489,7 +525,7 @@ let AuthService = class AuthService {
|
|
|
489
525
|
profile_photo_url: `${this.uploadPhotoDir}/${user.userImage}`,
|
|
490
526
|
},
|
|
491
527
|
},
|
|
492
|
-
access_token:
|
|
528
|
+
access_token: accessToken,
|
|
493
529
|
};
|
|
494
530
|
}
|
|
495
531
|
/**
|
package/dist/jwt/jwt.strategy.js
CHANGED
|
@@ -34,6 +34,10 @@ let JwtStrategy = class JwtStrategy extends (0, passport_1.PassportStrategy)(pas
|
|
|
34
34
|
console.log(`✅ User ${user.id} has access to module ${payload.moduleId}`);
|
|
35
35
|
}
|
|
36
36
|
console.log(`✅ JWT validated for user ${user.id}`);
|
|
37
|
+
if (user.status !== 1) {
|
|
38
|
+
console.log(`❌ User ${user.id} is not active`);
|
|
39
|
+
throw new common_1.UnauthorizedException('Your account is inactive. Please contact support.');
|
|
40
|
+
}
|
|
37
41
|
return {
|
|
38
42
|
id: user.id,
|
|
39
43
|
email: user.email,
|