feat: add field validators for username and password, and integrate them into DTOs
This commit is contained in:
@@ -0,0 +1,14 @@
|
|||||||
|
import { Matches, MinLength } from 'class-validator'
|
||||||
|
|
||||||
|
const MIN_LENGTH = 6
|
||||||
|
const REGEX = /^[a-zA-Z0-9]*$/
|
||||||
|
|
||||||
|
export const FiscalIdFieldValidator = () =>
|
||||||
|
function (target: object, propertyKey: string) {
|
||||||
|
MinLength(MIN_LENGTH, {
|
||||||
|
message: `شناسه یکتا باید حداقل ${MIN_LENGTH} کاراکتر باشد`,
|
||||||
|
})(target, propertyKey)
|
||||||
|
Matches(REGEX, {
|
||||||
|
message: 'شناسه یکتا فقط میتواند شامل حروف و اعداد باشد',
|
||||||
|
})(target, propertyKey)
|
||||||
|
}
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
export { FiscalIdFieldValidator } from './fiscalId-validator'
|
||||||
|
export { PasswordFieldValidator, PASSWORD_MIN_LENGTH } from './password'
|
||||||
|
export { UsernameFieldValidator } from './username'
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
import { MinLength } from 'class-validator'
|
||||||
|
|
||||||
|
export const PASSWORD_MIN_LENGTH = 6
|
||||||
|
|
||||||
|
export const PasswordFieldValidator = () =>
|
||||||
|
function (target: object, propertyKey: string) {
|
||||||
|
MinLength(PASSWORD_MIN_LENGTH, {
|
||||||
|
message: `رمز عبور باید حداقل ${PASSWORD_MIN_LENGTH} کاراکتر باشد`,
|
||||||
|
})(target, propertyKey)
|
||||||
|
}
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
import { Matches, MinLength } from 'class-validator'
|
||||||
|
|
||||||
|
const USERNAME_REGEX = /^[a-zA-Z0-9_-]*$/
|
||||||
|
const USERNAME_MIN_LENGTH = 6
|
||||||
|
|
||||||
|
export const UsernameFieldValidator = () =>
|
||||||
|
function (target: object, propertyKey: string) {
|
||||||
|
MinLength(USERNAME_MIN_LENGTH, {
|
||||||
|
message: `نام کاربری باید حداقل ${USERNAME_MIN_LENGTH} کاراکتر باشد`,
|
||||||
|
})(target, propertyKey)
|
||||||
|
Matches(USERNAME_REGEX, {
|
||||||
|
message: 'نام کاربری فقط میتواند شامل حروف، اعداد، زیرخط و خط تیره باشد',
|
||||||
|
})(target, propertyKey)
|
||||||
|
}
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
export * from './enum-translator.util'
|
export * from './enum-translator.util'
|
||||||
|
export * from './field-validator.util'
|
||||||
export * from './http-client.util'
|
export * from './http-client.util'
|
||||||
export * from './jwt-user.util'
|
export * from './jwt-user.util'
|
||||||
export * from './mappers/consumer_mappers.util'
|
export * from './mappers/consumer_mappers.util'
|
||||||
|
|||||||
@@ -1,13 +1,16 @@
|
|||||||
|
import { PasswordFieldValidator, UsernameFieldValidator } from '@/common/utils'
|
||||||
import { ApiProperty, PartialType } from '@nestjs/swagger'
|
import { ApiProperty, PartialType } from '@nestjs/swagger'
|
||||||
import { IsEnum, IsOptional, IsString } from 'class-validator'
|
import { IsEnum, IsOptional, IsString } from 'class-validator'
|
||||||
import { AccountStatus, ConsumerRole } from 'generated/prisma/enums'
|
import { AccountStatus, ConsumerRole } from 'generated/prisma/enums'
|
||||||
|
|
||||||
export class CreateConsumerAccountDto {
|
export class CreateConsumerAccountDto {
|
||||||
@IsString()
|
@IsString()
|
||||||
|
@UsernameFieldValidator()
|
||||||
@ApiProperty({ required: true })
|
@ApiProperty({ required: true })
|
||||||
username: string
|
username: string
|
||||||
|
|
||||||
@IsString()
|
@IsString()
|
||||||
|
@PasswordFieldValidator()
|
||||||
@ApiProperty({ required: true })
|
@ApiProperty({ required: true })
|
||||||
password: string
|
password: string
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import { PasswordFieldValidator, UsernameFieldValidator } from '@/common/utils'
|
||||||
import { ConsumerStatus } from '@/generated/prisma/enums'
|
import { ConsumerStatus } from '@/generated/prisma/enums'
|
||||||
import { ApiProperty, OmitType, PartialType } from '@nestjs/swagger'
|
import { ApiProperty, OmitType, PartialType } from '@nestjs/swagger'
|
||||||
import { IsEnum, IsOptional, IsString } from 'class-validator'
|
import { IsEnum, IsOptional, IsString } from 'class-validator'
|
||||||
@@ -16,10 +17,12 @@ export class CreateConsumerDto {
|
|||||||
last_name: string
|
last_name: string
|
||||||
|
|
||||||
@IsString()
|
@IsString()
|
||||||
|
@UsernameFieldValidator()
|
||||||
@ApiProperty({ required: true })
|
@ApiProperty({ required: true })
|
||||||
username: string
|
username: string
|
||||||
|
|
||||||
@IsString()
|
@IsString()
|
||||||
|
@PasswordFieldValidator()
|
||||||
@ApiProperty({ required: true })
|
@ApiProperty({ required: true })
|
||||||
password: string
|
password: string
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import { PasswordFieldValidator, UsernameFieldValidator } from '@/common/utils'
|
||||||
import { PartnerStatus, TspProviderType } from '@/generated/prisma/enums'
|
import { PartnerStatus, TspProviderType } from '@/generated/prisma/enums'
|
||||||
import { ApiProperty, PartialType } from '@nestjs/swagger'
|
import { ApiProperty, PartialType } from '@nestjs/swagger'
|
||||||
import { IsEnum, IsNumber, IsOptional, IsString } from 'class-validator'
|
import { IsEnum, IsNumber, IsOptional, IsString } from 'class-validator'
|
||||||
@@ -21,10 +22,12 @@ export class CreatePartnerDto {
|
|||||||
// license_quota?: number
|
// license_quota?: number
|
||||||
|
|
||||||
@IsString()
|
@IsString()
|
||||||
|
@UsernameFieldValidator()
|
||||||
@ApiProperty({ required: true })
|
@ApiProperty({ required: true })
|
||||||
username: string
|
username: string
|
||||||
|
|
||||||
@IsString()
|
@IsString()
|
||||||
|
@PasswordFieldValidator()
|
||||||
@ApiProperty({ required: true })
|
@ApiProperty({ required: true })
|
||||||
password: string
|
password: string
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import { PasswordFieldValidator, UsernameFieldValidator } from '@/common/utils'
|
||||||
import { ApiProperty, PartialType } from '@nestjs/swagger'
|
import { ApiProperty, PartialType } from '@nestjs/swagger'
|
||||||
import { IsEnum, IsOptional, IsString } from 'class-validator'
|
import { IsEnum, IsOptional, IsString } from 'class-validator'
|
||||||
import { PartnerRole } from 'generated/prisma/enums'
|
import { PartnerRole } from 'generated/prisma/enums'
|
||||||
@@ -5,9 +6,11 @@ import { PartnerRole } from 'generated/prisma/enums'
|
|||||||
export class CreatePartnerAccountDto {
|
export class CreatePartnerAccountDto {
|
||||||
@IsString()
|
@IsString()
|
||||||
@ApiProperty({})
|
@ApiProperty({})
|
||||||
|
@UsernameFieldValidator()
|
||||||
username: string
|
username: string
|
||||||
|
|
||||||
@IsString()
|
@IsString()
|
||||||
|
@PasswordFieldValidator()
|
||||||
@ApiProperty({})
|
@ApiProperty({})
|
||||||
password: string
|
password: string
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,13 +1,16 @@
|
|||||||
|
import { PasswordFieldValidator, UsernameFieldValidator } from '@/common/utils'
|
||||||
import { ApiProperty, PartialType } from '@nestjs/swagger'
|
import { ApiProperty, PartialType } from '@nestjs/swagger'
|
||||||
import { IsEnum, IsOptional, IsString } from 'class-validator'
|
import { IsEnum, IsOptional, IsString } from 'class-validator'
|
||||||
import { AccountStatus, AccountType } from 'generated/prisma/enums'
|
import { AccountStatus, AccountType } from 'generated/prisma/enums'
|
||||||
|
|
||||||
export class CreateAccountDto {
|
export class CreateAccountDto {
|
||||||
@IsString()
|
@IsString()
|
||||||
|
@UsernameFieldValidator()
|
||||||
@ApiProperty()
|
@ApiProperty()
|
||||||
username: string
|
username: string
|
||||||
|
|
||||||
@IsString()
|
@IsString()
|
||||||
|
@PasswordFieldValidator()
|
||||||
@ApiProperty()
|
@ApiProperty()
|
||||||
password: string
|
password: string
|
||||||
|
|
||||||
|
|||||||
@@ -2,11 +2,14 @@ import { ApiProperty } from '@nestjs/swagger'
|
|||||||
import { IsBoolean, IsOptional, IsString } from 'class-validator'
|
import { IsBoolean, IsOptional, IsString } from 'class-validator'
|
||||||
|
|
||||||
export class LoginDto {
|
export class LoginDto {
|
||||||
@ApiProperty({ description: 'Mobile number used as username', example: '09120258156' })
|
@ApiProperty({
|
||||||
|
description: 'you can use your mobile number as username',
|
||||||
|
example: '09120258156',
|
||||||
|
})
|
||||||
@IsString()
|
@IsString()
|
||||||
username: string
|
username: string
|
||||||
|
|
||||||
@ApiProperty({ description: 'OTP password (one-time password)', example: '11111' })
|
@ApiProperty({ example: '11111' })
|
||||||
@IsString()
|
@IsString()
|
||||||
password: string
|
password: string
|
||||||
|
|
||||||
|
|||||||
@@ -52,20 +52,14 @@ export class CatalogsService {
|
|||||||
|
|
||||||
async getSKU(search: string) {
|
async getSKU(search: string) {
|
||||||
const items = await this.prisma.stockKeepingUnits.findMany({
|
const items = await this.prisma.stockKeepingUnits.findMany({
|
||||||
// where: {
|
|
||||||
// OR: [{ code: { contains: search } }, { name: { contains: search } }],
|
|
||||||
// },
|
|
||||||
select: {
|
|
||||||
id: true,
|
|
||||||
code: true,
|
|
||||||
name: true,
|
|
||||||
is_domestic: true,
|
|
||||||
is_public: true,
|
|
||||||
VAT: true,
|
|
||||||
},
|
|
||||||
take: 100,
|
take: 100,
|
||||||
})
|
})
|
||||||
return ResponseMapper.list(items)
|
|
||||||
|
const mappedItems = items.map(item => ({
|
||||||
|
...item,
|
||||||
|
fullname: `${item.code} - ${item.name}`,
|
||||||
|
}))
|
||||||
|
return ResponseMapper.list(mappedItems)
|
||||||
}
|
}
|
||||||
|
|
||||||
async getGuildGoodCategories(guild_id: string) {
|
async getGuildGoodCategories(guild_id: string) {
|
||||||
|
|||||||
@@ -1,13 +1,16 @@
|
|||||||
|
import { PasswordFieldValidator, UsernameFieldValidator } from '@/common/utils'
|
||||||
import { ApiProperty, PartialType } from '@nestjs/swagger'
|
import { ApiProperty, PartialType } from '@nestjs/swagger'
|
||||||
import { IsEnum, IsOptional, IsString } from 'class-validator'
|
import { IsEnum, IsOptional, IsString } from 'class-validator'
|
||||||
import { AccountStatus } from 'generated/prisma/enums'
|
import { AccountStatus } from 'generated/prisma/enums'
|
||||||
|
|
||||||
export class CreateConsumerAccountDto {
|
export class CreateConsumerAccountDto {
|
||||||
@IsString()
|
@IsString()
|
||||||
|
@UsernameFieldValidator()
|
||||||
@ApiProperty({ required: true })
|
@ApiProperty({ required: true })
|
||||||
username: string
|
username: string
|
||||||
|
|
||||||
@IsString()
|
@IsString()
|
||||||
|
@PasswordFieldValidator()
|
||||||
@ApiProperty({ required: true })
|
@ApiProperty({ required: true })
|
||||||
password: string
|
password: string
|
||||||
|
|
||||||
|
|||||||
@@ -1,13 +1,16 @@
|
|||||||
|
import { PasswordFieldValidator, UsernameFieldValidator } from '@/common/utils'
|
||||||
import { ApiProperty, PartialType } from '@nestjs/swagger'
|
import { ApiProperty, PartialType } from '@nestjs/swagger'
|
||||||
import { IsEnum, IsOptional, IsString } from 'class-validator'
|
import { IsEnum, IsOptional, IsString } from 'class-validator'
|
||||||
import { AccountStatus, ConsumerRole } from 'generated/prisma/enums'
|
import { AccountStatus, ConsumerRole } from 'generated/prisma/enums'
|
||||||
|
|
||||||
export class CreateConsumerAccountDto {
|
export class CreateConsumerAccountDto {
|
||||||
@IsString()
|
@IsString()
|
||||||
|
@UsernameFieldValidator()
|
||||||
@ApiProperty({ required: true })
|
@ApiProperty({ required: true })
|
||||||
username: string
|
username: string
|
||||||
|
|
||||||
@IsString()
|
@IsString()
|
||||||
|
@PasswordFieldValidator()
|
||||||
@ApiProperty({ required: true })
|
@ApiProperty({ required: true })
|
||||||
password: string
|
password: string
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,12 @@
|
|||||||
import { RedisKeyMaker } from '@/common/utils'
|
import { RedisKeyMaker } from '@/common/utils'
|
||||||
import { BusinessActivitySelect } from '@/generated/prisma/models'
|
import {
|
||||||
|
BusinessActivityCreateInput,
|
||||||
|
BusinessActivitySelect,
|
||||||
|
} from '@/generated/prisma/models'
|
||||||
import { getPartnerFirstRemainingLicense } from '@/modules/partners/utils/getPartnerRemainingLicenses.util'
|
import { getPartnerFirstRemainingLicense } from '@/modules/partners/utils/getPartnerRemainingLicenses.util'
|
||||||
import { PrismaService } from '@/prisma/prisma.service'
|
import { PrismaService } from '@/prisma/prisma.service'
|
||||||
import { RedisService } from '@/redis/redis.service'
|
import { RedisService } from '@/redis/redis.service'
|
||||||
import { BadRequestException, Injectable } from '@nestjs/common'
|
import { Injectable } from '@nestjs/common'
|
||||||
import { ResponseMapper } from 'common/response/response-mapper'
|
import { ResponseMapper } from 'common/response/response-mapper'
|
||||||
import { PartnersCacheInvalidationService } from '../../cache/partners-cache-invalidation.service'
|
import { PartnersCacheInvalidationService } from '../../cache/partners-cache-invalidation.service'
|
||||||
import { CreateBusinessActivitiesDto } from './dto/create-business-activities.dto'
|
import { CreateBusinessActivitiesDto } from './dto/create-business-activities.dto'
|
||||||
@@ -158,6 +161,37 @@ export class BusinessActivitiesService {
|
|||||||
const license = await getPartnerFirstRemainingLicense(tx, { partner_id })
|
const license = await getPartnerFirstRemainingLicense(tx, { partner_id })
|
||||||
|
|
||||||
const { guild_id, license_starts_at, expires_at, ...rest } = data
|
const { guild_id, license_starts_at, expires_at, ...rest } = data
|
||||||
|
|
||||||
|
const dataToCreate: BusinessActivityCreateInput = {
|
||||||
|
...rest,
|
||||||
|
economic_code: String(data.economic_code),
|
||||||
|
guild: {
|
||||||
|
connect: {
|
||||||
|
id: guild_id,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
consumer: {
|
||||||
|
connect: {
|
||||||
|
id: consumer_id,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
if (license_starts_at) {
|
||||||
|
dataToCreate.license_activation = {
|
||||||
|
create: {
|
||||||
|
starts_at: license_starts_at ?? new Date(),
|
||||||
|
expires_at:
|
||||||
|
expires_at ?? this.setExpireDate(new Date(license_starts_at || '')),
|
||||||
|
license: {
|
||||||
|
connect: {
|
||||||
|
id: license.id,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const createdBusinessActivity = await tx.businessActivity.create({
|
const createdBusinessActivity = await tx.businessActivity.create({
|
||||||
data: {
|
data: {
|
||||||
...rest,
|
...rest,
|
||||||
@@ -196,25 +230,23 @@ export class BusinessActivitiesService {
|
|||||||
})
|
})
|
||||||
|
|
||||||
const activationId = createdBusinessActivity.license_activation?.id
|
const activationId = createdBusinessActivity.license_activation?.id
|
||||||
if (!activationId) {
|
if (activationId) {
|
||||||
throw new BadRequestException('لایسنس برای این فعالیت تجاری ایجاد نشد.')
|
const licenseAllocationCreation = Array.from({
|
||||||
}
|
length: license.accounts_limit,
|
||||||
|
}).map(() =>
|
||||||
const licenseAllocationCreation = Array.from({
|
tx.licenseAccountAllocation.create({
|
||||||
length: license.accounts_limit,
|
data: {
|
||||||
}).map(() =>
|
license_activation: {
|
||||||
tx.licenseAccountAllocation.create({
|
connect: {
|
||||||
data: {
|
id: activationId,
|
||||||
license_activation: {
|
},
|
||||||
connect: {
|
|
||||||
id: activationId,
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
}),
|
||||||
}),
|
)
|
||||||
)
|
|
||||||
|
|
||||||
await Promise.all(licenseAllocationCreation)
|
await Promise.all(licenseAllocationCreation)
|
||||||
|
}
|
||||||
|
|
||||||
return tx.businessActivity.findUniqueOrThrow({
|
return tx.businessActivity.findUniqueOrThrow({
|
||||||
where: {
|
where: {
|
||||||
|
|||||||
+9
-1
@@ -1,5 +1,6 @@
|
|||||||
|
import { FiscalIdFieldValidator } from '@/common/utils'
|
||||||
import { ApiProperty, PartialType } from '@nestjs/swagger'
|
import { ApiProperty, PartialType } from '@nestjs/swagger'
|
||||||
import { IsDateString, IsOptional, IsString } from 'class-validator'
|
import { IsDateString, IsNumber, IsOptional, IsString, Max, Min } from 'class-validator'
|
||||||
|
|
||||||
export class CreateBusinessActivitiesDto {
|
export class CreateBusinessActivitiesDto {
|
||||||
@IsString()
|
@IsString()
|
||||||
@@ -11,6 +12,7 @@ export class CreateBusinessActivitiesDto {
|
|||||||
economic_code: string
|
economic_code: string
|
||||||
|
|
||||||
@IsString()
|
@IsString()
|
||||||
|
@FiscalIdFieldValidator()
|
||||||
@ApiProperty({ required: true })
|
@ApiProperty({ required: true })
|
||||||
fiscal_id: string
|
fiscal_id: string
|
||||||
|
|
||||||
@@ -22,6 +24,12 @@ export class CreateBusinessActivitiesDto {
|
|||||||
@ApiProperty({ required: true })
|
@ApiProperty({ required: true })
|
||||||
guild_id: string
|
guild_id: string
|
||||||
|
|
||||||
|
@ApiProperty({ required: false, default: '1' })
|
||||||
|
@IsNumber()
|
||||||
|
@Min(0)
|
||||||
|
@Max(1_000_000_000)
|
||||||
|
invoice_number_sequence: number
|
||||||
|
|
||||||
@IsDateString()
|
@IsDateString()
|
||||||
@IsOptional()
|
@IsOptional()
|
||||||
@ApiProperty({ required: false })
|
@ApiProperty({ required: false })
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import { PasswordFieldValidator, UsernameFieldValidator } from '@/common/utils'
|
||||||
import { ConsumerIndividual, ConsumerLegal } from '@/generated/prisma/client'
|
import { ConsumerIndividual, ConsumerLegal } from '@/generated/prisma/client'
|
||||||
import { ConsumerStatus, ConsumerType } from '@/generated/prisma/enums'
|
import { ConsumerStatus, ConsumerType } from '@/generated/prisma/enums'
|
||||||
import { ApiProperty, OmitType, PartialType } from '@nestjs/swagger'
|
import { ApiProperty, OmitType, PartialType } from '@nestjs/swagger'
|
||||||
@@ -9,10 +10,12 @@ export class CreateConsumerDto {
|
|||||||
type: ConsumerType
|
type: ConsumerType
|
||||||
|
|
||||||
@IsString()
|
@IsString()
|
||||||
|
@UsernameFieldValidator()
|
||||||
@ApiProperty({ required: true })
|
@ApiProperty({ required: true })
|
||||||
username: string
|
username: string
|
||||||
|
|
||||||
@IsString()
|
@IsString()
|
||||||
|
@PasswordFieldValidator()
|
||||||
@ApiProperty({ required: true })
|
@ApiProperty({ required: true })
|
||||||
password: string
|
password: string
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user