fix(auth): add refresh & logout endpoints and ensure UsersService.findById handles fallback admin
All checks were successful
Deploy Canina / deploy (push) Successful in 1m53s
All checks were successful
Deploy Canina / deploy (push) Successful in 1m53s
This commit is contained in:
parent
28fc660f69
commit
1a21c4c642
@ -1,15 +1,17 @@
|
||||
import { Controller, Post, Body, HttpCode, HttpStatus } from '@nestjs/common';
|
||||
import { Controller, Post, Body, HttpCode, HttpStatus, UseGuards, Req } from '@nestjs/common';
|
||||
import { AuthService } from './auth.service';
|
||||
import { SendOtpDto } from './dto/send-otp.dto';
|
||||
import { VerifyOtpDto } from './dto/verify-otp.dto';
|
||||
import { RegisterDto } from './dto/register.dto';
|
||||
import { LoginDto } from './dto/login.dto';
|
||||
import { JwtAuthGuard } from './jwt-auth.guard';
|
||||
import {
|
||||
ApiTags,
|
||||
ApiOperation,
|
||||
ApiResponse,
|
||||
ApiOkResponse,
|
||||
ApiBadRequestResponse,
|
||||
ApiBearerAuth,
|
||||
} from '@nestjs/swagger';
|
||||
|
||||
import { AdminLoginDto } from './dto/admin-login.dto';
|
||||
@ -43,59 +45,17 @@ export class AuthController {
|
||||
},
|
||||
},
|
||||
})
|
||||
@ApiBadRequestResponse({
|
||||
description: 'فرمت شماره تلفن همراه نامعتبر است',
|
||||
schema: {
|
||||
example: {
|
||||
success: false,
|
||||
message: 'شماره موبایل نامعتبر است',
|
||||
code: 'BAD_REQUEST',
|
||||
details: {
|
||||
message: ['شماره موبایل نامعتبر است'],
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
@ApiBadRequestResponse({ description: 'شماره تلفن همراه نامعتبر است' })
|
||||
sendOtp(@Body() sendOtpDto: SendOtpDto) {
|
||||
return this.authService.sendOtp(sendOtpDto);
|
||||
}
|
||||
|
||||
@Post('verify-otp')
|
||||
@HttpCode(HttpStatus.OK)
|
||||
@ApiOperation({ summary: 'تایید کد پیامکی و ورود/ثبتنام کاربر' })
|
||||
@ApiOkResponse({
|
||||
description: 'ورود موفق به همراه توکن دسترسی JWT و اطلاعات کاربر',
|
||||
schema: {
|
||||
example: {
|
||||
success: true,
|
||||
data: {
|
||||
user: {
|
||||
id: 'd8c4e428-cd2f-4c55-bfa3-dfa312bb6480',
|
||||
firstName: 'کاربر',
|
||||
lastName: 'جدید',
|
||||
email: '09123456789@temp.local',
|
||||
mobile: '09123456789',
|
||||
role: 'User_PetOwner',
|
||||
walletBalance: '0.00',
|
||||
charityDonationTotal: '0.00',
|
||||
createdAt: '2026-05-26T15:20:00.000Z',
|
||||
updatedAt: '2026-05-26T15:20:00.000Z',
|
||||
},
|
||||
accessToken: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...',
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
@ApiOperation({ summary: 'تایید کد پیامکی و ورود به سیستم' })
|
||||
@ApiOkResponse({ description: 'کد تایید شد و ورود با موفقیت انجام گردید' })
|
||||
@ApiBadRequestResponse({
|
||||
description: 'کد تایید اشتباه یا منقضی شده است',
|
||||
schema: {
|
||||
example: {
|
||||
success: false,
|
||||
message: 'کد تایید اشتباه است',
|
||||
code: 'OTP_INVALID',
|
||||
details: {},
|
||||
},
|
||||
},
|
||||
description: 'کد تایید اشتباه است یا منقضی شده است',
|
||||
})
|
||||
verifyOtp(@Body() verifyOtpDto: VerifyOtpDto) {
|
||||
return this.authService.verifyOtp(verifyOtpDto);
|
||||
@ -129,4 +89,22 @@ export class AuthController {
|
||||
adminLogin(@Body() body: AdminLoginDto) {
|
||||
return this.authService.adminLogin(body);
|
||||
}
|
||||
|
||||
@ApiBearerAuth()
|
||||
@UseGuards(JwtAuthGuard)
|
||||
@Post('refresh')
|
||||
@HttpCode(HttpStatus.OK)
|
||||
@ApiOperation({ summary: 'تازهسازی توکن دسترسی (Refresh Token)' })
|
||||
@ApiOkResponse({ description: 'توکن جدید با موفقیت صادر شد' })
|
||||
refresh(@Req() req: { user: { id: string; email?: string; role?: string; mobile?: string } }) {
|
||||
return this.authService.refresh(req.user);
|
||||
}
|
||||
|
||||
@Post('logout')
|
||||
@HttpCode(HttpStatus.OK)
|
||||
@ApiOperation({ summary: 'خروج از حساب کاربری' })
|
||||
@ApiOkResponse({ description: 'با موفقیت خارج شدید' })
|
||||
logout() {
|
||||
return { success: true, message: 'با موفقیت خارج شدید' };
|
||||
}
|
||||
}
|
||||
|
||||
@ -245,4 +245,21 @@ export class AuthService {
|
||||
error: 'INVALID_ADMIN_CREDENTIALS',
|
||||
});
|
||||
}
|
||||
|
||||
async refresh(user: { id: string; email?: string; role?: string; mobile?: string }) {
|
||||
const payload = {
|
||||
sub: user.id,
|
||||
email: user.email,
|
||||
role: user.role,
|
||||
phoneNumber: user.mobile,
|
||||
};
|
||||
return {
|
||||
success: true,
|
||||
data: {
|
||||
user,
|
||||
accessToken: this.jwtService.sign(payload),
|
||||
},
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -18,6 +18,57 @@ export class UsersService {
|
||||
constructor(private prisma: PrismaService) {}
|
||||
|
||||
async findById(id: string) {
|
||||
if (id === '12345678-1234-1234-1234-123456789012') {
|
||||
const dbUser = await this.prisma.user.findUnique({
|
||||
where: { id },
|
||||
include: {
|
||||
pets: {
|
||||
include: {
|
||||
medicalConditions: true,
|
||||
reminders: {
|
||||
include: {
|
||||
completions: true,
|
||||
},
|
||||
},
|
||||
healthLogs: true,
|
||||
},
|
||||
},
|
||||
orders: {
|
||||
orderBy: { createdAt: 'desc' },
|
||||
include: {
|
||||
orderItems: {
|
||||
include: { product: true },
|
||||
},
|
||||
},
|
||||
},
|
||||
addresses: true,
|
||||
walletTransactions: {
|
||||
orderBy: { createdAt: 'desc' },
|
||||
take: 50,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
if (dbUser) return dbUser;
|
||||
|
||||
return {
|
||||
id: '12345678-1234-1234-1234-123456789012',
|
||||
firstName: 'مدیر',
|
||||
lastName: 'سیستم',
|
||||
email: process.env.ADMIN_EMAIL || 'admin@canina-iran.com',
|
||||
mobile: '09120000000',
|
||||
role: 'Admin',
|
||||
walletBalance: new Prisma.Decimal(0),
|
||||
charityDonationTotal: new Prisma.Decimal(0),
|
||||
pets: [],
|
||||
orders: [],
|
||||
addresses: [],
|
||||
walletTransactions: [],
|
||||
createdAt: new Date(),
|
||||
updatedAt: new Date(),
|
||||
};
|
||||
}
|
||||
|
||||
return this.prisma.user.findUnique({
|
||||
where: { id },
|
||||
include: {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user