update
This commit is contained in:
@@ -6,7 +6,8 @@
|
||||
"Bash(npm run migration:generate:*)",
|
||||
"Bash(npm run migration:run:*)",
|
||||
"Bash(npm run build:*)",
|
||||
"Bash(npx typeorm migration:generate:*)"
|
||||
"Bash(npx typeorm migration:generate:*)",
|
||||
"Bash(mkdir:*)"
|
||||
],
|
||||
"deny": []
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@ import { ConfigurationsModule } from './configurations/configurations.module';
|
||||
import { PosterAdModule } from './poster-ad/poster-ad.module';
|
||||
import { VideoAdModule } from './video-ad/video-ad.module';
|
||||
import { AdPositionModule } from './ad-position/ad-position.module';
|
||||
import { SmsService } from './sms.service';
|
||||
|
||||
@Module({
|
||||
imports: [
|
||||
@@ -64,6 +65,7 @@ import { AdPositionModule } from './ad-position/ad-position.module';
|
||||
AdPositionModule,
|
||||
],
|
||||
controllers: [AppController],
|
||||
providers: [AppService],
|
||||
providers: [AppService, SmsService],
|
||||
exports:[SmsService]
|
||||
})
|
||||
export class AppModule {}
|
||||
|
||||
@@ -8,15 +8,14 @@ import { ConfigModule, ConfigService } from '@nestjs/config';
|
||||
import { APP_GUARD } from '@nestjs/core';
|
||||
import { JwtAuthGuard } from './guard/jwt.guard';
|
||||
import { RolesGuard } from './guard/role.guard';
|
||||
import { TypeOrmModule } from '@nestjs/typeorm';
|
||||
import { Otp } from './entities/otp.entity';
|
||||
import { SmsService } from './sms.service';
|
||||
import { OtpModule } from 'src/otp/otp.module';
|
||||
import { SmsService } from 'src/sms.service';
|
||||
|
||||
@Module({
|
||||
imports: [
|
||||
UserModule,
|
||||
PassportModule,
|
||||
TypeOrmModule.forFeature([Otp]),
|
||||
OtpModule,
|
||||
JwtModule.registerAsync({
|
||||
imports: [ConfigModule],
|
||||
inject: [ConfigService],
|
||||
@@ -28,8 +27,8 @@ import { SmsService } from './sms.service';
|
||||
],
|
||||
controllers: [AuthController],
|
||||
providers: [
|
||||
AuthService,
|
||||
SmsService,
|
||||
AuthService,
|
||||
{
|
||||
provide: APP_GUARD,
|
||||
useClass: JwtAuthGuard,
|
||||
|
||||
@@ -11,16 +11,15 @@ import { ConfigService } from '@nestjs/config';
|
||||
import { User } from 'src/user/entities/user.entity';
|
||||
import { InjectRepository } from '@nestjs/typeorm';
|
||||
import { Repository, MoreThan } from 'typeorm';
|
||||
import { Otp } from './entities/otp.entity';
|
||||
import { SmsService } from './sms.service';
|
||||
import { SmsService } from '../sms.service';
|
||||
import { OtpService } from 'src/otp/otp.service';
|
||||
|
||||
@Injectable()
|
||||
export class AuthService {
|
||||
constructor(
|
||||
private readonly userService: UserService,
|
||||
private readonly jwtService: JwtService,
|
||||
@InjectRepository(Otp)
|
||||
private readonly otpRepository: Repository<Otp>,
|
||||
private readonly otpService: OtpService,
|
||||
private readonly smsService: SmsService,
|
||||
) {}
|
||||
|
||||
@@ -78,26 +77,14 @@ export class AuthService {
|
||||
// }
|
||||
|
||||
// Deactivate any existing active LOGIN OTPs for this phone number
|
||||
await this.otpRepository.update(
|
||||
{ phone_number: phone, purpose: 'LOGIN', isActive: true },
|
||||
{ isActive: false },
|
||||
);
|
||||
await this.otpService.invalidateOtps(phone, 'LOGIN')
|
||||
|
||||
const otpCode = Math.floor(100000 + Math.random() * 900000).toString();
|
||||
const expiresAt = new Date();
|
||||
expiresAt.setMinutes(expiresAt.getMinutes() + 5);
|
||||
|
||||
const otp = this.otpRepository.create({
|
||||
phone_number: phone,
|
||||
otp_code: otpCode,
|
||||
expires_at: expiresAt,
|
||||
is_verified: false,
|
||||
isActive: true,
|
||||
purpose: 'LOGIN',
|
||||
user: user ?? undefined, // Link to user if exists
|
||||
});
|
||||
const otp = this.otpService.generateOtp(phone, user??undefined)
|
||||
|
||||
await this.otpRepository.save(otp);
|
||||
|
||||
// Send SMS using the SMS service
|
||||
const smsSent = await this.smsService.sendOtp(phone, otpCode);
|
||||
@@ -115,26 +102,13 @@ export class AuthService {
|
||||
phone: string,
|
||||
otpCode: string,
|
||||
): Promise<{ message: string; token?: string }> {
|
||||
const otp = await this.otpRepository.findOne({
|
||||
where: {
|
||||
phone_number: phone,
|
||||
otp_code: otpCode,
|
||||
purpose: 'LOGIN',
|
||||
isActive: true,
|
||||
is_verified: false,
|
||||
expires_at: MoreThan(new Date()),
|
||||
},
|
||||
relations: ['user'],
|
||||
});
|
||||
const otp = await this.otpService.findValidOtp(phone, "LOGIN")
|
||||
|
||||
if (!otp) {
|
||||
throw new BadRequestException('Invalid or expired OTP');
|
||||
}
|
||||
|
||||
await this.otpRepository.update(otp.id, {
|
||||
is_verified: true,
|
||||
isActive: false,
|
||||
});
|
||||
await this.otpService.invalidateOtps(phone, "LOGIN")
|
||||
|
||||
// If linked to a real user, log them in with their actual data
|
||||
// Otherwise, create a viewer session
|
||||
@@ -168,30 +142,14 @@ export class AuthService {
|
||||
}
|
||||
|
||||
// Deactivate any existing verification OTPs
|
||||
await this.otpRepository.update(
|
||||
{ phone_number: phone, purpose: 'PHONE_VERIFICATION', isActive: true },
|
||||
{ isActive: false },
|
||||
);
|
||||
await this.otpService.invalidateOtps(phone, 'PHONE_VERIFICATION');
|
||||
|
||||
const otpCode = Math.floor(100000 + Math.random() * 900000).toString();
|
||||
const expiresAt = new Date();
|
||||
expiresAt.setMinutes(expiresAt.getMinutes() + 10);
|
||||
|
||||
const otp = this.otpRepository.create({
|
||||
phone_number: phone,
|
||||
otp_code: otpCode,
|
||||
expires_at: expiresAt,
|
||||
is_verified: false,
|
||||
isActive: true,
|
||||
purpose: 'PHONE_VERIFICATION',
|
||||
user,
|
||||
});
|
||||
const otp = await this.otpService.generateOtp(phone, user, 'PHONE_VERIFICATION')
|
||||
|
||||
await this.otpRepository.save(otp);
|
||||
|
||||
const smsSent = await this.smsService.sendOtp(phone, otpCode);
|
||||
const smsSent = await this.smsService.sendOtp(phone, otp);
|
||||
if (!smsSent) {
|
||||
console.log(`SMS failed, Verification OTP for ${phone}: ${otpCode}`);
|
||||
console.log(`SMS failed, Verification OTP for ${phone}: ${otp}`);
|
||||
return {
|
||||
message: 'Verification OTP generated but SMS delivery may have failed',
|
||||
};
|
||||
@@ -204,27 +162,14 @@ export class AuthService {
|
||||
phone: string,
|
||||
otpCode: string,
|
||||
): Promise<{ message: string; user?: any; token?: string }> {
|
||||
const otp = await this.otpRepository.findOne({
|
||||
where: {
|
||||
phone_number: phone,
|
||||
otp_code: otpCode,
|
||||
purpose: 'PHONE_VERIFICATION',
|
||||
isActive: true,
|
||||
is_verified: false,
|
||||
expires_at: MoreThan(new Date()),
|
||||
},
|
||||
relations: ['user'],
|
||||
});
|
||||
const otp = await this.otpService.findValidOtp(phone, 'PHONE_VERIFICATION')
|
||||
|
||||
if (!otp || !otp.user) {
|
||||
throw new BadRequestException('Invalid or expired verification OTP');
|
||||
}
|
||||
|
||||
// Mark OTP as used
|
||||
await this.otpRepository.update(otp.id, {
|
||||
is_verified: true,
|
||||
isActive: false,
|
||||
});
|
||||
await this.otpService.invalidateOtps(phone, 'PHONE_VERIFICATION');
|
||||
|
||||
// Update user verification status
|
||||
await this.userService.updateUser(otp.user.id, { phone_verified: true });
|
||||
|
||||
11
src/otp/otp.module.ts
Normal file
11
src/otp/otp.module.ts
Normal file
@@ -0,0 +1,11 @@
|
||||
import { Module } from '@nestjs/common';
|
||||
import { TypeOrmModule } from '@nestjs/typeorm';
|
||||
import { OtpService } from './otp.service';
|
||||
import { Otp } from './entities/otp.entity';
|
||||
|
||||
@Module({
|
||||
imports: [TypeOrmModule.forFeature([Otp])],
|
||||
providers: [OtpService],
|
||||
exports: [OtpService],
|
||||
})
|
||||
export class OtpModule {}
|
||||
86
src/otp/otp.service.ts
Normal file
86
src/otp/otp.service.ts
Normal file
@@ -0,0 +1,86 @@
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { InjectRepository } from '@nestjs/typeorm';
|
||||
import { Repository } from 'typeorm';
|
||||
import { Otp } from './entities/otp.entity';
|
||||
import { User } from 'src/user/entities/user.entity';
|
||||
|
||||
@Injectable()
|
||||
export class OtpService {
|
||||
constructor(
|
||||
@InjectRepository(Otp)
|
||||
private otpRepository: Repository<Otp>,
|
||||
) {}
|
||||
|
||||
async generateOtp(phoneNumber: string, user?: User, purpose: string = 'LOGIN'): Promise<string> {
|
||||
const otpCode = Math.floor(100000 + Math.random() * 900000).toString();
|
||||
const expiresAt = new Date(Date.now() + 10 * 60 * 1000); // 10 minutes
|
||||
|
||||
await this.otpRepository.update(
|
||||
{ phone_number: phoneNumber, is_verified: false },
|
||||
{ isActive: false }
|
||||
);
|
||||
|
||||
const otp = this.otpRepository.create({
|
||||
phone_number: phoneNumber,
|
||||
otp_code: otpCode,
|
||||
expires_at: expiresAt,
|
||||
purpose,
|
||||
user,
|
||||
});
|
||||
|
||||
await this.otpRepository.save(otp);
|
||||
return otpCode;
|
||||
}
|
||||
|
||||
async verifyOtp(phoneNumber: string, otpCode: string, purpose: string = 'LOGIN'): Promise<Otp | null> {
|
||||
const otp = await this.otpRepository.findOne({
|
||||
where: {
|
||||
phone_number: phoneNumber,
|
||||
otp_code: otpCode,
|
||||
purpose,
|
||||
is_verified: false,
|
||||
isActive: true,
|
||||
},
|
||||
relations: ['user'],
|
||||
});
|
||||
|
||||
if (!otp) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (new Date() > otp.expires_at) {
|
||||
return null;
|
||||
}
|
||||
|
||||
otp.is_verified = true;
|
||||
await this.otpRepository.save(otp);
|
||||
|
||||
return otp;
|
||||
}
|
||||
|
||||
async invalidateOtps(phoneNumber: string, purpose?: string): Promise<void> {
|
||||
const whereCondition: any = {
|
||||
phone_number: phoneNumber,
|
||||
is_verified: false,
|
||||
isActive: true,
|
||||
};
|
||||
|
||||
if (purpose) {
|
||||
whereCondition.purpose = purpose;
|
||||
}
|
||||
|
||||
await this.otpRepository.update(whereCondition, { isActive: false });
|
||||
}
|
||||
|
||||
async findValidOtp(phoneNumber: string, purpose: string = 'LOGIN'): Promise<Otp | null> {
|
||||
return this.otpRepository.findOne({
|
||||
where: {
|
||||
phone_number: phoneNumber,
|
||||
purpose,
|
||||
is_verified: false,
|
||||
isActive: true,
|
||||
},
|
||||
relations: ['user'],
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -1,112 +0,0 @@
|
||||
import { NestFactory } from '@nestjs/core';
|
||||
import { AppModule } from '../app.module';
|
||||
import { AdStatus } from '../common/enums/ad-status.enum';
|
||||
import { AdType } from '../common/enums/ad-type';
|
||||
import { PosterAdService } from '../poster-ad/poster-ad.service';
|
||||
import { LineAdService } from '../line-ad/line-ad.service';
|
||||
import { VideoAdService } from '../video-ad/video-ad.service';
|
||||
import { AdCommentService } from '../ad-comments/ad-comments.service';
|
||||
import { UserService } from '../user/user.service';
|
||||
|
||||
async function bootstrap() {
|
||||
const app = await NestFactory.createApplicationContext(AppModule);
|
||||
|
||||
try {
|
||||
const posterAdService = app.get(PosterAdService);
|
||||
const lineAdService = app.get(LineAdService);
|
||||
const videoAdService = app.get(VideoAdService);
|
||||
const adCommentService = app.get(AdCommentService);
|
||||
const userService = app.get(UserService);
|
||||
|
||||
// Get reviewer user
|
||||
const editor = await userService.findByPhoneOrEmailWithPassword(
|
||||
'editor@paisaads.com',
|
||||
);
|
||||
if (!editor) {
|
||||
throw new Error('Reviewer user not found');
|
||||
}
|
||||
|
||||
// Get all ads in YET_TO_BE_PUBLISHED status
|
||||
const posterAds = await posterAdService.findAllByStatuses([
|
||||
AdStatus.YET_TO_BE_PUBLISHED,
|
||||
]);
|
||||
const lineAds = await lineAdService.findAllByStatuses([
|
||||
AdStatus.YET_TO_BE_PUBLISHED,
|
||||
]);
|
||||
const videoAds = await videoAdService.findAllByStatuses([
|
||||
AdStatus.YET_TO_BE_PUBLISHED,
|
||||
]);
|
||||
|
||||
console.log(`Found ${posterAds.length} poster ads to approve`);
|
||||
console.log(`Found ${lineAds.length} line ads to approve`);
|
||||
console.log(`Found ${videoAds.length} video ads to approve`);
|
||||
|
||||
// Approve poster ads
|
||||
for (const ad of posterAds) {
|
||||
await posterAdService.updateAdStatus(ad.id, AdStatus.YET_TO_BE_PUBLISHED);
|
||||
try {
|
||||
await adCommentService.create(
|
||||
{
|
||||
actionType: AdStatus.PUBLISHED,
|
||||
comment: 'Bulk approved by editor',
|
||||
adType: AdType.POSTER,
|
||||
posterAdId: ad.id,
|
||||
},
|
||||
editor.id,
|
||||
AdType.POSTER,
|
||||
);
|
||||
} catch (error) {
|
||||
console.error(`Error approving poster ad: ${ad.id}`, error);
|
||||
}
|
||||
console.log(`Approved poster ad: ${ad.id}`);
|
||||
}
|
||||
|
||||
// Approve line ads
|
||||
for (const ad of lineAds) {
|
||||
await lineAdService.updateAdStatus(ad.id, AdStatus.PUBLISHED);
|
||||
try {
|
||||
await adCommentService.create(
|
||||
{
|
||||
actionType: AdStatus.PUBLISHED,
|
||||
comment: 'Bulk approved by editor',
|
||||
adType: AdType.LINE,
|
||||
lineAdId: ad.id,
|
||||
},
|
||||
editor.id,
|
||||
AdType.LINE,
|
||||
);
|
||||
} catch (error) {
|
||||
console.error(`Error approving line ad: ${ad.id}`, error);
|
||||
}
|
||||
console.log(`Approved line ad: ${ad.id}`);
|
||||
}
|
||||
|
||||
// Approve video ads
|
||||
for (const ad of videoAds) {
|
||||
await videoAdService.updateAdStatus(ad.id, AdStatus.PUBLISHED);
|
||||
try {
|
||||
await adCommentService.create(
|
||||
{
|
||||
actionType: AdStatus.PUBLISHED,
|
||||
comment: 'Bulk published by editor',
|
||||
adType: AdType.VIDEO,
|
||||
videoAdId: ad.id,
|
||||
},
|
||||
editor.id,
|
||||
AdType.VIDEO,
|
||||
);
|
||||
} catch (error) {
|
||||
console.error(`Error approving video ad: ${ad.id}`, error);
|
||||
}
|
||||
console.log(`Approved video ad: ${ad.id}`);
|
||||
}
|
||||
|
||||
console.log('All ads have been approved successfully!');
|
||||
} catch (error) {
|
||||
console.error('Error approving ads:', error);
|
||||
} finally {
|
||||
await app.close();
|
||||
}
|
||||
}
|
||||
|
||||
bootstrap();
|
||||
@@ -1,112 +0,0 @@
|
||||
import { NestFactory } from '@nestjs/core';
|
||||
import { AppModule } from '../app.module';
|
||||
import { AdStatus } from '../common/enums/ad-status.enum';
|
||||
import { AdType } from '../common/enums/ad-type';
|
||||
import { PosterAdService } from '../poster-ad/poster-ad.service';
|
||||
import { LineAdService } from '../line-ad/line-ad.service';
|
||||
import { VideoAdService } from '../video-ad/video-ad.service';
|
||||
import { AdCommentService } from '../ad-comments/ad-comments.service';
|
||||
import { UserService } from '../user/user.service';
|
||||
|
||||
async function bootstrap() {
|
||||
const app = await NestFactory.createApplicationContext(AppModule);
|
||||
|
||||
try {
|
||||
const posterAdService = app.get(PosterAdService);
|
||||
const lineAdService = app.get(LineAdService);
|
||||
const videoAdService = app.get(VideoAdService);
|
||||
const adCommentService = app.get(AdCommentService);
|
||||
const userService = app.get(UserService);
|
||||
|
||||
// Get reviewer user
|
||||
const reviewer = await userService.findByPhoneOrEmailWithPassword(
|
||||
'reviewer@paisaads.com',
|
||||
);
|
||||
if (!reviewer) {
|
||||
throw new Error('Reviewer user not found');
|
||||
}
|
||||
|
||||
// Get all ads in FOR_REVIEW status
|
||||
const posterAds = await posterAdService.findAllByStatuses([
|
||||
AdStatus.FOR_REVIEW,
|
||||
]);
|
||||
const lineAds = await lineAdService.findAllByStatuses([
|
||||
AdStatus.FOR_REVIEW,
|
||||
]);
|
||||
const videoAds = await videoAdService.findAllByStatuses([
|
||||
AdStatus.FOR_REVIEW,
|
||||
]);
|
||||
|
||||
console.log(`Found ${posterAds.length} poster ads to approve`);
|
||||
console.log(`Found ${lineAds.length} line ads to approve`);
|
||||
console.log(`Found ${videoAds.length} video ads to approve`);
|
||||
|
||||
// Approve poster ads
|
||||
for (const ad of posterAds) {
|
||||
await posterAdService.updateAdStatus(ad.id, AdStatus.YET_TO_BE_PUBLISHED);
|
||||
try {
|
||||
await adCommentService.create(
|
||||
{
|
||||
actionType: AdStatus.YET_TO_BE_PUBLISHED,
|
||||
comment: 'Bulk approved by reviewer',
|
||||
adType: AdType.POSTER,
|
||||
posterAdId: ad.id,
|
||||
},
|
||||
reviewer.id,
|
||||
AdType.POSTER,
|
||||
);
|
||||
} catch (error) {
|
||||
console.error(`Error approving poster ad: ${ad.id}`, error);
|
||||
}
|
||||
console.log(`Approved poster ad: ${ad.id}`);
|
||||
}
|
||||
|
||||
// Approve line ads
|
||||
for (const ad of lineAds) {
|
||||
await lineAdService.updateAdStatus(ad.id, AdStatus.YET_TO_BE_PUBLISHED);
|
||||
try {
|
||||
await adCommentService.create(
|
||||
{
|
||||
actionType: AdStatus.YET_TO_BE_PUBLISHED,
|
||||
comment: 'Bulk approved by reviewer',
|
||||
adType: AdType.LINE,
|
||||
lineAdId: ad.id,
|
||||
},
|
||||
reviewer.id,
|
||||
AdType.LINE,
|
||||
);
|
||||
} catch (error) {
|
||||
console.error(`Error approving line ad: ${ad.id}`, error);
|
||||
}
|
||||
console.log(`Approved line ad: ${ad.id}`);
|
||||
}
|
||||
|
||||
// Approve video ads
|
||||
for (const ad of videoAds) {
|
||||
await videoAdService.updateAdStatus(ad.id, AdStatus.YET_TO_BE_PUBLISHED);
|
||||
try {
|
||||
await adCommentService.create(
|
||||
{
|
||||
actionType: AdStatus.YET_TO_BE_PUBLISHED,
|
||||
comment: 'Bulk approved by reviewer',
|
||||
adType: AdType.VIDEO,
|
||||
videoAdId: ad.id,
|
||||
},
|
||||
reviewer.id,
|
||||
AdType.VIDEO,
|
||||
);
|
||||
} catch (error) {
|
||||
console.error(`Error approving video ad: ${ad.id}`, error);
|
||||
}
|
||||
console.log(`Approved video ad: ${ad.id}`);
|
||||
}
|
||||
|
||||
console.log('All ads have been approved successfully!');
|
||||
} catch (error) {
|
||||
console.error('Error approving ads:', error);
|
||||
} finally {
|
||||
await app.close();
|
||||
}
|
||||
}
|
||||
|
||||
bootstrap();
|
||||
@@ -3,7 +3,7 @@ import { BaseEntity } from 'src/common/types/base-entity';
|
||||
import { Column, Entity, JoinColumn, OneToOne, OneToMany } from 'typeorm';
|
||||
import { Admin } from './admin.entity';
|
||||
import { Customer } from './customer.entity';
|
||||
import { Otp } from 'src/auth/entities/otp.entity';
|
||||
import { Otp } from 'src/otp/entities/otp.entity';
|
||||
|
||||
@Entity('users')
|
||||
export class User extends BaseEntity {
|
||||
|
||||
@@ -6,11 +6,14 @@ import { User } from './entities/user.entity';
|
||||
import { Admin } from './entities/admin.entity';
|
||||
import { Customer } from './entities/customer.entity';
|
||||
import { ImageModule } from 'src/image/image.module';
|
||||
import { SmsService } from 'src/sms.service';
|
||||
import { OtpService } from 'src/otp/otp.service';
|
||||
import { OtpModule } from 'src/otp/otp.module';
|
||||
|
||||
@Module({
|
||||
imports: [TypeOrmModule.forFeature([User, Admin, Customer]), ImageModule],
|
||||
imports: [TypeOrmModule.forFeature([User, Admin, Customer]), ImageModule,OtpModule],
|
||||
controllers: [UserController],
|
||||
providers: [UserService],
|
||||
providers: [UserService,SmsService],
|
||||
exports: [UserService],
|
||||
})
|
||||
export class UserModule {}
|
||||
|
||||
@@ -18,6 +18,8 @@ import * as bcrypt from 'bcrypt';
|
||||
import { Role } from 'src/common/enums/role.enum';
|
||||
import { CreateUserAndCustomerDto } from './dto/create-user-and-customer';
|
||||
import { UpdateCustomerDto } from './dto/update-customer';
|
||||
import { SmsService } from 'src/sms.service';
|
||||
import { OtpService } from 'src/otp/otp.service';
|
||||
|
||||
@Injectable()
|
||||
export class UserService {
|
||||
@@ -26,6 +28,8 @@ export class UserService {
|
||||
@InjectRepository(Customer) private customerRepo: Repository<Customer>,
|
||||
@InjectRepository(Admin) private adminRepo: Repository<Admin>,
|
||||
private imageService: ImageService,
|
||||
private smsService: SmsService,
|
||||
private otpService: OtpService,
|
||||
) {}
|
||||
|
||||
// Utility hashing
|
||||
@@ -82,39 +86,48 @@ export class UserService {
|
||||
// throw new BadRequestException('Proof image does not exist');
|
||||
// }
|
||||
|
||||
await this.userRepo.manager.transaction(async (manager) => {
|
||||
// Create user
|
||||
const hashed = await this.hashPassword(dto.password);
|
||||
const user = manager.create(User, {
|
||||
name: dto.name,
|
||||
email: dto.email,
|
||||
phone_number: dto.phone_number,
|
||||
secondary_number: dto.secondary_number,
|
||||
password: hashed,
|
||||
role: Role.USER,
|
||||
isActive: true,
|
||||
});
|
||||
console.log('user', user);
|
||||
const savedUser = await manager.save(User, user);
|
||||
let proof;
|
||||
if (dto.proof) {
|
||||
proof = await this.imageService.confirmImage(dto.proof);
|
||||
}
|
||||
try {
|
||||
await this.userRepo.manager.transaction(async (manager) => {
|
||||
// Create user
|
||||
const hashed = await this.hashPassword(dto.password);
|
||||
const user = manager.create(User, {
|
||||
name: dto.name,
|
||||
email: dto.email,
|
||||
phone_number: dto.phone_number,
|
||||
secondary_number: dto.secondary_number,
|
||||
password: hashed,
|
||||
role: Role.USER,
|
||||
isActive: true,
|
||||
});
|
||||
const savedUser = await manager.save(User, user);
|
||||
let proof;
|
||||
if (dto.proof) {
|
||||
proof = await this.imageService.confirmImage(dto.proof);
|
||||
}
|
||||
|
||||
// Create customer and link image
|
||||
const customer = manager.create(Customer, {
|
||||
country: dto.country,
|
||||
country_id: dto.country_id,
|
||||
state: dto.state,
|
||||
state_id: dto.state_id,
|
||||
city: dto.city,
|
||||
city_id: dto.city_id,
|
||||
gender: dto.gender,
|
||||
user: savedUser,
|
||||
proof: proof ?? undefined,
|
||||
// Create customer and link image
|
||||
const customer = manager.create(Customer, {
|
||||
country: dto.country,
|
||||
country_id: dto.country_id,
|
||||
state: dto.state,
|
||||
state_id: dto.state_id,
|
||||
city: dto.city,
|
||||
city_id: dto.city_id,
|
||||
gender: dto.gender,
|
||||
user: savedUser,
|
||||
proof: proof ?? undefined,
|
||||
});
|
||||
await manager.save(Customer, customer);
|
||||
const otp = await this.otpService.generateOtp(
|
||||
user.phone_number,
|
||||
user,
|
||||
'LOGIN',
|
||||
);
|
||||
await this.smsService.sendOtp(user.phone_number, otp);
|
||||
});
|
||||
await manager.save(Customer, customer);
|
||||
});
|
||||
} catch (exception) {
|
||||
throw new BadRequestException(exception);
|
||||
}
|
||||
}
|
||||
|
||||
// -- Getters
|
||||
|
||||
Reference in New Issue
Block a user