Spaces:
Running
Running
Bibhu Mishra
Add GitHub Actions CI/CD, HF Space deployment, market hours guard, and static serving
abc493d | import { BadRequestException, Injectable, UnauthorizedException } from '@nestjs/common'; | |
| import { JwtService } from '@nestjs/jwt'; | |
| import { InjectRepository } from '@nestjs/typeorm'; | |
| import * as bcrypt from 'bcrypt'; | |
| import { Repository } from 'typeorm'; | |
| import { User } from '../common/entities/user.entity'; | |
| () | |
| export class AuthService { | |
| constructor( | |
| (User) private users: Repository<User>, | |
| private jwt: JwtService, | |
| ) {} | |
| async register(email: string, name: string, password: string) { | |
| const exists = await this.users.findOne({ where: { email } }); | |
| if (exists) throw new BadRequestException('Email already registered'); | |
| const hash = await bcrypt.hash(password, 10); | |
| // First user gets admin role | |
| const count = await this.users.count(); | |
| const role = count === 0 ? 'admin' : 'pending'; | |
| const user = this.users.create({ email, name, password_hash: hash, role }); | |
| await this.users.save(user); | |
| return { message: role === 'admin' ? 'Admin account created' : 'Registration pending approval', role }; | |
| } | |
| async login(email: string, password: string) { | |
| const user = await this.users.findOne({ where: { email } }); | |
| if (!user) throw new UnauthorizedException('Invalid credentials'); | |
| const valid = await bcrypt.compare(password, user.password_hash); | |
| if (!valid) throw new UnauthorizedException('Invalid credentials'); | |
| return { access_token: this._token(user), user: this._safe(user) }; | |
| } | |
| async me(userId: number) { | |
| const user = await this.users.findOne({ where: { id: userId } }); | |
| if (!user) throw new UnauthorizedException(); | |
| return this._safe(user); | |
| } | |
| async updateProfile(userId: number, name: string) { | |
| await this.users.update(userId, { name }); | |
| return this.me(userId); | |
| } | |
| async changePassword(userId: number, currentPassword: string, newPassword: string) { | |
| const user = await this.users.findOne({ where: { id: userId } }); | |
| if (!user) throw new UnauthorizedException(); | |
| const valid = await bcrypt.compare(currentPassword, user.password_hash); | |
| if (!valid) throw new BadRequestException('Current password is incorrect'); | |
| if (newPassword.length < 8) throw new BadRequestException('New password must be at least 8 characters'); | |
| const hash = await bcrypt.hash(newPassword, 10); | |
| await this.users.update(userId, { password_hash: hash }); | |
| return { message: 'Password updated successfully' }; | |
| } | |
| private _token(user: User) { | |
| return this.jwt.sign({ sub: user.id, email: user.email, role: user.role }); | |
| } | |
| private _safe(user: User) { | |
| const { password_hash, ...rest } = user as User & { password_hash?: string }; | |
| return rest; | |
| } | |
| } | |