"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); 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 __importStar = (this && this.__importStar) || (function () { var ownKeys = function(o) { ownKeys = Object.getOwnPropertyNames || function (o) { var ar = []; for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; return ar; }; return ownKeys(o); }; return function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); __setModuleDefault(result, mod); return result; }; })(); var __metadata = (this && this.__metadata) || function (k, v) { if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); }; Object.defineProperty(exports, "__esModule", { value: true }); exports.AuthService = void 0; const common_1 = require("@nestjs/common"); const config_1 = require("@nestjs/config"); const jwt_1 = require("@nestjs/jwt"); const bcrypt = __importStar(require("bcryptjs")); const prisma_service_1 = require("../prisma/prisma.service"); const phone_1 = require("../common/utils/phone"); let AuthService = class AuthService { prisma; jwt; config; constructor(prisma, jwt, config) { this.prisma = prisma; this.jwt = jwt; this.config = config; } async requestOtp(dto) { const phone = (0, phone_1.normalizePhone)((0, phone_1.toEnglishDigits)(dto.phone)); if (!(0, phone_1.isValidPhone)(phone)) { throw new common_1.BadRequestException('شماره موبایل نامعتبر است'); } const existing = await this.prisma.customer.findUnique({ where: { phone } }); const isRegister = Boolean(dto.isRegister); if (isRegister) { if (!dto.firstName?.trim() || !dto.lastName?.trim()) { throw new common_1.BadRequestException('نام و نام خانوادگی الزامی است'); } if (existing) { throw new common_1.BadRequestException('این شماره قبلاً ثبت شده است'); } } else if (!existing) { throw new common_1.BadRequestException('کاربری با این شماره یافت نشد'); } const code = this.config.get('MOCK_OTP_CODE', '123456'); const ttl = Number(this.config.get('OTP_TTL_MINUTES', 5)); const expiresAt = new Date(Date.now() + ttl * 60_000); await this.prisma.otpChallenge.deleteMany({ where: { phone } }); await this.prisma.otpChallenge.create({ data: { phone, code, firstName: dto.firstName?.trim(), lastName: dto.lastName?.trim(), isRegister, expiresAt, }, }); return { success: true, message: 'کد تأیید ارسال شد', expiresAt, debugCode: code, }; } async verifyOtp(dto) { const phone = (0, phone_1.normalizePhone)((0, phone_1.toEnglishDigits)(dto.phone)); const code = (0, phone_1.toEnglishDigits)(dto.code).trim(); const challenge = await this.prisma.otpChallenge.findFirst({ where: { phone }, orderBy: { createdAt: 'desc' }, }); if (!challenge || challenge.expiresAt < new Date()) { throw new common_1.UnauthorizedException('کد منقضی شده است'); } if (challenge.code !== code) { throw new common_1.UnauthorizedException('کد تأیید نادرست است'); } let user = await this.prisma.customer.findUnique({ where: { phone } }); if (challenge.isRegister) { if (user) { throw new common_1.BadRequestException('این شماره قبلاً ثبت شده است'); } user = await this.prisma.customer.create({ data: { phone, firstName: challenge.firstName ?? 'کاربر', lastName: challenge.lastName ?? 'جدید', }, }); } else if (!user) { throw new common_1.UnauthorizedException('کاربر یافت نشد'); } await this.prisma.otpChallenge.deleteMany({ where: { phone } }); const accessToken = await this.signCustomerToken(user.id, user.phone); return { accessToken, user: this.mapCustomer(user), }; } async adminLogin(dto) { const phone = (0, phone_1.normalizePhone)((0, phone_1.toEnglishDigits)(dto.phone)); const admin = await this.prisma.adminUser.findUnique({ where: { phone } }); if (!admin || !admin.isActive) { throw new common_1.UnauthorizedException('نام کاربری یا رمز عبور نادرست است'); } const ok = await bcrypt.compare(dto.password, admin.passwordHash); if (!ok) { throw new common_1.UnauthorizedException('نام کاربری یا رمز عبور نادرست است'); } await this.prisma.adminUser.update({ where: { id: admin.id }, data: { lastLoginAt: new Date() }, }); const accessToken = await this.jwt.signAsync({ sub: admin.id, type: 'admin', role: admin.role, phone: admin.phone, }); return { accessToken, user: { id: admin.id, fullName: admin.fullName, phone: admin.phone, email: admin.email, role: admin.role, }, }; } async me(userId, type) { if (type === 'admin') { const admin = await this.prisma.adminUser.findUnique({ where: { id: userId } }); if (!admin) throw new common_1.UnauthorizedException(); return { id: admin.id, fullName: admin.fullName, phone: admin.phone, email: admin.email, role: admin.role, }; } const user = await this.prisma.customer.findUnique({ where: { id: userId } }); if (!user) throw new common_1.UnauthorizedException(); return this.mapCustomer(user); } async updateProfile(userId, dto) { const user = await this.prisma.customer.update({ where: { id: userId }, data: { firstName: dto.firstName?.trim(), lastName: dto.lastName?.trim(), nationalId: dto.nationalId?.trim() || null, }, }); return this.mapCustomer(user); } async signCustomerToken(id, phone) { return this.jwt.signAsync({ sub: id, type: 'customer', phone, }); } mapCustomer(user) { return { id: user.id, firstName: user.firstName, lastName: user.lastName, phone: user.phone, nationalId: user.nationalId ?? undefined, createdAt: user.createdAt.toISOString(), }; } }; exports.AuthService = AuthService; exports.AuthService = AuthService = __decorate([ (0, common_1.Injectable)(), __metadata("design:paramtypes", [prisma_service_1.PrismaService, jwt_1.JwtService, config_1.ConfigService]) ], AuthService); //# sourceMappingURL=auth.service.js.map