fix auth login
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import { ConflictException, Injectable, NotFoundException } from '@nestjs/common';
|
||||
import { BadRequestException, ConflictException, Injectable, NotFoundException } from '@nestjs/common';
|
||||
import { InjectRepository } from '@mikro-orm/nestjs';
|
||||
import { EntityRepository } from '@mikro-orm/core';
|
||||
import { Admin } from '../entities/admin.entity';
|
||||
@@ -20,7 +20,7 @@ export class AdminService {
|
||||
private readonly adminRoleRepository: EntityRepository<AdminRole>,
|
||||
private readonly em: EntityManager,
|
||||
private readonly cacheService: CacheService,
|
||||
) {}
|
||||
) { }
|
||||
|
||||
async findByPhone(phone: string): Promise<Admin | null> {
|
||||
const normalizedPhone = normalizePhone(phone);
|
||||
@@ -194,4 +194,39 @@ export class AdminService {
|
||||
}
|
||||
return this.em.removeAndFlush(adminRole);
|
||||
}
|
||||
|
||||
async findByPhoneAndShopSlug(phone: string, shopSlug: string): Promise<Admin> {
|
||||
const normalizedPhone = normalizePhone(phone);
|
||||
console.log(phone, shopSlug);
|
||||
|
||||
const admin = await this.adminRepository.findOne(
|
||||
{
|
||||
phone: normalizedPhone,
|
||||
roles: {
|
||||
shop: {
|
||||
slug: shopSlug,
|
||||
},
|
||||
},
|
||||
},
|
||||
{ populate: ['roles', 'roles.role', 'roles.shop'] },
|
||||
);
|
||||
|
||||
console.log(admin);
|
||||
|
||||
if (!admin) {
|
||||
throw new BadRequestException('Admin not found');
|
||||
}
|
||||
|
||||
// Ensure all roles are populated
|
||||
// await adminRole.admin.roles.loadItems();
|
||||
// for (const role of adminRole.admin.roles.getItems()) {
|
||||
// if (role.role && role.role.permissions && !role.role.permissions.isInitialized()) {
|
||||
// await role.role.permissions.loadItems();
|
||||
// }
|
||||
// }
|
||||
|
||||
return admin;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -1,52 +1,15 @@
|
||||
import { EntityManager, EntityRepository } from '@mikro-orm/postgresql';
|
||||
import { Admin } from '../entities/admin.entity';
|
||||
import { AdminRole } from '../entities/adminRole.entity';
|
||||
import { ShopRepository } from '../../shops/repositories/rest.repository';
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { normalizePhone } from '../../utils/phone.util';
|
||||
|
||||
@Injectable()
|
||||
export class AdminRepository extends EntityRepository<Admin> {
|
||||
constructor(
|
||||
readonly em: EntityManager,
|
||||
private readonly shopRepository: ShopRepository,
|
||||
) {
|
||||
super(em, Admin);
|
||||
}
|
||||
|
||||
async findByPhoneAndRestaurantSlug(phone: string, slug: string): Promise<Admin | null> {
|
||||
console.log('phone', phone);
|
||||
const normalizedPhone = normalizePhone(phone);
|
||||
// First, find the shop by slug using the same repository as auth service
|
||||
const shop = await this.shopRepository.findOne({ slug });
|
||||
if (!shop) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Find AdminRole that matches the admin phone and shop
|
||||
const adminRole = await this.em.findOne(
|
||||
AdminRole,
|
||||
{
|
||||
admin: { phone: normalizedPhone },
|
||||
shop: { id: shop.id },
|
||||
},
|
||||
{ populate: ['admin', 'admin.roles', 'role', 'role.permissions', 'shop'] },
|
||||
);
|
||||
|
||||
if (!adminRole || !adminRole.admin) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Ensure all roles are populated
|
||||
await adminRole.admin.roles.loadItems();
|
||||
for (const role of adminRole.admin.roles.getItems()) {
|
||||
if (role.role && role.role.permissions && !role.role.permissions.isInitialized()) {
|
||||
await role.role.permissions.loadItems();
|
||||
}
|
||||
}
|
||||
|
||||
return adminRole.admin;
|
||||
}
|
||||
async findAdminsWithPermission(restaurantId: string, permission: string): Promise<Admin[]> {
|
||||
const admins = await this.em.find(
|
||||
Admin,
|
||||
|
||||
@@ -10,6 +10,6 @@ export class RequestOtpDto {
|
||||
|
||||
@IsNotEmpty()
|
||||
@IsString()
|
||||
@ApiProperty({ example: 'zhivan', description: 'shop slug' })
|
||||
@ApiProperty({ example: 'boote', description: 'shop slug' })
|
||||
slug: string;
|
||||
}
|
||||
|
||||
@@ -16,6 +16,6 @@ export class VerifyOtpDto {
|
||||
|
||||
@IsNotEmpty()
|
||||
@IsString()
|
||||
@ApiProperty({ example: 'zhivan', description: 'shop slug' })
|
||||
@ApiProperty({ example: 'boote', description: 'shop slug' })
|
||||
slug: string;
|
||||
}
|
||||
|
||||
@@ -12,6 +12,7 @@ import { AdminLoginTransformer } from '../transformers/admin-login.transformer';
|
||||
import { UserLoginTransformer } from '../transformers/user-login.transformer';
|
||||
import { ConfigService } from '@nestjs/config';
|
||||
import { normalizePhone } from 'src/modules/utils/phone.util';
|
||||
import { AdminService } from 'src/modules/admin/providers/admin.service';
|
||||
|
||||
@Injectable()
|
||||
export class AuthService {
|
||||
@@ -24,6 +25,7 @@ export class AuthService {
|
||||
private readonly tokensService: TokensService,
|
||||
private readonly shopRepository: ShopRepository,
|
||||
private readonly adminRepository: AdminRepository,
|
||||
private readonly adminService: AdminService,
|
||||
private readonly configService: ConfigService,
|
||||
) {
|
||||
this.OTP_EXPIRATION_TIME = this.configService.get<number>('OTP_EXPIRATION_TIME') ?? 240;
|
||||
@@ -44,9 +46,9 @@ export class AuthService {
|
||||
const key = isAdmin ? this.adminOtpKey(slug, normalizedPhone) : this.userOtpKey(slug, normalizedPhone);
|
||||
await this.cacheService.set(key, code, this.OTP_EXPIRATION_TIME);
|
||||
|
||||
await this.smsService.sendotp(normalizedPhone, code);
|
||||
// await this.smsService.sendotp(normalizedPhone, code);
|
||||
|
||||
return { code: null };
|
||||
return { code };
|
||||
}
|
||||
|
||||
async verifyOtp(phone: string, slug: string, code: string) {
|
||||
@@ -83,11 +85,7 @@ export class AuthService {
|
||||
if (cachedCode !== code) throw new BadRequestException('Invalid OTP');
|
||||
await this.cacheService.del(key);
|
||||
|
||||
const admin = await this.adminRepository.findByPhoneAndRestaurantSlug(normalizedPhone, slug);
|
||||
|
||||
if (!admin) {
|
||||
throw new BadRequestException(AuthMessage.ADMIN_NOT_FOUND);
|
||||
}
|
||||
const admin = await this.adminService.findByPhoneAndShopSlug(normalizedPhone, slug);
|
||||
|
||||
const rest = await this.shopRepository.findOne({ slug });
|
||||
|
||||
@@ -107,7 +105,7 @@ export class AuthService {
|
||||
*/
|
||||
async loginAdminForDsc(phone: string, slug: string) {
|
||||
const normalizedPhone = normalizePhone(phone);
|
||||
const admin = await this.adminRepository.findByPhoneAndRestaurantSlug(normalizedPhone, slug);
|
||||
const admin = await this.adminService.findByPhoneAndShopSlug(normalizedPhone, slug);
|
||||
|
||||
if (!admin) {
|
||||
throw new BadRequestException(AuthMessage.ADMIN_NOT_FOUND);
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import { Type } from 'class-transformer';
|
||||
import {
|
||||
ArrayUnique,
|
||||
IsArray,
|
||||
IsBoolean,
|
||||
IsEnum,
|
||||
@@ -16,7 +15,8 @@ import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger';
|
||||
|
||||
export class CreateVariantDto {
|
||||
@IsString()
|
||||
@ApiProperty()
|
||||
@IsOptional()
|
||||
@ApiPropertyOptional()
|
||||
id: string
|
||||
|
||||
@IsString()
|
||||
@@ -49,9 +49,9 @@ export class CreateProductDto {
|
||||
@ApiPropertyOptional({
|
||||
type: CreateVariantDto,
|
||||
example: [{
|
||||
id: '',
|
||||
value: 'قرمز',
|
||||
price: 100000,
|
||||
stock: 20
|
||||
}]
|
||||
})
|
||||
variants: CreateVariantDto[]
|
||||
@@ -88,12 +88,6 @@ export class CreateProductDto {
|
||||
@ApiPropertyOptional({ example: 0 })
|
||||
discount?: number;
|
||||
|
||||
@IsOptional()
|
||||
@IsNumber()
|
||||
@Min(0)
|
||||
@Type(() => Number)
|
||||
@ApiProperty({ example: 50 })
|
||||
stock: number;
|
||||
|
||||
@IsOptional()
|
||||
@IsBoolean()
|
||||
|
||||
@@ -15,7 +15,7 @@ export class AdminsSeeder {
|
||||
const role = rolesMap.get(adminData.roleName);
|
||||
if (!role) continue;
|
||||
|
||||
const shop = adminData.restaurantSlug ? restaurantsMap.get(adminData.restaurantSlug) : null;
|
||||
const shop = adminData.shopSlug ? restaurantsMap.get(adminData.shopSlug) : null;
|
||||
|
||||
// For shop role, shop is required
|
||||
if (!shop) continue;
|
||||
@@ -31,7 +31,7 @@ export class AdminsSeeder {
|
||||
const adminRole = em.create(AdminRole, {
|
||||
admin,
|
||||
role,
|
||||
shop: adminData.restaurantSlug ? shop : null,
|
||||
shop: adminData.shopSlug ? shop : null,
|
||||
});
|
||||
em.persist(adminRole);
|
||||
admin.roles.add(adminRole);
|
||||
|
||||
@@ -3,7 +3,7 @@ export interface AdminData {
|
||||
firstName: string;
|
||||
lastName: string;
|
||||
roleName: string;
|
||||
restaurantSlug: string | null;
|
||||
shopSlug: string | null;
|
||||
}
|
||||
|
||||
export const adminsData: AdminData[] = [
|
||||
@@ -12,27 +12,27 @@ export const adminsData: AdminData[] = [
|
||||
firstName: 'مرتضی',
|
||||
lastName: 'مرتضایی',
|
||||
roleName: 'مدیر ( پلن ویژه)',
|
||||
restaurantSlug: 'boote',
|
||||
shopSlug: 'boote',
|
||||
},
|
||||
{
|
||||
phone: '09185290775',
|
||||
firstName: 'حمید',
|
||||
lastName: 'ضرقامی',
|
||||
roleName: 'مدیر ( پلن ویژه)',
|
||||
restaurantSlug: 'boote',
|
||||
roleName: 'مدیر ( پلن ویژه)',
|
||||
shopSlug: 'boote',
|
||||
},
|
||||
{
|
||||
phone: '09129283395',
|
||||
firstName: 'مهرداد',
|
||||
lastName: 'مظفری',
|
||||
roleName: 'مدیر ( پلن ویژه)',
|
||||
restaurantSlug: 'boote',
|
||||
shopSlug: 'boote',
|
||||
},
|
||||
{
|
||||
phone: '09184317567',
|
||||
firstName: 'ادمین',
|
||||
lastName: 'هنر',
|
||||
roleName: 'مدیر ( پلن ویژه)',
|
||||
restaurantSlug: 'boote',
|
||||
shopSlug: 'boote',
|
||||
},
|
||||
];
|
||||
|
||||
@@ -40,9 +40,9 @@ export const shopsData: ShopData[] =[
|
||||
subscriptionId: 'sub_seed_zhivan_001',
|
||||
},
|
||||
{
|
||||
name: 'سپنتا',
|
||||
slug: 'sepanta',
|
||||
domain: 'https://dmenu-plus-front.dev.danakcorp.com/sepanta',
|
||||
name: 'بوته',
|
||||
slug: 'boote',
|
||||
domain: 'https://dmenu-plus-front.dev.danakcorp.com/boote',
|
||||
isActive: true,
|
||||
phone: '',
|
||||
logo: 'https://dmenu.danakcorp.com/uploads/images/store/store_1641199914860_61d2b72b2e8bd97126a70b5f.png',
|
||||
@@ -56,6 +56,6 @@ export const shopsData: ShopData[] =[
|
||||
marriageDateScore: '0',
|
||||
referrerScore: '0',
|
||||
},
|
||||
subscriptionId: 'sub_seed_sepanta_001',
|
||||
subscriptionId: 'sub_seed_boote_001',
|
||||
},
|
||||
]
|
||||
Reference in New Issue
Block a user