ecrs-auth-core 1.0.69 → 1.0.71

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.
@@ -1,206 +1,207 @@
1
- "use strict";
2
- var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
- var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
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
- return c > 3 && r && Object.defineProperty(target, key, r), r;
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
- };
14
- Object.defineProperty(exports, "__esModule", { value: true });
15
- exports.AuthController = void 0;
16
- const common_1 = require("@nestjs/common");
17
- const auth_service_1 = require("./auth.service");
18
- const login_dto_1 = require("./dtos/login.dto");
19
- const login_response_dto_1 = require("./dtos/login-response.dto");
20
- const swagger_1 = require("@nestjs/swagger");
21
- let AuthController = class AuthController {
22
- constructor(authService) {
23
- this.authService = authService;
24
- }
25
- async login(request, body) {
26
- // Get client IP from socket/request
27
- const clientIp = this.getClientIp(request);
28
- const userAgent = request.get('user-agent') || 'Unknown';
29
- // Extract additional client data
30
- const additionalData = this.extractClientData(request, userAgent);
31
- console.log(`📍 Login attempt from IP: ${clientIp}, User-Agent: ${userAgent}`);
32
- // Validate user with IP restriction check
33
- const user = await this.authService.validateUser(body.email, body.password, clientIp);
34
- if (!user) {
35
- // Save failed login attempt
36
- await this.authService.saveLastLogin({ email: body.email }, clientIp, 'failed', 'Invalid credentials or IP not allowed', additionalData).catch(() => { }); // Ignore errors
37
- throw new common_1.UnauthorizedException('Login failed: email or password not matched or IP not allowed');
38
- }
39
- const requestedModuleId = Number(body.moduleId);
40
- if (!Number.isFinite(requestedModuleId)) {
41
- throw new common_1.UnauthorizedException('You are not authorized to access this module');
42
- }
43
- const allowedDb = await this.authService.hasModuleAccess(user.id, requestedModuleId);
44
- if (!allowedDb) {
45
- throw new common_1.UnauthorizedException('You are not authorized to access this module');
46
- }
47
- const perms = await this.authService.getPermissions(user.id);
48
- if (!Array.isArray(perms.modules) || !perms.modules.includes(requestedModuleId)) {
49
- throw new common_1.UnauthorizedException('You are not authorized to access this module');
50
- }
51
- const loginResponse = await this.authService.login(user, requestedModuleId);
52
- // Save successful login details with additional client data
53
- await this.authService.saveLastLogin(user, clientIp, 'success', undefined, {
54
- ...additionalData,
55
- moduleId: requestedModuleId,
56
- }).catch(() => { }); // Ignore errors - don't block login
57
- return loginResponse;
58
- }
59
- /**
60
- * Extract additional client data from request and user-agent
61
- */
62
- extractClientData(request, userAgent) {
63
- const { browser, os, deviceType } = this.parseUserAgent(userAgent);
64
- const ipAddressName = request.get('x-forwarded-host') || request.get('host') || 'Unknown';
65
- const location = request.get('cf-ipcountry') || 'Unknown'; // Cloudflare header
66
- return {
67
- browser,
68
- deviceType,
69
- operatingSystem: os,
70
- userAgent,
71
- location,
72
- ipAddressName,
73
- };
74
- }
75
- /**
76
- * Parse user-agent string to extract browser, OS, and device type
77
- */
78
- parseUserAgent(userAgent) {
79
- const ua = userAgent.toLowerCase();
80
- // Detect browser
81
- let browser = 'Unknown';
82
- if (ua.includes('chrome'))
83
- browser = 'Chrome';
84
- else if (ua.includes('firefox'))
85
- browser = 'Firefox';
86
- else if (ua.includes('safari'))
87
- browser = 'Safari';
88
- else if (ua.includes('edg/'))
89
- browser = 'Edge';
90
- else if (ua.includes('opera') || ua.includes('opr/'))
91
- browser = 'Opera';
92
- else if (ua.includes('trident'))
93
- browser = 'Internet Explorer';
94
- // Detect OS
95
- let os = 'Unknown';
96
- if (ua.includes('windows'))
97
- os = 'Windows';
98
- else if (ua.includes('mac'))
99
- os = 'macOS';
100
- else if (ua.includes('linux'))
101
- os = 'Linux';
102
- else if (ua.includes('iphone') || ua.includes('ipad'))
103
- os = 'iOS';
104
- else if (ua.includes('android'))
105
- os = 'Android';
106
- // Detect device type
107
- let deviceType = 'Desktop';
108
- if (ua.includes('mobile') || ua.includes('android') || ua.includes('iphone'))
109
- deviceType = 'Mobile';
110
- else if (ua.includes('tablet') || ua.includes('ipad'))
111
- deviceType = 'Tablet';
112
- return { browser, os, deviceType };
113
- }
114
- /**
115
- * Extract client IP from request
116
- * Priority:
117
- * 1. X-Forwarded-For header (proxy)
118
- * 2. X-Real-IP header (nginx)
119
- * 3. CF-Connecting-IP (Cloudflare)
120
- * 4. request.ip (Express native)
121
- * 5. socket.remoteAddress (direct connection)
122
- */
123
- getClientIp(request) {
124
- // Check X-Forwarded-For header (most common with proxies)
125
- const xForwardedFor = request.headers['x-forwarded-for'];
126
- if (xForwardedFor) {
127
- const ips = Array.isArray(xForwardedFor)
128
- ? xForwardedFor
129
- : xForwardedFor.split(',');
130
- return ips[0].trim();
131
- }
132
- // Check X-Real-IP header (nginx)
133
- const xRealIp = request.headers['x-real-ip'];
134
- if (xRealIp) {
135
- return Array.isArray(xRealIp) ? xRealIp[0] : xRealIp;
136
- }
137
- // Check CF-Connecting-IP (Cloudflare)
138
- const cfIp = request.headers['cf-connecting-ip'];
139
- if (cfIp) {
140
- return Array.isArray(cfIp) ? cfIp[0] : cfIp;
141
- }
142
- // Use Express native request.ip (handles proxies if trust proxy is set)
143
- if (request.ip) {
144
- return request.ip;
145
- }
146
- // Fallback to socket remote address
147
- const socketIp = (request.socket.remoteAddress || '').replace(/^.*:/, '');
148
- return socketIp || 'unknown';
149
- }
150
- };
151
- exports.AuthController = AuthController;
152
- __decorate([
153
- (0, common_1.Post)('login'),
154
- (0, common_1.HttpCode)(200),
155
- (0, swagger_1.ApiBody)({
156
- required: true,
157
- description: 'Credentials required for authentication',
158
- schema: {
159
- $ref: (0, swagger_1.getSchemaPath)(login_dto_1.LoginDto),
160
- example: { email: 'user@example.com', password: 'StrongP@ssw0rd', moduleId: '3' },
161
- },
162
- }),
163
- (0, swagger_1.ApiOperation)({
164
- summary: 'User login',
165
- description: 'Authenticate user and return access token'
166
- }),
167
- (0, swagger_1.ApiOkResponse)({
168
- description: 'Login successful',
169
- schema: {
170
- $ref: (0, swagger_1.getSchemaPath)(login_response_dto_1.LoginResponseDto),
171
- example: {
172
- status: true,
173
- message: 'Login successful',
174
- data: {
175
- user: {
176
- id: 1,
177
- email: 'user@example.com',
178
- roleId: 2,
179
- roleName: 'Admin',
180
- moduleId: 3,
181
- name: 'John Doe',
182
- firstName: 'John',
183
- lastName: 'Doe',
184
- mobileNo: 9876543210,
185
- userImage: 'https://cdn.example.com/avatar.png',
186
- employeeId: 1001
187
- }
188
- },
189
- access_token: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...'
190
- }
191
- }
192
- }),
193
- (0, swagger_1.ApiUnauthorizedResponse)({ description: 'Invalid credentials or IP not allowed' }),
194
- __param(0, (0, common_1.Req)()),
195
- __param(1, (0, common_1.Body)()),
196
- __metadata("design:type", Function),
197
- __metadata("design:paramtypes", [Object, login_dto_1.LoginDto]),
198
- __metadata("design:returntype", Promise)
199
- ], AuthController.prototype, "login", null);
200
- exports.AuthController = AuthController = __decorate([
201
- (0, swagger_1.ApiTags)('auth'),
202
- (0, swagger_1.ApiBearerAuth)(),
203
- (0, swagger_1.ApiExtraModels)(login_dto_1.LoginDto, login_response_dto_1.LoginResponseDto),
204
- (0, common_1.Controller)('auth'),
205
- __metadata("design:paramtypes", [auth_service_1.AuthService])
206
- ], AuthController);
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
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
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
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
+ };
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.AuthController = void 0;
16
+ const common_1 = require("@nestjs/common");
17
+ const auth_service_1 = require("./auth.service");
18
+ const login_dto_1 = require("./dtos/login.dto");
19
+ const login_response_dto_1 = require("./dtos/login-response.dto");
20
+ const swagger_1 = require("@nestjs/swagger");
21
+ let AuthController = class AuthController {
22
+ constructor(authService) {
23
+ this.authService = authService;
24
+ }
25
+ async login(request, body) {
26
+ // Get client IP from socket/request
27
+ const clientIp = this.getClientIp(request);
28
+ const userAgent = request.get('user-agent') || 'Unknown';
29
+ // Extract additional client data
30
+ const additionalData = this.extractClientData(request, userAgent);
31
+ console.log(`📍 Login attempt from IP: ${clientIp}, User-Agent: ${userAgent}`);
32
+ // Validate user with IP restriction check
33
+ const user = await this.authService.validateUser(body.email, body.password, clientIp);
34
+ console.log(`🔐 User validation result for ${body.email}: ${user ? 'Success' : 'Failed'}`);
35
+ if (!user) {
36
+ // Save failed login attempt
37
+ await this.authService.saveLastLogin({ email: body.email }, clientIp, 'failed', 'Invalid credentials or IP not allowed', additionalData).catch(() => { }); // Ignore errors
38
+ throw new common_1.UnauthorizedException('Login failed: email or password not matched or IP not allowed');
39
+ }
40
+ const requestedModuleId = Number(body.moduleId);
41
+ if (!Number.isFinite(requestedModuleId)) {
42
+ throw new common_1.UnauthorizedException('You are not authorized to access this module');
43
+ }
44
+ const allowedDb = await this.authService.hasModuleAccess(user.id, requestedModuleId);
45
+ if (!allowedDb) {
46
+ throw new common_1.UnauthorizedException('You are not authorized to access this module');
47
+ }
48
+ const perms = await this.authService.getPermissions(user.id);
49
+ if (!Array.isArray(perms.modules) || !perms.modules.includes(requestedModuleId)) {
50
+ throw new common_1.UnauthorizedException('You are not authorized to access this module');
51
+ }
52
+ const loginResponse = await this.authService.login(user, requestedModuleId);
53
+ // Save successful login details with additional client data
54
+ await this.authService.saveLastLogin(user, clientIp, 'success', undefined, {
55
+ ...additionalData,
56
+ moduleId: requestedModuleId,
57
+ }).catch(() => { }); // Ignore errors - don't block login
58
+ return loginResponse;
59
+ }
60
+ /**
61
+ * Extract additional client data from request and user-agent
62
+ */
63
+ extractClientData(request, userAgent) {
64
+ const { browser, os, deviceType } = this.parseUserAgent(userAgent);
65
+ const ipAddressName = request.get('x-forwarded-host') || request.get('host') || 'Unknown';
66
+ const location = request.get('cf-ipcountry') || 'Unknown'; // Cloudflare header
67
+ return {
68
+ browser,
69
+ deviceType,
70
+ operatingSystem: os,
71
+ userAgent,
72
+ location,
73
+ ipAddressName,
74
+ };
75
+ }
76
+ /**
77
+ * Parse user-agent string to extract browser, OS, and device type
78
+ */
79
+ parseUserAgent(userAgent) {
80
+ const ua = userAgent.toLowerCase();
81
+ // Detect browser
82
+ let browser = 'Unknown';
83
+ if (ua.includes('chrome'))
84
+ browser = 'Chrome';
85
+ else if (ua.includes('firefox'))
86
+ browser = 'Firefox';
87
+ else if (ua.includes('safari'))
88
+ browser = 'Safari';
89
+ else if (ua.includes('edg/'))
90
+ browser = 'Edge';
91
+ else if (ua.includes('opera') || ua.includes('opr/'))
92
+ browser = 'Opera';
93
+ else if (ua.includes('trident'))
94
+ browser = 'Internet Explorer';
95
+ // Detect OS
96
+ let os = 'Unknown';
97
+ if (ua.includes('windows'))
98
+ os = 'Windows';
99
+ else if (ua.includes('mac'))
100
+ os = 'macOS';
101
+ else if (ua.includes('linux'))
102
+ os = 'Linux';
103
+ else if (ua.includes('iphone') || ua.includes('ipad'))
104
+ os = 'iOS';
105
+ else if (ua.includes('android'))
106
+ os = 'Android';
107
+ // Detect device type
108
+ let deviceType = 'Desktop';
109
+ if (ua.includes('mobile') || ua.includes('android') || ua.includes('iphone'))
110
+ deviceType = 'Mobile';
111
+ else if (ua.includes('tablet') || ua.includes('ipad'))
112
+ deviceType = 'Tablet';
113
+ return { browser, os, deviceType };
114
+ }
115
+ /**
116
+ * Extract client IP from request
117
+ * Priority:
118
+ * 1. X-Forwarded-For header (proxy)
119
+ * 2. X-Real-IP header (nginx)
120
+ * 3. CF-Connecting-IP (Cloudflare)
121
+ * 4. request.ip (Express native)
122
+ * 5. socket.remoteAddress (direct connection)
123
+ */
124
+ getClientIp(request) {
125
+ // Check X-Forwarded-For header (most common with proxies)
126
+ const xForwardedFor = request.headers['x-forwarded-for'];
127
+ if (xForwardedFor) {
128
+ const ips = Array.isArray(xForwardedFor)
129
+ ? xForwardedFor
130
+ : xForwardedFor.split(',');
131
+ return ips[0].trim();
132
+ }
133
+ // Check X-Real-IP header (nginx)
134
+ const xRealIp = request.headers['x-real-ip'];
135
+ if (xRealIp) {
136
+ return Array.isArray(xRealIp) ? xRealIp[0] : xRealIp;
137
+ }
138
+ // Check CF-Connecting-IP (Cloudflare)
139
+ const cfIp = request.headers['cf-connecting-ip'];
140
+ if (cfIp) {
141
+ return Array.isArray(cfIp) ? cfIp[0] : cfIp;
142
+ }
143
+ // Use Express native request.ip (handles proxies if trust proxy is set)
144
+ if (request.ip) {
145
+ return request.ip;
146
+ }
147
+ // Fallback to socket remote address
148
+ const socketIp = (request.socket.remoteAddress || '').replace(/^.*:/, '');
149
+ return socketIp || 'unknown';
150
+ }
151
+ };
152
+ exports.AuthController = AuthController;
153
+ __decorate([
154
+ (0, common_1.Post)('login'),
155
+ (0, common_1.HttpCode)(200),
156
+ (0, swagger_1.ApiBody)({
157
+ required: true,
158
+ description: 'Credentials required for authentication',
159
+ schema: {
160
+ $ref: (0, swagger_1.getSchemaPath)(login_dto_1.LoginDto),
161
+ example: { email: 'user@example.com', password: 'StrongP@ssw0rd', moduleId: '3' },
162
+ },
163
+ }),
164
+ (0, swagger_1.ApiOperation)({
165
+ summary: 'User login',
166
+ description: 'Authenticate user and return access token'
167
+ }),
168
+ (0, swagger_1.ApiOkResponse)({
169
+ description: 'Login successful',
170
+ schema: {
171
+ $ref: (0, swagger_1.getSchemaPath)(login_response_dto_1.LoginResponseDto),
172
+ example: {
173
+ status: true,
174
+ message: 'Login successful',
175
+ data: {
176
+ user: {
177
+ id: 1,
178
+ email: 'user@example.com',
179
+ roleId: 2,
180
+ roleName: 'Admin',
181
+ moduleId: 3,
182
+ name: 'John Doe',
183
+ firstName: 'John',
184
+ lastName: 'Doe',
185
+ mobileNo: 9876543210,
186
+ userImage: 'https://cdn.example.com/avatar.png',
187
+ employeeId: 1001
188
+ }
189
+ },
190
+ access_token: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...'
191
+ }
192
+ }
193
+ }),
194
+ (0, swagger_1.ApiUnauthorizedResponse)({ description: 'Invalid credentials or IP not allowed' }),
195
+ __param(0, (0, common_1.Req)()),
196
+ __param(1, (0, common_1.Body)()),
197
+ __metadata("design:type", Function),
198
+ __metadata("design:paramtypes", [Object, login_dto_1.LoginDto]),
199
+ __metadata("design:returntype", Promise)
200
+ ], AuthController.prototype, "login", null);
201
+ exports.AuthController = AuthController = __decorate([
202
+ (0, swagger_1.ApiTags)('auth'),
203
+ (0, swagger_1.ApiBearerAuth)(),
204
+ (0, swagger_1.ApiExtraModels)(login_dto_1.LoginDto, login_response_dto_1.LoginResponseDto),
205
+ (0, common_1.Controller)('auth'),
206
+ __metadata("design:paramtypes", [auth_service_1.AuthService])
207
+ ], AuthController);