update pos consumer module
This commit is contained in:
@@ -0,0 +1,29 @@
|
||||
import {
|
||||
BadRequestException,
|
||||
createParamDecorator,
|
||||
ExecutionContext,
|
||||
UnauthorizedException,
|
||||
} from '@nestjs/common'
|
||||
import { Request } from 'express'
|
||||
import { IPosPayload } from '../models/posPayload.model'
|
||||
|
||||
export const PosInfo = createParamDecorator(
|
||||
(data: keyof IPosPayload | undefined, ctx: ExecutionContext) => {
|
||||
try {
|
||||
const request = ctx.switchToHttp().getRequest<Request>()
|
||||
const posInfo = request.posData
|
||||
|
||||
if (!posInfo) {
|
||||
throw new UnauthorizedException('شما به این بخش دسترسی ندارید')
|
||||
}
|
||||
|
||||
if (data) {
|
||||
return posInfo[data]
|
||||
}
|
||||
|
||||
return posInfo
|
||||
} catch (err) {
|
||||
throw new BadRequestException('مشکلی در ساختار درخواست شما وجود دارد.')
|
||||
}
|
||||
},
|
||||
)
|
||||
@@ -1,4 +1,4 @@
|
||||
import { AccessTokenPayload } from '@/modules/auth/models'
|
||||
import { AccessTokenPayload } from '@/common/models/tokenPayload.model'
|
||||
import {
|
||||
BadRequestException,
|
||||
createParamDecorator,
|
||||
@@ -29,6 +29,8 @@ export const TokenAccount = createParamDecorator(
|
||||
// ✅ if called with no param — return full account object
|
||||
return account
|
||||
} catch (err) {
|
||||
console.log(err)
|
||||
|
||||
throw new BadRequestException('مشکلی در ساختار درخواست شما وجود دارد.')
|
||||
}
|
||||
},
|
||||
|
||||
@@ -8,15 +8,11 @@ import { Response } from 'express'
|
||||
|
||||
@Catch(BadRequestException)
|
||||
export class ValidationExceptionFilter implements ExceptionFilter {
|
||||
constructor() {
|
||||
console.log('ValidationExceptionFilter initialized')
|
||||
}
|
||||
catch(exception: BadRequestException, host: ArgumentsHost) {
|
||||
const ctx = host.switchToHttp()
|
||||
const response = ctx.getResponse<Response>()
|
||||
const status = exception.getStatus()
|
||||
const exceptionResponse = exception.getResponse()
|
||||
console.log(exception)
|
||||
|
||||
response.status(status).json({
|
||||
statusCode: status,
|
||||
|
||||
@@ -1,57 +0,0 @@
|
||||
import {
|
||||
CanActivate,
|
||||
ExecutionContext,
|
||||
Injectable,
|
||||
UnauthorizedException,
|
||||
} from '@nestjs/common'
|
||||
import { Reflector } from '@nestjs/core'
|
||||
import { JwtService } from '@nestjs/jwt'
|
||||
import { IS_PUBLIC_KEY } from '../decorators/public.decorator'
|
||||
import { IWithJWTPayloadRequest } from '../models/token-model'
|
||||
|
||||
@Injectable()
|
||||
export class JwtAuthGuard implements CanActivate {
|
||||
constructor(
|
||||
private jwt: JwtService,
|
||||
private reflector: Reflector,
|
||||
) {}
|
||||
|
||||
async canActivate(context: ExecutionContext): Promise<boolean> {
|
||||
const isPublic = this.reflector.getAllAndOverride<boolean>(IS_PUBLIC_KEY, [
|
||||
context.getHandler(),
|
||||
context.getClass(),
|
||||
])
|
||||
if (isPublic) return true
|
||||
|
||||
const req = context.switchToHttp().getRequest<IWithJWTPayloadRequest>()
|
||||
|
||||
let token: string | undefined = req.cookies?.accessToken
|
||||
if (!token) {
|
||||
const authHeader = (req.headers.authorization || req.headers.Authorization) as
|
||||
| string
|
||||
| undefined
|
||||
if (authHeader && authHeader.startsWith('Bearer ')) {
|
||||
token = authHeader.slice(7)
|
||||
}
|
||||
}
|
||||
|
||||
if (!token) throw new UnauthorizedException('Missing access token')
|
||||
|
||||
try {
|
||||
const payload = this.jwt.verify(token, {
|
||||
secret: process.env.JWT_SECRET || 'secret',
|
||||
})
|
||||
|
||||
if (payload.type !== 'POS')
|
||||
throw new UnauthorizedException('Invalid or expired token')
|
||||
|
||||
// Set the typed dataPayload to the request
|
||||
req.dataPayload = payload
|
||||
|
||||
return true
|
||||
} catch (err) {
|
||||
console.log(err)
|
||||
throw new UnauthorizedException('Invalid or expired token')
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6,8 +6,8 @@ import {
|
||||
} from '@nestjs/common'
|
||||
import { Reflector } from '@nestjs/core'
|
||||
import { JwtService } from '@nestjs/jwt'
|
||||
import { Request as ExpressRequest } from 'express'
|
||||
import { IS_PUBLIC_KEY } from '../decorators/public.decorator'
|
||||
import { IWithJWTPayloadRequest } from '../models/token-model'
|
||||
|
||||
@Injectable()
|
||||
export class JwtAuthGuard implements CanActivate {
|
||||
@@ -23,7 +23,7 @@ export class JwtAuthGuard implements CanActivate {
|
||||
])
|
||||
if (isPublic) return true
|
||||
|
||||
const req = context.switchToHttp().getRequest<IWithJWTPayloadRequest>()
|
||||
const req = context.switchToHttp().getRequest<ExpressRequest>()
|
||||
|
||||
let token: string | undefined = req.cookies?.accessToken
|
||||
if (!token) {
|
||||
@@ -38,15 +38,15 @@ export class JwtAuthGuard implements CanActivate {
|
||||
if (!token) throw new UnauthorizedException('Missing access token')
|
||||
|
||||
try {
|
||||
const payload = this.jwt.verify(token, {
|
||||
secret: process.env.JWT_SECRET || 'secret',
|
||||
this.jwt.verify(token, {
|
||||
secret: process.env.JWT_SECRET,
|
||||
})
|
||||
|
||||
// if (payload.type !== 'POS')
|
||||
// throw new UnauthorizedException('Invalid or expired token')
|
||||
|
||||
// Set the typed dataPayload to the request
|
||||
req.dataPayload = payload
|
||||
// req.dataPayload = payload
|
||||
|
||||
return true
|
||||
} catch (err) {
|
||||
|
||||
@@ -0,0 +1,130 @@
|
||||
// src/common/guards/permissions.guard.ts
|
||||
import { PrismaService } from '@/prisma/prisma.service'
|
||||
import {
|
||||
CanActivate,
|
||||
ExecutionContext,
|
||||
ForbiddenException,
|
||||
Injectable,
|
||||
} from '@nestjs/common'
|
||||
import { Reflector } from '@nestjs/core'
|
||||
import { JwtService } from '@nestjs/jwt'
|
||||
import { Request as ExpressRequest } from 'express'
|
||||
import { IS_PUBLIC_KEY } from '../decorators/public.decorator'
|
||||
import { checkAndDecodeJwtToken } from '../utils/jwt-user.util'
|
||||
|
||||
@Injectable()
|
||||
export class PosGuard implements CanActivate {
|
||||
constructor(
|
||||
private jwt: JwtService,
|
||||
private reflector: Reflector,
|
||||
private prisma: PrismaService,
|
||||
) {}
|
||||
|
||||
async canActivate(context: ExecutionContext): Promise<boolean> {
|
||||
const isPublic = this.reflector.getAllAndOverride<boolean>(IS_PUBLIC_KEY, [
|
||||
context.getHandler(),
|
||||
context.getClass(),
|
||||
])
|
||||
if (isPublic) return true
|
||||
|
||||
// const requiredPermissions = this.reflector.get<string[]>(
|
||||
// 'permissions',
|
||||
// context.getHandler(),
|
||||
// )
|
||||
// if (!requiredPermissions || requiredPermissions.length === 0) return true
|
||||
|
||||
const req = context.switchToHttp().getRequest<ExpressRequest>()
|
||||
|
||||
const account = checkAndDecodeJwtToken(req, this.jwt)
|
||||
// const account = req.decodedToken
|
||||
|
||||
if (!req.url.startsWith('/api/v1/pos/')) {
|
||||
return true
|
||||
}
|
||||
|
||||
if (!account || account.type !== 'CONSUMER')
|
||||
throw new ForbiddenException('شما دسترسی لازم را ندارید.')
|
||||
|
||||
const cookie = req.cookies
|
||||
const { posId, accessToken } = cookie
|
||||
|
||||
if (!posId || !accessToken) {
|
||||
return false
|
||||
}
|
||||
|
||||
const pos = await this.prisma.pos.findUnique({
|
||||
where: {
|
||||
id: posId,
|
||||
complex: {
|
||||
business_activity: {
|
||||
user: {
|
||||
accounts: {
|
||||
some: {
|
||||
account_id: account.account_id,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
select: {
|
||||
complex: {
|
||||
select: {
|
||||
id: true,
|
||||
business_activity_id: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
if (!pos) {
|
||||
throw new ForbiddenException('شما دسترسی لازم را ندارید.')
|
||||
}
|
||||
|
||||
const foundedAccount = await this.prisma.account.findUnique({
|
||||
where: {
|
||||
id: account.account_id,
|
||||
},
|
||||
select: {
|
||||
consumer_account: {
|
||||
select: {
|
||||
role: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
if (foundedAccount?.consumer_account?.role === 'OWNER') {
|
||||
return true
|
||||
}
|
||||
|
||||
const accountPermissions = await this.prisma.permissionConsumer.findUnique({
|
||||
where: {
|
||||
account_id: account.account_id,
|
||||
},
|
||||
select: {
|
||||
posPermissions: true,
|
||||
businessPermissions: true,
|
||||
complexPermissions: true,
|
||||
},
|
||||
})
|
||||
|
||||
if (accountPermissions?.posPermissions.some(p => p.pos_id === posId)) {
|
||||
return true
|
||||
}
|
||||
if (
|
||||
accountPermissions?.complexPermissions.some(p => p.complex_id === pos.complex.id)
|
||||
) {
|
||||
return true
|
||||
}
|
||||
if (
|
||||
accountPermissions?.businessPermissions.some(
|
||||
p => p.business_id === pos.complex.business_activity_id,
|
||||
)
|
||||
) {
|
||||
return true
|
||||
}
|
||||
|
||||
throw new ForbiddenException('شما دسترسی لازم را ندارید.')
|
||||
}
|
||||
}
|
||||
@@ -6,3 +6,5 @@ export interface SaleInvoiceGoldTypePayload {
|
||||
profit: number
|
||||
}
|
||||
export interface SaleInvoiceStandardPayload {}
|
||||
|
||||
export type SaleInvoiceType = SaleInvoiceGoldTypePayload | SaleInvoiceStandardPayload
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
export interface IPosPayload {
|
||||
pos_id: string
|
||||
complex_id: string
|
||||
guild_id: string
|
||||
business_id: string
|
||||
consumer_account_id: string
|
||||
}
|
||||
@@ -1,29 +0,0 @@
|
||||
import { Request as ExpressRequest } from 'express'
|
||||
import { AccountType } from '../enums/enums'
|
||||
|
||||
export interface IWithJWTPayloadRequest extends ExpressRequest {
|
||||
dataPayload?: AccessTokenPayload
|
||||
}
|
||||
|
||||
export interface AccessTokenPayload {
|
||||
userId: string
|
||||
mobile_number: string
|
||||
type: AccountType
|
||||
username: string
|
||||
pos_id: number
|
||||
pos_name: string
|
||||
|
||||
complex_id: string
|
||||
license_id: string
|
||||
license_expired_at: string
|
||||
// complex: {
|
||||
// id: string
|
||||
// name: string
|
||||
// }
|
||||
// license: {
|
||||
// id: string
|
||||
// starts_at: string
|
||||
// expires_at: string
|
||||
// status: string
|
||||
// }
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
import { AccountType } from '../../generated/prisma/enums'
|
||||
|
||||
export interface AccessTokenPayload {
|
||||
account_id: string
|
||||
type: AccountType
|
||||
username: string
|
||||
user?: AccessTokenUser
|
||||
// license_id?: string
|
||||
// license_expired_at?: string
|
||||
}
|
||||
|
||||
export interface AccessTokenUser extends Record<string, any> {
|
||||
id?: string
|
||||
name?: string
|
||||
}
|
||||
@@ -1,8 +1,8 @@
|
||||
import { AccessTokenPayload } from '@/common/models/tokenPayload.model'
|
||||
import { ITokenPayload } from '@/modules/auth/auth.utils'
|
||||
import { UnauthorizedException } from '@nestjs/common'
|
||||
import { JwtService } from '@nestjs/jwt'
|
||||
import { Request } from 'express'
|
||||
import { AccessTokenPayload } from 'modules/auth/models'
|
||||
|
||||
export function checkAndDecodeJwtToken(
|
||||
req: Request,
|
||||
|
||||
Reference in New Issue
Block a user