summaryrefslogtreecommitdiff
path: root/lib/users
diff options
context:
space:
mode:
authordujinkim <dujin.kim@dtsolution.co.kr>2025-04-08 03:08:19 +0000
committerdujinkim <dujin.kim@dtsolution.co.kr>2025-04-08 03:08:19 +0000
commit9ceed79cf32c896f8a998399bf1b296506b2cd4a (patch)
treef84750fa6cac954d5e31221fc47a54c655fc06a9 /lib/users
parent230ce796836c25df26c130dbcd616ef97d12b2ec (diff)
로그인 및 미들웨어 처리. 구조 변경
Diffstat (limited to 'lib/users')
-rw-r--r--lib/users/send-otp.ts118
-rw-r--r--lib/users/verifyOtp.ts31
2 files changed, 96 insertions, 53 deletions
diff --git a/lib/users/send-otp.ts b/lib/users/send-otp.ts
index c8cfb83d..55c08eaf 100644
--- a/lib/users/send-otp.ts
+++ b/lib/users/send-otp.ts
@@ -7,65 +7,79 @@ import { findUserByEmail, addNewOtp } from '@/lib/users/service';
export async function sendOtpAction(email: string, lng: string) {
- // Next.js의 headers() API로 헤더 정보를 얻을 수 있습니다.
- const headersList = await headers();
- // 호스트 정보 (request.nextUrl.host 대체)
- const host = headersList.get('host') || 'localhost:3000';
+ try {
+ // Next.js의 headers() API로 헤더 정보를 얻을 수 있습니다.
+ const headersList = await headers();
- // 사용자 조회
- const user = await findUserByEmail(email);
+ // 호스트 정보 (request.nextUrl.host 대체)
+ const host = headersList.get('host') || 'localhost:3000';
- if (!user) {
- // 서버 액션에서 에러 던지면, 클라이언트 컴포넌트에서 try-catch로 잡을 수 있습니다.
- throw new Error('User does not exist');
- }
+ // 사용자 조회
+ const user = await findUserByEmail(email);
- // OTP 및 만료 시간 생성
- const otp = Math.floor(100000 + Math.random() * 900000).toString();
- const expires = new Date(Date.now() + 10 * 60 * 1000); // 10분 후 만료
- const token = jwt.sign(
- {
- email,
- otp,
- exp: Math.floor(expires.getTime() / 1000),
- },
- process.env.JWT_SECRET!
- );
+ if (!user) {
+ // Return error object instead of throwing
+ return {
+ success: false,
+ error: 'userNotFound',
+ message: 'User does not exist'
+ };
+ }
- // DB에 OTP 추가
- await addNewOtp(email, otp, new Date(), token, expires);
+ // OTP 및 만료 시간 생성
+ const otp = Math.floor(100000 + Math.random() * 900000).toString();
+ const expires = new Date(Date.now() + 10 * 60 * 1000); // 10분 후 만료
+ const token = jwt.sign(
+ {
+ email,
+ otp,
+ exp: Math.floor(expires.getTime() / 1000),
+ },
+ process.env.JWT_SECRET!
+ );
- // 이메일에서 사용할 URL 구성
- const verificationUrl = `http://${host}/ko/login?token=${token}`;
+ // DB에 OTP 추가
+ await addNewOtp(email, otp, new Date(), token, expires);
- // IP 정보로부터 지역 조회 (ip-api 사용)
- const ip = headersList.get('x-forwarded-for')?.split(',')[0]?.trim() || '';
- let location = '';
- try {
- const response = await fetch(`http://ip-api.com/json/${ip}?fields=country,city`);
- const data = await response.json();
- location = data.city && data.country ? `${data.city}, ${data.country}` : '';
- } catch (error) {
- // 위치 조회 실패 시 무시
- }
+ // 이메일에서 사용할 URL 구성
+ const verificationUrl = `http://${host}/ko/login?token=${token}`;
+
+ // IP 정보로부터 지역 조회 (ip-api 사용)
+ const ip = headersList.get('x-forwarded-for')?.split(',')[0]?.trim() || '';
+ let location = '';
+ try {
+ const response = await fetch(`http://ip-api.com/json/${ip}?fields=country,city`);
+ const data = await response.json();
+ location = data.city && data.country ? `${data.city}, ${data.country}` : '';
+ } catch (error) {
+ // 위치 조회 실패 시 무시
+ }
- // OTP 이메일 발송
- await sendEmail({
- to: email,
- subject: `${otp} - SHI eVCP Sign-in Verification`,
- template: 'otp',
- context: {
- name: user.name,
- otp,
- verificationUrl,
- location,
- language: lng,
- },
- });
+ // OTP 이메일 발송
+ await sendEmail({
+ to: email,
+ subject: `${otp} - SHI eVCP Sign-in Verification`,
+ template: 'otp',
+ context: {
+ name: user.name,
+ otp,
+ verificationUrl,
+ location,
+ language: lng,
+ },
+ });
- // 클라이언트로 반환할 수 있는 값
- return {
- success: true,
- };
+ // 클라이언트로 반환할 수 있는 값
+ return {
+ success: true,
+ };
+ } catch (error) {
+ // Handle unexpected errors
+ return {
+ success: false,
+ error: 'serverError',
+ message: error instanceof Error ? error.message : 'An unexpected error occurred'
+ };
+ }
} \ No newline at end of file
diff --git a/lib/users/verifyOtp.ts b/lib/users/verifyOtp.ts
index 5de76f90..aa759338 100644
--- a/lib/users/verifyOtp.ts
+++ b/lib/users/verifyOtp.ts
@@ -25,4 +25,33 @@ export async function verifyOtp(email: string, code: string) {
companyId: otpRecord.companyId,
domain: otpRecord.domain,
}
-} \ No newline at end of file
+}
+
+
+export async function verifyExternalCredentials(username: string, password: string) {
+ // DB에서 email과 code가 맞는지, 만료 안됐는지 검증
+ const otpRecord = await findEmailandOtp(username, password)
+ if (!otpRecord) {
+ return null
+ }
+
+ // 만료 체크
+ if (otpRecord.otpExpires && otpRecord.otpExpires < new Date()) {
+ return null
+ }
+
+ // 여기서 otpRecord에 유저 정보가 있다고 가정
+ // 예: otpRecord.userId, otpRecord.userName, otpRecord.email 등
+ // 실제 DB 설계에 맞춰 필드명을 조정하세요.
+ return {
+ email: otpRecord.email,
+ name: otpRecord.name,
+ id: otpRecord.id,
+ imageUrl: otpRecord.imageUrl,
+ companyId: otpRecord.companyId,
+ domain: otpRecord.domain,
+ }
+}
+
+
+