YARA-1075

This commit is contained in:
SepehrYahyaee
2026-07-01 12:11:19 +03:30
parent 493be68b80
commit f92cee0575

View File

@@ -2092,14 +2092,32 @@ export class RequestManagementService {
(req.parties[secondIdx].person as any).phoneNumber = phoneNumber;
}
// If a valid OTP is already active for this number, return 200 immediately —
// no duplicate SMS, no unnecessary write, no error shown to the expert.
const canonicalPhoneAdv = normalizeIranMobile(phoneNumber) ?? phoneNumber;
const existingUserAdv = await this.userDbService.findOne(
buildUserLookupByPhone(canonicalPhoneAdv),
);
if (existingUserAdv && isOtpExpiryActive(existingUserAdv.otpExpire)) {
return {
requestId: req._id,
publicId: req.publicId,
workflow: req.workflow,
message: `OTP already sent to ${phoneNumber} and is still valid. Collect the code and call verify-party-otp.`,
};
}
// Send OTP to second party — expert collects it from them in person
try {
await this.userAuthService.sendOtpRequest(phoneNumber);
} catch (e: any) {
if (e?.message?.includes("Wait for expiry")) {
throw new BadRequestException(
`(${phoneNumber}): OTP was recently sent. Wait for the expiry time before requesting again.`,
);
return {
requestId: req._id,
publicId: req.publicId,
workflow: req.workflow,
message: `OTP already sent to ${phoneNumber} and is still valid. Collect the code and call verify-party-otp.`,
};
}
throw e;
}
@@ -4548,29 +4566,32 @@ export class RequestManagementService {
);
}
const sent: string[] = [];
try {
await this.userAuthService.sendOtpRequest(dto.firstPartyPhoneNumber);
sent.push(dto.firstPartyPhoneNumber);
} catch (e: any) {
if (e?.message?.includes("Wait for expiry")) {
throw new BadRequestException(
`First party (${dto.firstPartyPhoneNumber}): OTP was recently sent. Wait for the expiry time before requesting again.`,
);
// Helper: send OTP or silently succeed when a valid OTP already exists.
const sendOrSkipIfActive = async (phone: string): Promise<void> => {
const canonical = normalizeIranMobile(phone) ?? phone;
const existing = await this.userDbService.findOne(
buildUserLookupByPhone(canonical),
);
if (existing && isOtpExpiryActive(existing.otpExpire)) {
sent.push(phone); // already has a live OTP — treat as sent
return;
}
throw e;
}
if (dto.secondPartyPhoneNumber) {
try {
await this.userAuthService.sendOtpRequest(dto.secondPartyPhoneNumber);
sent.push(dto.secondPartyPhoneNumber);
await this.userAuthService.sendOtpRequest(phone);
sent.push(phone);
} catch (e: any) {
if (e?.message?.includes("Wait for expiry")) {
throw new BadRequestException(
`Second party (${dto.secondPartyPhoneNumber}): OTP was recently sent. Wait for the expiry time before requesting again.`,
);
sent.push(phone); // race: sendOtpRequest found it active too — treat as sent
return;
}
throw e;
}
};
await sendOrSkipIfActive(dto.firstPartyPhoneNumber);
if (dto.secondPartyPhoneNumber) {
await sendOrSkipIfActive(dto.secondPartyPhoneNumber);
}
return {
sent: true,
@@ -4749,32 +4770,34 @@ export class RequestManagementService {
new Date(event.timestamp) > twoMinutesAgo,
);
if (recentlySentToPhone) {
throw new BadRequestException(
`(${phone}): OTP was sent recently. Please wait 2 minutes before requesting again.`,
);
return {
sent: true,
message: `OTP already sent to ${phone} and is still valid. Collect the code from the party, then call verify-party-otp.`,
};
}
// --- DB-level cooldown guard (catches burst/concurrent requests before history is saved) ---
// Read the user's otpExpire directly from the users collection. If a live
// OTP already exists we return 400 immediately — no SMS call, no DB writes.
const canonicalPhone =
normalizeIranMobile(phone) ?? phone;
// OTP already exists return 200 immediately — no duplicate SMS, no DB writes.
const canonicalPhone = normalizeIranMobile(phone) ?? phone;
const existingUser = await this.userDbService.findOne(
buildUserLookupByPhone(canonicalPhone),
);
if (existingUser && isOtpExpiryActive(existingUser.otpExpire)) {
throw new BadRequestException(
`(${phone}): OTP was sent recently. Please wait before requesting again.`,
);
return {
sent: true,
message: `OTP already sent to ${phone} and is still valid. Collect the code from the party, then call verify-party-otp.`,
};
}
try {
await this.userAuthService.sendOtpRequest(phone);
} catch (e: any) {
if (e?.message?.includes("Wait for expiry")) {
throw new BadRequestException(
`(${phone}): OTP was recently sent. Wait for the expiry time before requesting again.`,
);
return {
sent: true,
message: `OTP already sent to ${phone} and is still valid. Collect the code from the party, then call verify-party-otp.`,
};
}
throw e;
}