diff --git a/.vscode/settings.json b/.vscode/settings.json index 158d031..b336fb1 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -7,7 +7,7 @@ "source.fixAll.eslint": "explicit" }, "[typescript]": { - "editor.defaultFormatter": "esbenp.prettier-vscode" + "editor.defaultFormatter": "vscode.typescript-language-features" }, "[json]": { "editor.defaultFormatter": "vscode.json-language-features" diff --git a/src/modules/auth/controllers/auth.controller.ts b/src/modules/auth/controllers/auth.controller.ts index 5a5ef99..6a4b7b9 100644 --- a/src/modules/auth/controllers/auth.controller.ts +++ b/src/modules/auth/controllers/auth.controller.ts @@ -1,16 +1,18 @@ -import { Controller, Post, Body } from '@nestjs/common'; +import { Controller, Post, Body, UseGuards } from '@nestjs/common'; import { AuthService } from '../services/auth.service'; import { RequestOtpDto } from '../dto/request-otp.dto'; +import { DirectLoginDto } from '../dto/direct-login.dto'; import { ApiTags, ApiOperation, ApiBody } from '@nestjs/swagger'; import { VerifyOtpDto } from '../dto/verify-otp.dto'; import { Throttle } from '@nestjs/throttler'; import { RefreshTokenRateLimit } from 'src/common/decorators/rate-limit.decorator'; import { RefreshTokenDto } from '../dto/refresh-token.dto'; +import { SuperAdminAuthGuard } from '../guards/superAdminAuth.guard'; @ApiTags('auth') @Controller() export class AuthController { - constructor(private readonly authService: AuthService) {} + constructor(private readonly authService: AuthService) { } @Throttle({ default: { limit: 3, ttl: 180_000 } }) @Post('public/auth/otp/request') @@ -55,4 +57,15 @@ export class AuthController { refreshTokenAdmin(@Body() refreshTokenDto: RefreshTokenDto) { return this.authService.refreshToken(refreshTokenDto.refreshToken); } + + //super admin routes + + @UseGuards(SuperAdminAuthGuard) + @Post('super-admin/auth/direct-login') + @ApiOperation({ summary: 'Direct login for DSC - returns login credentials' }) + @ApiBody({ type: DirectLoginDto, description: 'Phone number and restaurant slug for direct login' }) + directloginForDsc(@Body() dto: DirectLoginDto) { + return this.authService.loginAdminForDsc(dto.phone, dto.slug); + } + } diff --git a/src/modules/auth/dto/direct-login.dto.ts b/src/modules/auth/dto/direct-login.dto.ts new file mode 100644 index 0000000..05833cd --- /dev/null +++ b/src/modules/auth/dto/direct-login.dto.ts @@ -0,0 +1,15 @@ +import { IsNotEmpty, IsString, IsMobilePhone } from 'class-validator'; +import { ApiProperty } from '@nestjs/swagger'; + +export class DirectLoginDto { + @IsNotEmpty() + @IsString() + @ApiProperty({ example: '09362532122', description: 'Mobile number' }) + @IsMobilePhone('fa-IR') + phone: string; + + @IsNotEmpty() + @IsString() + @ApiProperty({ example: 'zhivan', description: 'Restaurant slug' }) + slug: string; +} diff --git a/src/modules/auth/services/auth.service.ts b/src/modules/auth/services/auth.service.ts index 899786a..b6844eb 100644 --- a/src/modules/auth/services/auth.service.ts +++ b/src/modules/auth/services/auth.service.ts @@ -101,6 +101,30 @@ export class AuthService { return { tokens, admin: adminResponse }; } + /** + * + to use for login directly from DSC + */ + async loginAdminForDsc(phone: string, slug: string) { + const normalizedPhone = normalizePhone(phone); + const admin = await this.adminRepository.findByPhoneAndRestaurantSlug(normalizedPhone, slug); + + if (!admin) { + throw new BadRequestException(AuthMessage.ADMIN_NOT_FOUND); + } + + const rest = await this.restRepository.findOne({ slug }); + + if (!rest) { + throw new BadRequestException(RestMessage.NOT_FOUND); + } + + const tokens = await this.tokensService.generateAccessAndRefreshToken(admin.id, rest.id, true, slug); + + const adminResponse = await AdminLoginTransformer.transform(admin, rest); + + return { tokens, admin: adminResponse }; + } private generateOtpCode(): string { const code = randomInt(10000, 100000);