import { Injectable } from '@nestjs/common'; import { JwtService } from '@nestjs/jwt'; import { TenantDatabaseService } from '../tenant/tenant-database.service'; import * as bcrypt from 'bcrypt'; @Injectable() export class AuthService { constructor( private tenantDbService: TenantDatabaseService, private jwtService: JwtService, ) {} async validateUser( tenantId: string, email: string, password: string, ): Promise { const tenantDb = await this.tenantDbService.getTenantKnex(tenantId); const user = await tenantDb('users') .where({ email }) .first(); if (!user) { return null; } if (await bcrypt.compare(password, user.password)) { // Load user roles and permissions const userRoles = await tenantDb('user_roles') .where({ userId: user.id }) .join('roles', 'user_roles.roleId', 'roles.id') .select('roles.*'); const { password: _, ...result } = user; return { ...result, tenantId, userRoles, }; } return null; } async login(user: any) { const payload = { sub: user.id, email: user.email, }; return { access_token: this.jwtService.sign(payload), user: { id: user.id, email: user.email, firstName: user.firstName, lastName: user.lastName, }, }; } async register( tenantId: string, email: string, password: string, firstName?: string, lastName?: string, ) { const tenantDb = await this.tenantDbService.getTenantKnex(tenantId); const hashedPassword = await bcrypt.hash(password, 10); const [userId] = await tenantDb('users').insert({ email, password: hashedPassword, firstName, lastName, isActive: true, created_at: new Date(), updated_at: new Date(), }); const user = await tenantDb('users') .where({ id: userId }) .first(); const { password: _, ...result } = user; return result; } }