@sologence/nestjs-auth
Version:
## Overview
276 lines • 13.3 kB
JavaScript
"use strict";
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
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;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __metadata = (this && this.__metadata) || function (k, v) {
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
var AuthService_1;
Object.defineProperty(exports, "__esModule", { value: true });
exports.AuthService = void 0;
const common_1 = require("@nestjs/common");
const jwt_1 = require("@nestjs/jwt");
const typeorm_1 = require("typeorm");
const user_entity_1 = require("../entity/user.entity");
const bcrypt = require("bcrypt");
const class_transformer_1 = require("class-transformer");
let AuthService = AuthService_1 = class AuthService {
constructor(userRepository, jwtService, jwtConfig, entityManager) {
this.userRepository = userRepository;
this.jwtService = jwtService;
this.jwtConfig = jwtConfig;
this.entityManager = entityManager;
this.logger = new common_1.Logger(AuthService_1.name);
this.logger.log('AuthService initialized');
}
async isSuperAdminExists() {
try {
const superAdmin = await this.entityManager.query('SELECT * FROM "user" WHERE "role" = $1', [user_entity_1.USER_ROLE.SUPER_ADMIN]);
return superAdmin.length > 0;
}
catch (error) {
this.logger.error('Error checking if super admin exists');
this.logger.error(`Cause: ${error.message}`);
throw new common_1.InternalServerErrorException('Error checking if super admin exists');
}
}
async validateUser(email, password) {
try {
const users = await this.entityManager.query('SELECT * FROM "user" WHERE email = $1', [email]);
const user = users[0];
if (user && (await bcrypt.compare(password, user.password))) {
const token = await this.generateToken(user);
return {
isValidated: true,
userRole: user.role,
token,
user: (0, class_transformer_1.instanceToPlain)(user),
};
}
return {
isValidated: false,
};
}
catch (error) {
this.logger.error('Error validating user credentials');
this.logger.error(`Cause: ${error.message}`);
throw new common_1.InternalServerErrorException('Error validating user');
}
}
async generateToken(user) {
const payload = {
email: user.email,
role: user.role,
};
return this.jwtService.signAsync(payload);
}
async validateToken(token) {
try {
const payload = await this.jwtService.verifyAsync(token, {
secret: this.jwtConfig.secret,
});
const users = await this.entityManager.query('SELECT * FROM "user" WHERE email = $1', [payload.email]);
const user = users[0];
if (!user) {
throw new common_1.UnauthorizedException('User not found');
}
return user;
}
catch (error) {
this.logger.error('Error validating JWT token');
this.logger.error(`Cause: ${error.message}`);
throw new common_1.UnauthorizedException('Invalid token');
}
}
async validateUserFromJWT(token) {
try {
const user = await this.validateToken(token);
if (!user.is_active) {
return {
isValidated: false,
};
}
return {
isValidated: true,
userRole: user.role,
user: (0, class_transformer_1.instanceToPlain)(user),
};
}
catch (error) {
this.logger.error('Error validating user from JWT token');
this.logger.error(`Cause: ${error.message}`);
return {
isValidated: false,
};
}
}
async registerUser(email, password, role = user_entity_1.USER_ROLE.TECH_ROLE, firstName, lastName, mobile) {
try {
this.logger.log(`Attempting to register user with email: ${email} and role: ${role}`);
const existingUser = await this.entityManager.query('SELECT * FROM "user" WHERE email = $1', [email]);
if (existingUser.length > 0) {
this.logger.warn(`Registration failed: User with email ${email} already exists`);
throw new common_1.ConflictException('User with this email already exists.');
}
if (role === user_entity_1.USER_ROLE.SUPER_ADMIN) {
this.logger.log('Redirecting to super admin registration');
return this.registerSuperAdmin(email, password, firstName, lastName, mobile);
}
const hashedPassword = await bcrypt.hash(password, 10);
const newUser = this.userRepository.create({
email,
password: hashedPassword,
first_name: firstName,
last_name: lastName,
created_on: new Date(),
updated_on: new Date(),
role: role,
mobile,
is_active: false,
});
this.logger.log(`Successfully registered user with email: ${email}`);
return this.userRepository.save(newUser);
}
catch (error) {
this.logger.error('Error registering new user');
this.logger.error(`Cause: ${error.message}`);
throw new common_1.InternalServerErrorException('Error registering user');
}
}
async registerSuperAdmin(email, password, firstName, lastName, mobile) {
try {
this.logger.log(`Attempting to register super admin with email: ${email}`);
const superAdminExists = await this.isSuperAdminExists();
if (superAdminExists) {
this.logger.warn('Super admin registration failed: Super admin already exists');
throw new common_1.ConflictException('Super Admin already exists. Cannot register another Super Admin.');
}
const existingUser = await this.entityManager.query('SELECT * FROM "user" WHERE email = $1', [email]);
if (existingUser.length > 0) {
this.logger.warn(`Super admin registration failed: Email ${email} already exists`);
throw new common_1.ConflictException('User with this email already exists.');
}
const hashedPassword = await bcrypt.hash(password, 10);
const newUser = this.userRepository.create({
email,
password: hashedPassword,
first_name: firstName,
last_name: lastName,
created_on: new Date(),
updated_on: new Date(),
role: user_entity_1.USER_ROLE.SUPER_ADMIN,
mobile,
is_active: true,
});
this.logger.log(`Successfully registered super admin with email: ${email}`);
return this.userRepository.save(newUser);
}
catch (error) {
this.logger.error('Error registering super admin');
this.logger.error(`Cause: ${error.message}`);
throw new common_1.InternalServerErrorException('Error registering super admin');
}
}
async activateUser(userEmail, adminEmail, adminPassword) {
try {
const validation = await this.validateUser(adminEmail, adminPassword);
if (!validation.isValidated) {
throw new common_1.UnauthorizedException('Invalid admin credentials');
}
if (![user_entity_1.USER_ROLE.ADMIN, user_entity_1.USER_ROLE.SUPER_ADMIN].includes(validation.userRole)) {
throw new common_1.UnauthorizedException('Unauthorized: Only administrators can activate users');
}
const users = await this.entityManager.query('SELECT * FROM "user" WHERE email = $1', [userEmail]);
const user = users[0];
if (!user) {
throw new common_1.UnauthorizedException('User not found');
}
await this.entityManager.query('UPDATE "user" SET is_active = true, updated_on = $1 WHERE email = $2', [new Date(), userEmail]);
return Object.assign(Object.assign({}, user), { is_active: true, updated_on: new Date() });
}
catch (error) {
this.logger.error('Error activating user');
this.logger.error(`Cause: ${error.message}`);
throw new common_1.InternalServerErrorException('Error activating user');
}
}
async activateUserWithToken(adminToken, userEmail) {
try {
const admin = await this.validateToken(adminToken);
if (admin.role !== user_entity_1.USER_ROLE.SUPER_ADMIN) {
throw new common_1.UnauthorizedException('Only super admins can activate users');
}
const users = await this.entityManager.query('SELECT * FROM "user" WHERE email = $1', [userEmail]);
const user = users[0];
if (!user) {
throw new common_1.NotFoundException('User not found');
}
await this.entityManager.query('UPDATE "user" SET is_active = true, updated_on = $1 WHERE email = $2', [new Date(), userEmail]);
this.logger.log(`User ${userEmail} activated by super admin: ${admin.email}`);
return Object.assign(Object.assign({}, user), { is_active: true, updated_on: new Date() });
}
catch (error) {
this.logger.error('Error activating user with token');
this.logger.error(`Cause: ${error.message}`);
throw new common_1.InternalServerErrorException('Error activating user');
}
}
async changePassword(token, oldPassword, newPassword) {
try {
const user = await this.validateToken(token);
const users = await this.entityManager.query('SELECT * FROM "user" WHERE email = $1', [user.email]);
const currentUser = users[0];
if (!currentUser || !(await bcrypt.compare(oldPassword, currentUser.password))) {
throw new common_1.UnauthorizedException('Current password is incorrect');
}
const hashedNewPassword = await bcrypt.hash(newPassword, 10);
await this.entityManager.query('UPDATE "user" SET password = $1, updated_on = $2 WHERE email = $3', [hashedNewPassword, new Date(), user.email]);
this.logger.log(`Password successfully changed for user: ${user.email}`);
return true;
}
catch (error) {
this.logger.error('Error changing password');
this.logger.error(`Cause: ${error.message}`);
throw new common_1.InternalServerErrorException('Error changing password');
}
}
async resetUserPassword(adminToken, userEmail) {
try {
const admin = await this.validateToken(adminToken);
if (admin.role !== user_entity_1.USER_ROLE.SUPER_ADMIN) {
throw new common_1.UnauthorizedException('Only super admins can reset passwords');
}
const users = await this.entityManager.query('SELECT * FROM "user" WHERE email = $1', [userEmail]);
if (users.length === 0) {
throw new common_1.NotFoundException('User not found');
}
const newPassword = Math.random().toString(36).slice(-8);
const hashedPassword = await bcrypt.hash(newPassword, 10);
await this.entityManager.query('UPDATE "user" SET password = $1, updated_on = $2 WHERE email = $3', [hashedPassword, new Date(), userEmail]);
this.logger.log(`Password reset successful for user: ${userEmail}`);
return {
success: true,
newPassword: newPassword,
message: 'Password reset successful'
};
}
catch (error) {
this.logger.error('Error resetting password');
this.logger.error(`Cause: ${error.message}`);
return {
success: false,
message: error.message || 'Error resetting password'
};
}
}
};
exports.AuthService = AuthService;
exports.AuthService = AuthService = AuthService_1 = __decorate([
(0, common_1.Injectable)(),
__metadata("design:paramtypes", [typeorm_1.Repository,
jwt_1.JwtService, Object, typeorm_1.EntityManager])
], AuthService);
//# sourceMappingURL=auth.service.js.map