init to partner module
This commit is contained in:
@@ -1,15 +1,18 @@
|
|||||||
import { AccessTokenPayload, IConsumerPayload, IPosPayload } from '@/common/models'
|
import { AccessTokenPayload, IConsumerPayload, IPosPayload } from '@/common/models'
|
||||||
|
import { IPartnerPayload } from '@/common/models/partnerPayload.model'
|
||||||
|
|
||||||
declare global {
|
declare global {
|
||||||
interface Request {
|
interface Request {
|
||||||
decodedToken?: AccessTokenPayload
|
decodedToken?: AccessTokenPayload
|
||||||
consumerData?: IConsumerPayload
|
consumerData?: IConsumerPayload
|
||||||
|
partnerData?: IPartnerPayload
|
||||||
posData?: IPosPayload
|
posData?: IPosPayload
|
||||||
}
|
}
|
||||||
namespace Express {
|
namespace Express {
|
||||||
interface Request {
|
interface Request {
|
||||||
decodedToken?: AccessTokenPayload
|
decodedToken?: AccessTokenPayload
|
||||||
consumerData?: IConsumerPayload
|
partnerData?: IConsumerPayload
|
||||||
|
partnerData?: IPartnerPayload
|
||||||
posData?: IPosPayload
|
posData?: IPosPayload
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import { AuthModule } from './modules/auth/auth.module'
|
|||||||
import { CatalogModule } from './modules/catalog/catalog.module'
|
import { CatalogModule } from './modules/catalog/catalog.module'
|
||||||
import { ConsumerModule } from './modules/consumer/consumer.module'
|
import { ConsumerModule } from './modules/consumer/consumer.module'
|
||||||
import { EnumsModule } from './modules/enums/enums.module'
|
import { EnumsModule } from './modules/enums/enums.module'
|
||||||
|
import { PartnerModule } from './modules/partners/partners.module'
|
||||||
import { PosModule } from './modules/pos/pos.module'
|
import { PosModule } from './modules/pos/pos.module'
|
||||||
import { SalesInvoiceItemsModule } from './modules/pos/sales-invoices/sales-invoice-items/sales-invoice-items.module'
|
import { SalesInvoiceItemsModule } from './modules/pos/sales-invoices/sales-invoice-items/sales-invoice-items.module'
|
||||||
import { SalesInvoicePaymentsModule } from './modules/pos/sales-invoices/sales-invoice-payments/sales-invoice-payments.module'
|
import { SalesInvoicePaymentsModule } from './modules/pos/sales-invoices/sales-invoice-payments/sales-invoice-payments.module'
|
||||||
@@ -21,6 +22,7 @@ import { PrismaModule } from './prisma/prisma.module'
|
|||||||
CatalogModule,
|
CatalogModule,
|
||||||
ConsumerModule,
|
ConsumerModule,
|
||||||
PosModule,
|
PosModule,
|
||||||
|
PartnerModule,
|
||||||
AuthModule,
|
AuthModule,
|
||||||
SalesInvoiceItemsModule,
|
SalesInvoiceItemsModule,
|
||||||
SalesInvoicePaymentsModule,
|
SalesInvoicePaymentsModule,
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ export const ConsumerInfo = createParamDecorator(
|
|||||||
(data: keyof IConsumerPayload | undefined, ctx: ExecutionContext) => {
|
(data: keyof IConsumerPayload | undefined, ctx: ExecutionContext) => {
|
||||||
try {
|
try {
|
||||||
const request = ctx.switchToHttp().getRequest<Request>()
|
const request = ctx.switchToHttp().getRequest<Request>()
|
||||||
const info = request.consumerData
|
const info = request.partnerData
|
||||||
|
|
||||||
if (!info) {
|
if (!info) {
|
||||||
throw new ForbiddenException('شما به این بخش دسترسی ندارید')
|
throw new ForbiddenException('شما به این بخش دسترسی ندارید')
|
||||||
|
|||||||
@@ -0,0 +1,33 @@
|
|||||||
|
import {
|
||||||
|
BadRequestException,
|
||||||
|
createParamDecorator,
|
||||||
|
ExecutionContext,
|
||||||
|
ForbiddenException,
|
||||||
|
} from '@nestjs/common'
|
||||||
|
import { Request } from 'express'
|
||||||
|
import { IPartnerPayload } from '../models/partnerPayload.model'
|
||||||
|
|
||||||
|
export const PartnerInfo = createParamDecorator(
|
||||||
|
(data: keyof IPartnerPayload | undefined, ctx: ExecutionContext) => {
|
||||||
|
try {
|
||||||
|
const request = ctx.switchToHttp().getRequest<Request>()
|
||||||
|
const info = request.partnerData
|
||||||
|
|
||||||
|
if (!info) {
|
||||||
|
throw new ForbiddenException('شما به این بخش دسترسی ندارید')
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data) {
|
||||||
|
return info[data]
|
||||||
|
}
|
||||||
|
|
||||||
|
return info
|
||||||
|
} catch (err) {
|
||||||
|
if (err) {
|
||||||
|
throw err
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new BadRequestException('مشکلی در ساختار درخواست شما وجود دارد.')
|
||||||
|
}
|
||||||
|
},
|
||||||
|
)
|
||||||
@@ -0,0 +1,49 @@
|
|||||||
|
// src/common/guards/permissions.guard.ts
|
||||||
|
import { ITokenPayload } from '@/modules/auth/auth.utils'
|
||||||
|
import { PrismaService } from '@/prisma/prisma.service'
|
||||||
|
import {
|
||||||
|
ExecutionContext,
|
||||||
|
ForbiddenException,
|
||||||
|
Injectable,
|
||||||
|
UnauthorizedException,
|
||||||
|
} from '@nestjs/common'
|
||||||
|
import { Request as ExpressRequest } from 'express'
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class PartnerGuard {
|
||||||
|
constructor(private prisma: PrismaService) {}
|
||||||
|
|
||||||
|
async canActivate(
|
||||||
|
tokenPayload: ITokenPayload,
|
||||||
|
context: ExecutionContext,
|
||||||
|
): Promise<boolean> {
|
||||||
|
if (!tokenPayload || tokenPayload.type !== 'PARTNER') {
|
||||||
|
throw new UnauthorizedException()
|
||||||
|
}
|
||||||
|
|
||||||
|
const partner = await this.prisma.partner.findFirst({
|
||||||
|
where: {
|
||||||
|
partner_accounts: {
|
||||||
|
some: {
|
||||||
|
id: tokenPayload.account_id,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
select: {
|
||||||
|
partner_accounts: {
|
||||||
|
select: {
|
||||||
|
role: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
if (!partner) {
|
||||||
|
throw new ForbiddenException('شما دسترسی لازم را ندارید.')
|
||||||
|
}
|
||||||
|
|
||||||
|
const req = context.switchToHttp().getRequest<ExpressRequest>()
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,7 +2,6 @@ import { ITokenPayload } from '@/modules/auth/auth.utils'
|
|||||||
import {
|
import {
|
||||||
CanActivate,
|
CanActivate,
|
||||||
ExecutionContext,
|
ExecutionContext,
|
||||||
ForbiddenException,
|
|
||||||
Injectable,
|
Injectable,
|
||||||
UnauthorizedException,
|
UnauthorizedException,
|
||||||
} from '@nestjs/common'
|
} from '@nestjs/common'
|
||||||
@@ -12,6 +11,7 @@ import { Request as ExpressRequest } from 'express'
|
|||||||
import { IS_PUBLIC_KEY } from '../decorators/public.decorator'
|
import { IS_PUBLIC_KEY } from '../decorators/public.decorator'
|
||||||
import { IS_PUBLIC_WITH_TOKEN_KEY } from '../decorators/withToken.decorator'
|
import { IS_PUBLIC_WITH_TOKEN_KEY } from '../decorators/withToken.decorator'
|
||||||
import { ConsumerGuard } from './auth-consumer.guard'
|
import { ConsumerGuard } from './auth-consumer.guard'
|
||||||
|
import { PartnerGuard } from './auth-partner.guard'
|
||||||
import { PosGuard } from './auth-pos.guard'
|
import { PosGuard } from './auth-pos.guard'
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
@@ -21,6 +21,7 @@ export class JwtAuthGuard implements CanActivate {
|
|||||||
private reflector: Reflector,
|
private reflector: Reflector,
|
||||||
private consumerGuard: ConsumerGuard,
|
private consumerGuard: ConsumerGuard,
|
||||||
private posGuard: PosGuard,
|
private posGuard: PosGuard,
|
||||||
|
private partnerGuard: PartnerGuard,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
async canActivate(context: ExecutionContext): Promise<boolean> {
|
async canActivate(context: ExecutionContext): Promise<boolean> {
|
||||||
@@ -59,14 +60,17 @@ export class JwtAuthGuard implements CanActivate {
|
|||||||
|
|
||||||
const tokenPayload = this.jwt.decode(token) as ITokenPayload
|
const tokenPayload = this.jwt.decode(token) as ITokenPayload
|
||||||
|
|
||||||
if (req.url.startsWith('/api/v1/consumer')) {
|
// if (req.url.startsWith('/api/v1/partner')) {
|
||||||
await this.consumerGuard.canActivate(tokenPayload, context)
|
// await this.partnerGuard.canActivate(tokenPayload, context)
|
||||||
} else if (req.url.startsWith('/api/v1/pos')) {
|
// }
|
||||||
|
// if (req.url.startsWith('/api/v1/consumer')) {
|
||||||
// await this.consumerGuard.canActivate(tokenPayload, context)
|
// await this.consumerGuard.canActivate(tokenPayload, context)
|
||||||
await this.posGuard.canActivate(tokenPayload, context)
|
// } else if (req.url.startsWith('/api/v1/pos')) {
|
||||||
} else if (tokenPayload.type != 'ADMIN') {
|
// // await this.consumerGuard.canActivate(tokenPayload, context)
|
||||||
throw new ForbiddenException('شما دسترسی لازم را ندارید')
|
// await this.posGuard.canActivate(tokenPayload, context)
|
||||||
}
|
// } else if (tokenPayload.type != 'ADMIN') {
|
||||||
|
// throw new ForbiddenException('شما دسترسی لازم را ندارید')
|
||||||
|
// }
|
||||||
return true
|
return true
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
if (err) throw err
|
if (err) throw err
|
||||||
|
|||||||
@@ -0,0 +1,4 @@
|
|||||||
|
export interface IPartnerPayload {
|
||||||
|
id: string
|
||||||
|
account_id: string
|
||||||
|
}
|
||||||
@@ -6,6 +6,7 @@ import { AppModule } from './app.module'
|
|||||||
import { PrismaExceptionFilter } from './common/filters/prisma-exception.filter'
|
import { PrismaExceptionFilter } from './common/filters/prisma-exception.filter'
|
||||||
import { ValidationExceptionFilter } from './common/filters/validation-exception.filter'
|
import { ValidationExceptionFilter } from './common/filters/validation-exception.filter'
|
||||||
import { ConsumerGuard } from './common/guards/auth-consumer.guard'
|
import { ConsumerGuard } from './common/guards/auth-consumer.guard'
|
||||||
|
import { PartnerGuard } from './common/guards/auth-partner.guard'
|
||||||
import { PosGuard } from './common/guards/auth-pos.guard'
|
import { PosGuard } from './common/guards/auth-pos.guard'
|
||||||
import { JwtAuthGuard } from './common/guards/jwt-auth.guard'
|
import { JwtAuthGuard } from './common/guards/jwt-auth.guard'
|
||||||
import { LoggingInterceptor } from './common/interceptors/logging.interceptor'
|
import { LoggingInterceptor } from './common/interceptors/logging.interceptor'
|
||||||
@@ -88,6 +89,7 @@ async function bootstrap() {
|
|||||||
app.get(Reflector),
|
app.get(Reflector),
|
||||||
new ConsumerGuard(new PrismaService()),
|
new ConsumerGuard(new PrismaService()),
|
||||||
new PosGuard(new PrismaService()),
|
new PosGuard(new PrismaService()),
|
||||||
|
new PartnerGuard(new PrismaService()),
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ export class ConsumerMiddleware implements NestMiddleware {
|
|||||||
return doForbidden()
|
return doForbidden()
|
||||||
}
|
}
|
||||||
|
|
||||||
req.consumerData = {
|
req.partnerData = {
|
||||||
account_id: consumerAccount.id,
|
account_id: consumerAccount.id,
|
||||||
id: consumerAccount.consumer_id,
|
id: consumerAccount.consumer_id,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,39 @@
|
|||||||
|
import { TokenAccount } from '@/common/decorators/tokenInfo.decorator'
|
||||||
|
import { Body, Controller, Get, Param, Patch } from '@nestjs/common'
|
||||||
|
import { ApiTags } from '@nestjs/swagger'
|
||||||
|
import { AccountsService } from './accounts.service'
|
||||||
|
import { UpdateAccountDto } from './dto/account.dto'
|
||||||
|
|
||||||
|
@ApiTags('PartnerAccounts')
|
||||||
|
@Controller('partner/accounts')
|
||||||
|
export class AccountsController {
|
||||||
|
constructor(private readonly service: AccountsService) {}
|
||||||
|
|
||||||
|
@Get()
|
||||||
|
async findAll(@TokenAccount('userId') consumerId: string) {
|
||||||
|
return this.service.findAll(consumerId)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Get(':id')
|
||||||
|
async findOne(@Param('id') id: string) {
|
||||||
|
return this.service.findOne(id)
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Post()
|
||||||
|
// async create(
|
||||||
|
// @TokenAccount('userId') consumerId: string,
|
||||||
|
// @Body() data: CreateConsumerAccountDto,
|
||||||
|
// ) {
|
||||||
|
// return this.service.create(consumerId, data)
|
||||||
|
// }
|
||||||
|
|
||||||
|
@Patch(':id')
|
||||||
|
async update(@Param('id') id: string, @Body() data: UpdateAccountDto) {
|
||||||
|
return this.service.update(id, data)
|
||||||
|
}
|
||||||
|
|
||||||
|
// @Delete(':id')
|
||||||
|
// async delete(@Param('id') id: string) {
|
||||||
|
// return this.service.delete(id)
|
||||||
|
// }
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
import { PrismaModule } from '@/prisma/prisma.module'
|
||||||
|
import { Module } from '@nestjs/common'
|
||||||
|
import { AccountsController } from './accounts.controller'
|
||||||
|
import { AccountsService } from './accounts.service'
|
||||||
|
|
||||||
|
@Module({
|
||||||
|
imports: [PrismaModule],
|
||||||
|
controllers: [AccountsController],
|
||||||
|
providers: [AccountsService],
|
||||||
|
exports: [AccountsService],
|
||||||
|
})
|
||||||
|
export class PartnerAccountsModule {}
|
||||||
@@ -0,0 +1,79 @@
|
|||||||
|
import { PasswordUtil } from '@/common/utils/password.util'
|
||||||
|
import { AccountStatus, AccountType } from '@/generated/prisma/enums'
|
||||||
|
import { PrismaService } from '@/prisma/prisma.service'
|
||||||
|
import { Injectable } from '@nestjs/common'
|
||||||
|
import { ResponseMapper } from 'common/response/response-mapper'
|
||||||
|
import { CreatePartnerAccountDto, UpdateAccountDto } from './dto/account.dto'
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class AccountsService {
|
||||||
|
constructor(private readonly prisma: PrismaService) {}
|
||||||
|
|
||||||
|
async findAll(partner_id: string) {
|
||||||
|
const accounts = await this.prisma.partnerAccount.findMany({
|
||||||
|
where: { partner_id },
|
||||||
|
select: {
|
||||||
|
id: true,
|
||||||
|
role: true,
|
||||||
|
created_at: true,
|
||||||
|
account: {
|
||||||
|
select: {
|
||||||
|
username: true,
|
||||||
|
status: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
return ResponseMapper.list(accounts)
|
||||||
|
}
|
||||||
|
|
||||||
|
async findOne(id: string) {
|
||||||
|
const account = await this.prisma.partnerAccount.findUniqueOrThrow({
|
||||||
|
where: { id },
|
||||||
|
select: {
|
||||||
|
id: true,
|
||||||
|
role: true,
|
||||||
|
created_at: true,
|
||||||
|
account: {
|
||||||
|
select: {
|
||||||
|
username: true,
|
||||||
|
status: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
return ResponseMapper.single(account)
|
||||||
|
}
|
||||||
|
|
||||||
|
async create(partnerId: string, data: CreatePartnerAccountDto) {
|
||||||
|
const account = await this.prisma.partnerAccount.create({
|
||||||
|
data: {
|
||||||
|
role: data.role,
|
||||||
|
account: {
|
||||||
|
create: {
|
||||||
|
password: await PasswordUtil.hash(data.password),
|
||||||
|
status: AccountStatus.ACTIVE,
|
||||||
|
type: AccountType.PARTNER,
|
||||||
|
username: data.username,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
partner: {
|
||||||
|
connect: {
|
||||||
|
id: partnerId,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
return ResponseMapper.create(account)
|
||||||
|
}
|
||||||
|
|
||||||
|
async update(id: string, data: UpdateAccountDto) {
|
||||||
|
const account = await this.prisma.account.update({ where: { id }, data })
|
||||||
|
return ResponseMapper.update(account)
|
||||||
|
}
|
||||||
|
|
||||||
|
// async delete(id: string) {
|
||||||
|
// await this.prisma.account.delete({ where: { id } })
|
||||||
|
// return ResponseMapper.delete()
|
||||||
|
// }
|
||||||
|
}
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
import { ApiProperty, PartialType } from '@nestjs/swagger'
|
||||||
|
import { IsEnum, IsOptional, IsString } from 'class-validator'
|
||||||
|
import { AccountStatus, PartnerRole } from 'generated/prisma/enums'
|
||||||
|
|
||||||
|
export class CreatePartnerAccountDto {
|
||||||
|
@IsString()
|
||||||
|
@ApiProperty({ required: true })
|
||||||
|
username: string
|
||||||
|
|
||||||
|
@IsString()
|
||||||
|
@ApiProperty({ required: true })
|
||||||
|
password: string
|
||||||
|
|
||||||
|
@IsEnum(PartnerRole)
|
||||||
|
@ApiProperty({ required: true, enum: PartnerRole })
|
||||||
|
role: PartnerRole
|
||||||
|
}
|
||||||
|
|
||||||
|
export class UpdateAccountDto extends PartialType(CreatePartnerAccountDto) {
|
||||||
|
@IsOptional()
|
||||||
|
@IsEnum(AccountStatus)
|
||||||
|
@ApiProperty({ enum: AccountStatus })
|
||||||
|
status?: AccountStatus
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
import { PartnerInfo } from '@/common/decorators/partnerInfo.decorator'
|
||||||
|
import { Controller, Get, Param } from '@nestjs/common'
|
||||||
|
import { PartnerCustomersService } from './customers.service'
|
||||||
|
|
||||||
|
@Controller('partner/customers')
|
||||||
|
export class PartnerCustomersController {
|
||||||
|
constructor(private readonly service: PartnerCustomersService) {}
|
||||||
|
|
||||||
|
@Get()
|
||||||
|
async findAll(@PartnerInfo('id') partnerId: string) {
|
||||||
|
return this.service.findAll(partnerId)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Get(':id')
|
||||||
|
async findOne(@PartnerInfo('id') partnerId: string, @Param('id') id: string) {
|
||||||
|
return this.service.findOne(partnerId, id)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
import { PrismaModule } from '@/prisma/prisma.module'
|
||||||
|
import { Module } from '@nestjs/common'
|
||||||
|
import { PartnerCustomersController } from './customers.controller'
|
||||||
|
import { PartnerCustomersService } from './customers.service'
|
||||||
|
|
||||||
|
@Module({
|
||||||
|
imports: [PrismaModule],
|
||||||
|
controllers: [PartnerCustomersController],
|
||||||
|
providers: [PartnerCustomersService],
|
||||||
|
})
|
||||||
|
export class PartnerCustomersModule {}
|
||||||
@@ -0,0 +1,61 @@
|
|||||||
|
import { ConsumerSelect, ConsumerWhereInput } from '@/generated/prisma/models'
|
||||||
|
import { PrismaService } from '@/prisma/prisma.service'
|
||||||
|
import { Injectable } from '@nestjs/common'
|
||||||
|
import { ResponseMapper } from 'common/response/response-mapper'
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class PartnerCustomersService {
|
||||||
|
constructor(private readonly prisma: PrismaService) {}
|
||||||
|
|
||||||
|
defaultSelect: ConsumerSelect = {
|
||||||
|
id: true,
|
||||||
|
first_name: true,
|
||||||
|
last_name: true,
|
||||||
|
status: true,
|
||||||
|
license: {
|
||||||
|
select: {
|
||||||
|
id: true,
|
||||||
|
starts_at: true,
|
||||||
|
status: true,
|
||||||
|
expires_at: true,
|
||||||
|
created_at: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
created_at: true,
|
||||||
|
}
|
||||||
|
|
||||||
|
private defaultWhere = (partner_id: string): ConsumerWhereInput => ({
|
||||||
|
license: {
|
||||||
|
partner_id,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
async findAll(partner_id: string, page = 1, pageSize = 10) {
|
||||||
|
const [partners, count] = await this.prisma.$transaction(async tx => [
|
||||||
|
await tx.consumer.findMany({
|
||||||
|
where: this.defaultWhere(partner_id),
|
||||||
|
select: this.defaultSelect,
|
||||||
|
skip: (page - 1) * pageSize,
|
||||||
|
take: 10,
|
||||||
|
}),
|
||||||
|
await tx.consumer.count({
|
||||||
|
where: this.defaultWhere(partner_id),
|
||||||
|
}),
|
||||||
|
])
|
||||||
|
return ResponseMapper.paginate(partners, { count, page, pageSize })
|
||||||
|
}
|
||||||
|
|
||||||
|
async findOne(partner_id: string, consumer_id: string) {
|
||||||
|
const partner = await this.prisma.consumer.findUniqueOrThrow({
|
||||||
|
where: {
|
||||||
|
license: {
|
||||||
|
partner_id,
|
||||||
|
},
|
||||||
|
id: consumer_id,
|
||||||
|
},
|
||||||
|
select: this.defaultSelect,
|
||||||
|
})
|
||||||
|
|
||||||
|
return ResponseMapper.single(partner)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,74 @@
|
|||||||
|
import { ApiProperty } from '@nestjs/swagger'
|
||||||
|
import {
|
||||||
|
IsBoolean,
|
||||||
|
IsNumber,
|
||||||
|
IsOptional,
|
||||||
|
IsString,
|
||||||
|
MaxLength,
|
||||||
|
MinLength,
|
||||||
|
} from 'class-validator'
|
||||||
|
|
||||||
|
export class UpdateCustomerLegalDto {
|
||||||
|
@IsString()
|
||||||
|
@IsOptional()
|
||||||
|
@ApiProperty({ required: true })
|
||||||
|
company_name?: string
|
||||||
|
|
||||||
|
@IsString()
|
||||||
|
@IsOptional()
|
||||||
|
@ApiProperty({ required: true })
|
||||||
|
economic_code?: string
|
||||||
|
|
||||||
|
@IsString()
|
||||||
|
@IsOptional()
|
||||||
|
@ApiProperty({ required: true })
|
||||||
|
registration_number?: string
|
||||||
|
|
||||||
|
@IsNumber()
|
||||||
|
@MaxLength(10)
|
||||||
|
@MinLength(10)
|
||||||
|
@IsOptional()
|
||||||
|
@ApiProperty({ maxLength: 10, minLength: 10 })
|
||||||
|
postal_code?: string
|
||||||
|
|
||||||
|
@IsBoolean()
|
||||||
|
@IsOptional()
|
||||||
|
@ApiProperty({ required: false })
|
||||||
|
is_favorite?: boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
export class UpdateCustomerIndividualDto {
|
||||||
|
@IsString()
|
||||||
|
@IsOptional()
|
||||||
|
@ApiProperty({ required: true })
|
||||||
|
first_name?: string
|
||||||
|
|
||||||
|
@IsString()
|
||||||
|
@IsOptional()
|
||||||
|
@ApiProperty({ required: true })
|
||||||
|
last_name?: string
|
||||||
|
|
||||||
|
@IsNumber()
|
||||||
|
@MaxLength(10)
|
||||||
|
@MinLength(10)
|
||||||
|
@IsOptional()
|
||||||
|
@ApiProperty({ required: true, maxLength: 10, minLength: 10 })
|
||||||
|
national_code?: string
|
||||||
|
|
||||||
|
@IsNumber()
|
||||||
|
@MaxLength(10)
|
||||||
|
@MinLength(10)
|
||||||
|
@IsOptional()
|
||||||
|
@ApiProperty({ maxLength: 10, minLength: 10 })
|
||||||
|
postal_code?: string
|
||||||
|
|
||||||
|
@IsBoolean()
|
||||||
|
@IsOptional()
|
||||||
|
@ApiProperty({ required: false })
|
||||||
|
is_favorite?: boolean
|
||||||
|
|
||||||
|
@IsNumber()
|
||||||
|
@IsOptional()
|
||||||
|
@ApiProperty({ required: false })
|
||||||
|
economic_code?: string
|
||||||
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
import { ConsumerInfo } from '@/common/decorators/consumerInfo.decorator'
|
||||||
|
import { Controller, Get } from '@nestjs/common'
|
||||||
|
import { ApiTags } from '@nestjs/swagger'
|
||||||
|
import { PartnerService } from './partners.service'
|
||||||
|
|
||||||
|
@ApiTags('Partner')
|
||||||
|
@Controller('partner')
|
||||||
|
export class PartnerController {
|
||||||
|
constructor(private service: PartnerService) {}
|
||||||
|
|
||||||
|
@Get('')
|
||||||
|
async findOne(@ConsumerInfo('id') consumerId: string) {
|
||||||
|
return this.service.getInfo(consumerId)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,61 @@
|
|||||||
|
import { checkAndDecodeJwtToken } from '@/common/utils/jwt-user.util'
|
||||||
|
import { PrismaService } from '@/prisma/prisma.service'
|
||||||
|
import {
|
||||||
|
ForbiddenException,
|
||||||
|
Injectable,
|
||||||
|
NestMiddleware,
|
||||||
|
UnauthorizedException,
|
||||||
|
} from '@nestjs/common'
|
||||||
|
import { JwtService } from '@nestjs/jwt'
|
||||||
|
import { NextFunction, Request, Response } from 'express'
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class PartnerMiddleware implements NestMiddleware {
|
||||||
|
constructor(
|
||||||
|
private prisma: PrismaService,
|
||||||
|
private jwtService: JwtService,
|
||||||
|
) {}
|
||||||
|
|
||||||
|
async use(req: Request, _res: Response, next: NextFunction) {
|
||||||
|
const doForbidden = () => {
|
||||||
|
console.log('doForbidden')
|
||||||
|
|
||||||
|
throw new ForbiddenException('شما دسترسی لازم را ندارید')
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
const tokenAccount = checkAndDecodeJwtToken(req, this.jwtService)
|
||||||
|
|
||||||
|
if (tokenAccount?.type !== 'PARTNER') {
|
||||||
|
throw new UnauthorizedException()
|
||||||
|
}
|
||||||
|
|
||||||
|
const partnerAccount = await this.prisma.partnerAccount.findUnique({
|
||||||
|
where: {
|
||||||
|
id: tokenAccount.account_id,
|
||||||
|
},
|
||||||
|
select: {
|
||||||
|
partner_id: true,
|
||||||
|
id: true,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
if (!partnerAccount) {
|
||||||
|
return doForbidden()
|
||||||
|
}
|
||||||
|
|
||||||
|
req.partnerData = {
|
||||||
|
account_id: partnerAccount.id,
|
||||||
|
id: partnerAccount.partner_id,
|
||||||
|
}
|
||||||
|
|
||||||
|
req.decodedToken = tokenAccount
|
||||||
|
|
||||||
|
return next()
|
||||||
|
} catch (error) {
|
||||||
|
if (error && typeof error === 'object') {
|
||||||
|
throw error
|
||||||
|
}
|
||||||
|
return doForbidden()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
import { MiddlewareConsumer, Module, NestModule, RequestMethod } from '@nestjs/common'
|
||||||
|
import { JwtService } from '@nestjs/jwt'
|
||||||
|
import { PartnerAccountsModule } from './accounts/accounts.module'
|
||||||
|
import { PartnerCustomersModule } from './customers/customers.module'
|
||||||
|
import { PartnerController } from './partners.controller'
|
||||||
|
import { PartnerMiddleware } from './partners.middleware'
|
||||||
|
import { PartnerService } from './partners.service'
|
||||||
|
|
||||||
|
@Module({
|
||||||
|
controllers: [PartnerController],
|
||||||
|
imports: [PartnerAccountsModule, PartnerCustomersModule],
|
||||||
|
providers: [JwtService, PartnerService],
|
||||||
|
})
|
||||||
|
export class PartnerModule implements NestModule {
|
||||||
|
configure(partner: MiddlewareConsumer) {
|
||||||
|
partner.apply(PartnerMiddleware).forRoutes({
|
||||||
|
path: '/partner*path',
|
||||||
|
method: RequestMethod.ALL,
|
||||||
|
version: '1',
|
||||||
|
})
|
||||||
|
partner.apply(PartnerMiddleware).forRoutes({
|
||||||
|
path: '/partner',
|
||||||
|
method: RequestMethod.ALL,
|
||||||
|
version: '1',
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
import { ResponseMapper } from '@/common/response/response-mapper'
|
||||||
|
import { PrismaService } from '@/prisma/prisma.service'
|
||||||
|
import { Injectable } from '@nestjs/common'
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class PartnerService {
|
||||||
|
constructor(private readonly prisma: PrismaService) {}
|
||||||
|
|
||||||
|
async getInfo(partner_id: string) {
|
||||||
|
const partner = await this.prisma.partner.findUniqueOrThrow({
|
||||||
|
where: {
|
||||||
|
id: partner_id,
|
||||||
|
},
|
||||||
|
select: {
|
||||||
|
id: true,
|
||||||
|
name: true,
|
||||||
|
status: true,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
return ResponseMapper.single(partner)
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user