Merge branch 'development' of ssh://git.eigen.co.id:2222/eigen/pos-be into development
commit
033ed0046e
|
@ -38,6 +38,14 @@ export class OtpService {
|
||||||
return Object.values(counts).some((count) => count > 2);
|
return Object.values(counts).some((count) => count > 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private hasNoMatchLength(str: string) {
|
||||||
|
return str.length !== this.otpLength;
|
||||||
|
}
|
||||||
|
|
||||||
|
private hasStartWithZero(str: string) {
|
||||||
|
return str.split('')[0] === '0';
|
||||||
|
}
|
||||||
|
|
||||||
public generateSecureOTP(): string {
|
public generateSecureOTP(): string {
|
||||||
let otp: string;
|
let otp: string;
|
||||||
|
|
||||||
|
@ -46,11 +54,12 @@ export class OtpService {
|
||||||
Math.floor(Math.random() * 10).toString(),
|
Math.floor(Math.random() * 10).toString(),
|
||||||
).join('');
|
).join('');
|
||||||
} while (
|
} while (
|
||||||
|
this.hasNoMatchLength(otp) ||
|
||||||
this.hasSequentialDigits(otp) ||
|
this.hasSequentialDigits(otp) ||
|
||||||
this.hasRepeatedDigits(otp) ||
|
this.hasRepeatedDigits(otp) ||
|
||||||
this.isPalindrome(otp) ||
|
this.isPalindrome(otp) ||
|
||||||
this.hasPartiallyRepeatedDigits(otp) ||
|
this.hasPartiallyRepeatedDigits(otp) ||
|
||||||
otp?.length < this.otpLength
|
this.hasStartWithZero(otp)
|
||||||
);
|
);
|
||||||
return otp;
|
return otp;
|
||||||
}
|
}
|
||||||
|
|
|
@ -74,7 +74,9 @@ export class OtpVerificationService {
|
||||||
const createdAtMoment = moment(Number(activeOTP.created_at));
|
const createdAtMoment = moment(Number(activeOTP.created_at));
|
||||||
const nowMoment = moment(Number(dateNow));
|
const nowMoment = moment(Number(dateNow));
|
||||||
const diffSeconds = nowMoment.diff(createdAtMoment, 'seconds');
|
const diffSeconds = nowMoment.diff(createdAtMoment, 'seconds');
|
||||||
if (diffSeconds < 60) {
|
const isProduction = process.env.NODE_ENV === 'true';
|
||||||
|
|
||||||
|
if (diffSeconds < 60 && isProduction) {
|
||||||
throw new BadRequestException(
|
throw new BadRequestException(
|
||||||
'An active OTP request was made recently. Please try again later.',
|
'An active OTP request was made recently. Please try again later.',
|
||||||
);
|
);
|
||||||
|
@ -116,10 +118,13 @@ export class OtpVerificationService {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let otp: any;
|
||||||
|
|
||||||
// Build a where condition with OR between target_id and reference
|
// Build a where condition with OR between target_id and reference
|
||||||
const otp = await this.otpVerificationRepo.findOne({
|
|
||||||
where: [
|
if (target_id) {
|
||||||
{
|
otp = await this.otpVerificationRepo.findOne({
|
||||||
|
where: {
|
||||||
otp_code,
|
otp_code,
|
||||||
action_type,
|
action_type,
|
||||||
target_id,
|
target_id,
|
||||||
|
@ -127,7 +132,10 @@ export class OtpVerificationService {
|
||||||
is_used: false,
|
is_used: false,
|
||||||
is_replaced: false,
|
is_replaced: false,
|
||||||
},
|
},
|
||||||
{
|
});
|
||||||
|
} else if (reference) {
|
||||||
|
otp = await this.otpVerificationRepo.findOne({
|
||||||
|
where: {
|
||||||
otp_code,
|
otp_code,
|
||||||
action_type,
|
action_type,
|
||||||
reference,
|
reference,
|
||||||
|
@ -135,8 +143,8 @@ export class OtpVerificationService {
|
||||||
is_used: false,
|
is_used: false,
|
||||||
is_replaced: false,
|
is_replaced: false,
|
||||||
},
|
},
|
||||||
],
|
});
|
||||||
});
|
}
|
||||||
|
|
||||||
if (!otp) {
|
if (!otp) {
|
||||||
throw new BadRequestException('Invalid or expired OTP.');
|
throw new BadRequestException('Invalid or expired OTP.');
|
||||||
|
|
|
@ -15,6 +15,12 @@ import { TransactionEntity } from 'src/modules/transaction/transaction/domain/en
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class CancelReconciliationManager extends BaseUpdateStatusManager<TransactionEntity> {
|
export class CancelReconciliationManager extends BaseUpdateStatusManager<TransactionEntity> {
|
||||||
|
protected payloadBody: any;
|
||||||
|
|
||||||
|
setCustomBodyRequest(body) {
|
||||||
|
this.payloadBody = body;
|
||||||
|
}
|
||||||
|
|
||||||
getResult(): string {
|
getResult(): string {
|
||||||
return `Success active data ${this.result.id}`;
|
return `Success active data ${this.result.id}`;
|
||||||
}
|
}
|
||||||
|
@ -50,6 +56,7 @@ export class CancelReconciliationManager extends BaseUpdateStatusManager<Transac
|
||||||
async beforeProcess(): Promise<void> {
|
async beforeProcess(): Promise<void> {
|
||||||
if (this.data.is_recap_transaction) {
|
if (this.data.is_recap_transaction) {
|
||||||
Object.assign(this.data, {
|
Object.assign(this.data, {
|
||||||
|
otp_code: this.payloadBody?.otp_code,
|
||||||
reconciliation_confirm_by: null,
|
reconciliation_confirm_by: null,
|
||||||
reconciliation_confirm_date: null,
|
reconciliation_confirm_date: null,
|
||||||
reconciliation_status: STATUS.PENDING,
|
reconciliation_status: STATUS.PENDING,
|
||||||
|
@ -58,6 +65,7 @@ export class CancelReconciliationManager extends BaseUpdateStatusManager<Transac
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
Object.assign(this.data, {
|
Object.assign(this.data, {
|
||||||
|
otp_code: this.payloadBody?.otp_code,
|
||||||
reconciliation_mdr: this.data.reconciliation_mdr ?? null,
|
reconciliation_mdr: this.data.reconciliation_mdr ?? null,
|
||||||
reconciliation_confirm_by: this.user.name,
|
reconciliation_confirm_by: this.user.name,
|
||||||
reconciliation_confirm_date: new Date().getTime(),
|
reconciliation_confirm_date: new Date().getTime(),
|
||||||
|
@ -70,6 +78,7 @@ export class CancelReconciliationManager extends BaseUpdateStatusManager<Transac
|
||||||
: this.data.settlement_date,
|
: this.data.settlement_date,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -58,9 +58,10 @@ export class ReconciliationDataOrchestrator {
|
||||||
return this.batchConfirmManager.getResult();
|
return this.batchConfirmManager.getResult();
|
||||||
}
|
}
|
||||||
|
|
||||||
async cancel(dataId): Promise<string> {
|
async cancel(dataId, body): Promise<string> {
|
||||||
this.cancelManager.setData(dataId, STATUS.REJECTED);
|
this.cancelManager.setData(dataId, STATUS.REJECTED);
|
||||||
this.cancelManager.setService(this.serviceData, TABLE_NAME.TRANSACTION);
|
this.cancelManager.setService(this.serviceData, TABLE_NAME.TRANSACTION);
|
||||||
|
this.cancelManager.setCustomBodyRequest(body);
|
||||||
await this.cancelManager.execute();
|
await this.cancelManager.execute();
|
||||||
return this.cancelManager.getResult();
|
return this.cancelManager.getResult();
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,14 @@
|
||||||
|
import { ApiProperty } from '@nestjs/swagger';
|
||||||
|
import { IsNotEmpty, IsString } from 'class-validator';
|
||||||
|
|
||||||
|
export class OtpVerifyDto {
|
||||||
|
@ApiProperty({
|
||||||
|
name: 'otp_code',
|
||||||
|
type: String,
|
||||||
|
required: true,
|
||||||
|
example: '2345',
|
||||||
|
})
|
||||||
|
@IsString()
|
||||||
|
@IsNotEmpty()
|
||||||
|
otp_code: string;
|
||||||
|
}
|
|
@ -16,6 +16,7 @@ import { Public } from 'src/core/guards';
|
||||||
import { TransactionEntity } from '../../transaction/domain/entities/transaction.entity';
|
import { TransactionEntity } from '../../transaction/domain/entities/transaction.entity';
|
||||||
import { UpdateReconciliationDto } from './dto/reconciliation.dto';
|
import { UpdateReconciliationDto } from './dto/reconciliation.dto';
|
||||||
import { RecapReconciliationDto } from './dto/recap.dto';
|
import { RecapReconciliationDto } from './dto/recap.dto';
|
||||||
|
import { OtpVerifyDto } from './dto/cancel-top-dto';
|
||||||
|
|
||||||
@ApiTags(`${MODULE_NAME.RECONCILIATION.split('-').join(' ')} - data`)
|
@ApiTags(`${MODULE_NAME.RECONCILIATION.split('-').join(' ')} - data`)
|
||||||
@Controller(`v1/${MODULE_NAME.RECONCILIATION}`)
|
@Controller(`v1/${MODULE_NAME.RECONCILIATION}`)
|
||||||
|
@ -40,8 +41,11 @@ export class ReconciliationDataController {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Patch(':id/cancel')
|
@Patch(':id/cancel')
|
||||||
async cancel(@Param('id') dataId: string): Promise<string> {
|
async cancel(
|
||||||
return await this.orchestrator.cancel(dataId);
|
@Param('id') dataId: string,
|
||||||
|
@Body() body: OtpVerifyDto,
|
||||||
|
): Promise<string> {
|
||||||
|
return await this.orchestrator.cancel(dataId, body);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Put('/batch-cancel')
|
@Put('/batch-cancel')
|
||||||
|
|
Loading…
Reference in New Issue