Files
api/src/auth/auth.service.ts
T
MahdiandCursor a6b3457779 Add production-ready SuperAdmin API features for tenants, SMS, servers, and plugins.
Includes mobile auth, get_user/get_version, SMS wallet parity endpoints, appearance backfill, and related Prisma migrations.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-30 18:19:53 +03:30

79 lines
2.0 KiB
TypeScript

import { Injectable, UnauthorizedException } from '@nestjs/common';
import { JwtService } from '@nestjs/jwt';
import * as bcrypt from 'bcrypt';
import { PrismaService } from '../prisma/prisma.service';
import { displayName, normalizeMobile } from '../common/mobile.util';
import { LoginDto } from './dto/login.dto';
@Injectable()
export class AuthService {
constructor(
private readonly prisma: PrismaService,
private readonly jwt: JwtService,
) {}
async login(dto: LoginDto) {
const mobile = normalizeMobile(dto.mobile);
if (!mobile) {
throw new UnauthorizedException('موبایل یا رمز عبور نادرست است');
}
const user = await this.prisma.user.findUnique({
where: { mobile },
});
if (!user || !user.isActive) {
throw new UnauthorizedException('موبایل یا رمز عبور نادرست است');
}
const ok = await bcrypt.compare(dto.password, user.passwordHash);
if (!ok) {
throw new UnauthorizedException('موبایل یا رمز عبور نادرست است');
}
const name = displayName(user.firstName, user.lastName);
const payload = {
sub: user.id,
mobile: user.mobile,
role: user.role,
};
return {
accessToken: await this.jwt.signAsync(payload),
user: {
id: user.id,
mobile: user.mobile,
firstName: user.firstName,
lastName: user.lastName,
name,
role: user.role,
},
};
}
async me(userId: string) {
const user = await this.prisma.user.findUnique({
where: { id: userId },
select: {
id: true,
mobile: true,
firstName: true,
lastName: true,
email: true,
role: true,
isActive: true,
createdAt: true,
},
});
if (!user || !user.isActive) {
throw new UnauthorizedException();
}
return {
...user,
name: displayName(user.firstName, user.lastName),
};
}
}