transform core api codes into this project, update modules as admin/pos context modules
This commit is contained in:
@@ -0,0 +1,11 @@
|
||||
export default {
|
||||
COUNT: 'تعداد',
|
||||
GRAM: 'گرم',
|
||||
KILO_GRAM: 'کیلوگرم',
|
||||
LITER: 'لیتر',
|
||||
MILLILITER: 'میلیلیتر',
|
||||
STANDARD: 'استاندارد',
|
||||
GOLD: 'طلا',
|
||||
ACTIVE: 'فعال',
|
||||
SUSPENDED: 'غیرفعال',
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
import enums from './enums'
|
||||
|
||||
export default {
|
||||
enums,
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
// src/common/database/transaction.helper.ts
|
||||
import { PrismaService } from '../../prisma/prisma.service'
|
||||
import { PrismaService } from '@/prisma/prisma.service'
|
||||
|
||||
export async function withTransaction<T>(
|
||||
prisma: PrismaService,
|
||||
|
||||
+10
-10
@@ -1,18 +1,18 @@
|
||||
export enum TokenType {
|
||||
ACCESS,
|
||||
REFRESH,
|
||||
ACCESS = 'ACCESS',
|
||||
REFRESH = 'REFRESH',
|
||||
}
|
||||
|
||||
export enum AccountType {
|
||||
PARTNER,
|
||||
BUSINESS,
|
||||
ADMIN,
|
||||
PROVIDER,
|
||||
POS,
|
||||
PARTNER = 'PARTNER',
|
||||
BUSINESS = 'BUSINESS',
|
||||
ADMIN = 'ADMIN',
|
||||
PROVIDER = 'PROVIDER',
|
||||
POS = 'POS',
|
||||
}
|
||||
|
||||
export enum GoldKarat {
|
||||
KARAT_18 = 18,
|
||||
KARAT_21 = 21,
|
||||
KARAT_24 = 24,
|
||||
KARAT_18 = '18',
|
||||
KARAT_21 = '21',
|
||||
KARAT_24 = '24',
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@ import {
|
||||
HttpStatus,
|
||||
} from '@nestjs/common'
|
||||
import type { Request, Response } from 'express'
|
||||
import { Prisma } from '../../generated/prisma/client'
|
||||
import { Prisma } from 'generated/prisma/client'
|
||||
|
||||
@Catch()
|
||||
export class PrismaExceptionFilter implements ExceptionFilter {
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
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')
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
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> {
|
||||
console.log('asd')
|
||||
|
||||
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')
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -76,12 +76,12 @@ export class ResponseMappingInterceptor implements NestInterceptor {
|
||||
break
|
||||
case 'list':
|
||||
payload = Array.isArray(wrapped.items) ? wrapped.items : []
|
||||
meta = {
|
||||
totalRecords: payload.length,
|
||||
totalPages: 1,
|
||||
page: 1,
|
||||
perPage: payload.length,
|
||||
}
|
||||
// meta = {
|
||||
// totalRecords: payload.length,
|
||||
// totalPages: 1,
|
||||
// page: 1,
|
||||
// perPage: payload.length,
|
||||
// }
|
||||
break
|
||||
case 'paginate': {
|
||||
const items = Array.isArray(wrapped.items) ? wrapped.items : []
|
||||
@@ -193,7 +193,7 @@ export class ResponseMappingInterceptor implements NestInterceptor {
|
||||
}
|
||||
}
|
||||
|
||||
if (meta)
|
||||
if (meta || ['list', 'paginate'].includes((data as any).__mapped))
|
||||
return {
|
||||
data: data.items,
|
||||
meta,
|
||||
|
||||
@@ -5,10 +5,17 @@
|
||||
* the global `ResponseMappingInterceptor` understands and normalizes.
|
||||
*/
|
||||
export type MapperWrapper<T> =
|
||||
| { __mapped: 'create' | 'update' | 'single' | 'delete'; data: T }
|
||||
| { __mapped: 'create' | 'update' | 'single'; data: T }
|
||||
| { __mapped: 'list'; items: T[] }
|
||||
| { __mapped: 'paginate'; items: T[]; total: number; page?: number; perPage?: number }
|
||||
| { __mapped: 'paginate'; items: T[]; count: number; page?: number; pageSize?: number }
|
||||
| { __mapped: 'sequelize'; rows: T[]; count: number; page?: number; perPage?: number }
|
||||
| { __mapped: 'delete' }
|
||||
|
||||
interface IPaginateMeta {
|
||||
count: number
|
||||
page?: number
|
||||
pageSize?: number
|
||||
}
|
||||
|
||||
export const ResponseMapper = {
|
||||
create<T>(item: T): MapperWrapper<T> {
|
||||
@@ -23,20 +30,20 @@ export const ResponseMapper = {
|
||||
return { __mapped: 'single', data: item }
|
||||
},
|
||||
|
||||
delete<T>(item: T): MapperWrapper<T> {
|
||||
return { __mapped: 'delete', data: item }
|
||||
delete(): MapperWrapper<boolean> {
|
||||
return { __mapped: 'delete' }
|
||||
},
|
||||
|
||||
list<T>(items: T[]): MapperWrapper<T> {
|
||||
return { __mapped: 'list', items }
|
||||
},
|
||||
|
||||
paginate<T>(items: T[], total: number, page = 1, perPage = items.length) {
|
||||
return { __mapped: 'paginate', items, total, page, perPage }
|
||||
paginate<T>(items: T[], { count, page = 1, pageSize: perPage }: IPaginateMeta) {
|
||||
return { __mapped: 'paginate', items, count, page, perPage }
|
||||
},
|
||||
|
||||
sequelizePaginate<T>(rows: T[], count: number, page = 1, perPage = rows.length) {
|
||||
return { __mapped: 'sequelize', rows, count, page, perPage }
|
||||
sequelizePaginate<T>(rows: T[], count: number, page = 1, pageSize = rows.length) {
|
||||
return { __mapped: 'sequelize', rows, count, page, pageSize }
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
import { UnauthorizedException } from '@nestjs/common'
|
||||
import { JwtService } from '@nestjs/jwt'
|
||||
import { Request } from 'express'
|
||||
import { AccessTokenPayload } from 'modules/auth/models'
|
||||
|
||||
export function getAccountIdFromJwt(req: Request, jwtService: JwtService): string | null {
|
||||
// Try to get token from Authorization header
|
||||
|
||||
let token = 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 accessToken cookie')
|
||||
|
||||
// const token = authHeader.replace('Bearer ', '')
|
||||
try {
|
||||
const payload = jwtService.decode(token) as AccessTokenPayload
|
||||
console.log(payload)
|
||||
|
||||
return payload?.account_id || null
|
||||
} catch {
|
||||
return null
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
import * as bcrypt from 'bcrypt'
|
||||
|
||||
export class PasswordUtil {
|
||||
static async hash(password: string, saltRounds = 10): Promise<string> {
|
||||
return bcrypt.hash(password, saltRounds)
|
||||
}
|
||||
|
||||
static async compare(password: string, hashedPassword: string): Promise<boolean> {
|
||||
return bcrypt.compare(password, hashedPassword)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user