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.
- package/dist/auth.controller.js +207 -206
- package/dist/auth.service.js +361 -360
- package/dist/index.d.ts +31 -31
- package/dist/index.js +54 -54
- package/dist/interfaces/auth-core-options.interface.d.ts +38 -38
- package/package.json +1 -1
package/dist/auth.controller.js
CHANGED
|
@@ -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
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
const
|
|
65
|
-
const
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
*
|
|
117
|
-
*
|
|
118
|
-
*
|
|
119
|
-
*
|
|
120
|
-
*
|
|
121
|
-
*
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
(0, common_1.
|
|
155
|
-
(0,
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
__param(
|
|
196
|
-
|
|
197
|
-
__metadata("design:
|
|
198
|
-
__metadata("design:
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
(0, swagger_1.
|
|
203
|
-
(0, swagger_1.
|
|
204
|
-
(0,
|
|
205
|
-
|
|
206
|
-
|
|
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);
|