UNPKG

@sologence/nestjs-auth

Version:

## Overview

276 lines 13.3 kB
"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