diff options
Diffstat (limited to 'lib/users/auth')
| -rw-r--r-- | lib/users/auth/passwordUtil.ts | 83 |
1 files changed, 75 insertions, 8 deletions
diff --git a/lib/users/auth/passwordUtil.ts b/lib/users/auth/passwordUtil.ts index 4d5d69f6..e4090aee 100644 --- a/lib/users/auth/passwordUtil.ts +++ b/lib/users/auth/passwordUtil.ts @@ -786,21 +786,21 @@ export async function verifyEmailToken( ) ) .limit(1); - + if (!mfaToken[0]) { return { success: false, error: '잘못된 인증번호입니다' }; } - + // 만료 체크 if (mfaToken[0].expiresAt < new Date()) { await db .update(mfaTokens) .set({ isActive: false }) .where(eq(mfaTokens.id, mfaToken[0].id)); - + return { success: false, error: '인증번호가 만료되었습니다' }; } - + // 시도 횟수 증가 const newAttempts = mfaToken[0].attempts + 1; if (newAttempts > 3) { @@ -808,10 +808,10 @@ export async function verifyEmailToken( .update(mfaTokens) .set({ isActive: false }) .where(eq(mfaTokens.id, mfaToken[0].id)); - + return { success: false, error: '시도 횟수를 초과했습니다' }; } - + // 토큰 사용 처리 await db .update(mfaTokens) @@ -821,15 +821,82 @@ export async function verifyEmailToken( attempts: newAttempts, }) .where(eq(mfaTokens.id, mfaToken[0].id)); - + return { success: true }; - + } catch (error) { console.error('Email token verification error:', error); return { success: false, error: '인증 중 오류가 발생했습니다' }; } } +// ========== 입찰 공고 알림 SMS 전송 ========== + +// 입찰 공고 알림 SMS 템플릿 +const BIDDING_NOTICE_SMS_TEMPLATES = { + '82': '[입찰공고] {title} 입찰이 생성되었습니다. 확인 부탁드립니다.', // 한국 + '1': '[Bidding Notice] {title} bidding has been created. Please check.', // 미국 + '81': '[入札公告] {title} 入札が作成されました。ご確認ください。', // 일본 + '86': '[招标公告] {title} 投标已创建。请确认。', // 중국 + 'default': '[입찰공고] {title} 입찰이 생성되었습니다. 확인 부탁드립니다.' // 기본값 (한국어) +} as const; + +// 입찰 공고 알림용 SMS 메시지 생성 +function getBiddingNoticeSmsMessage(phoneNumber: string, title: string): string { + try { + const countryInfo = extractCountryInfo(phoneNumber); + if (!countryInfo) { + return BIDDING_NOTICE_SMS_TEMPLATES.default.replace('{title}', title); + } + + const template = BIDDING_NOTICE_SMS_TEMPLATES[countryInfo.countryCode as keyof typeof BIDDING_NOTICE_SMS_TEMPLATES] || BIDDING_NOTICE_SMS_TEMPLATES.default; + return template.replace('{title}', title); + } catch (error) { + return BIDDING_NOTICE_SMS_TEMPLATES.default.replace('{title}', title); // 에러 시 기본값 + } +} + +// 입찰 공고 알림 SMS 전송 +export async function sendBiddingNoticeSms( + phoneNumber: string, + biddingTitle: string +): Promise<{ success: boolean; error?: string }> { + try { + // 전화번호 유효성 검사 + if (!isValidPhoneNumber(phoneNumber)) { + console.log(`Invalid phone number format: ${phoneNumber}`); + return { success: false, error: '유효하지 않은 전화번호입니다' }; + } + + // 전화번호 정규화 + const normalizedPhone = normalizePhoneNumber(phoneNumber); + if (!normalizedPhone) { + console.log(`Failed to normalize phone number: ${phoneNumber}`); + return { success: false, error: '전화번호 형식이 올바르지 않습니다' }; + } + + // 메시지 생성 + const message = getBiddingNoticeSmsMessage(normalizedPhone, biddingTitle); + + console.log(`Sending bidding notice SMS to ${normalizedPhone}: ${message}`); + + // SMS 전송 + const smsResult = await sendSmsMessage(normalizedPhone, message); + + if (smsResult) { + console.log(`Bidding notice SMS sent successfully to ${normalizedPhone}`); + return { success: true }; + } else { + console.error(`Failed to send bidding notice SMS to ${normalizedPhone}`); + return { success: false, error: 'SMS 전송에 실패했습니다' }; + } + + } catch (error) { + console.error('Bidding notice SMS send error:', error); + return { success: false, error: 'SMS 전송 중 오류가 발생했습니다' }; + } +} + // 패스워드 강제 변경 필요 체크 export async function checkPasswordChangeRequired(userId: number): Promise<boolean> { const user = await db |
