Explorar el Código

Feature: Implement SMS OTP verification functionality with input validation

emrecevik106 hace 1 mes
padre
commit
f809c018c3

+ 4 - 1
src/actions/auth/index.ts

@@ -18,4 +18,7 @@ export {
 } from "./finishMailVerify";
 export {
     default as startMailVerify 
-} from "./startMailVerify";
+} from "./startMailVerify";
+export {
+    default as smsOTP 
+} from "./smsOTP";

+ 59 - 0
src/actions/auth/smsOTP/index.ts

@@ -0,0 +1,59 @@
+import {
+    User
+} from "../../../models/User";
+import redis from "../../../config/redis";
+import {
+    SmsOTPResult,
+    SmsOTPInput
+} from "./types";
+
+const smsOTP = async (input: SmsOTPInput): Promise<SmsOTPResult> => {
+    try {
+        const {
+            userID,
+            code
+        } = input;
+
+        const user = await User.findById(userID);
+        if (!user) {
+            return {
+                message: "user-not-found",
+                code: 404
+            };
+        }
+
+        const cachedCode = await redis.get(`sms-verify-${userID}`);
+        if (!cachedCode) {
+            return {
+                message: "exceeded-time-limit-for-request",
+                code: 400
+            };
+        }
+
+        if (cachedCode !== code) {
+            return {
+                message: "invalid-code",
+                code: 400
+            };
+        }
+
+        await User.findByIdAndUpdate(userID, {
+            isPhoneVerified: true
+        });
+
+        await redis.del(`sms-verify-${userID}`);
+
+        return {
+            message: "your-request-has-been-received-we-will-contact-you-shortly",
+            code: 200
+        };
+    } catch (error) {
+        console.error("smsOTP error:", error);
+        return {
+            message: "internal-server-error",
+            code: 500
+        };
+    }
+};
+
+export default smsOTP;

+ 19 - 0
src/actions/auth/smsOTP/types.ts

@@ -0,0 +1,19 @@
+import {
+    IsNotEmpty,
+    IsString
+} from "class-validator";
+
+export class SmsOTPInput {
+    @IsString()
+    @IsNotEmpty({ message: "userID-is-required" })
+    userID?: string;
+
+    @IsString()
+    @IsNotEmpty({ message: "code-is-required" })
+    code?: string;
+}
+
+export interface SmsOTPResult {
+    message: string;
+    code: number;
+}

+ 4 - 2
src/actions/auth/startMailVerify/index.ts

@@ -3,10 +3,12 @@ import {
 } from "../../../models/User";
 import redis from "../../../config/redis";
 import {
-    StartMailVerifyResult, StartMailVerifyInput
+    StartMailVerifyResult,
+    StartMailVerifyInput
 } from "./types";
 import {
-    verificationCode, TTL_SECONDS
+    verificationCode,
+    TTL_SECONDS
 } from "../../../utils";
 // import { sendMail } from "../../../utils/mailer"; // mail gönderme fonskiyonu bu şekilde ilerde import edilecek.
 

+ 4 - 1
src/actions/auth/types/index.ts

@@ -12,4 +12,7 @@ export {
 } from "../../auth/refreshToken/types";
 export {
     StartMailVerifyInput 
-} from "../../auth/startMailVerify/types";
+} from "../../auth/startMailVerify/types";
+export {
+    SmsOTPInput 
+} from "../../auth/smsOTP/types";

+ 11 - 0
src/controllers/authController.ts

@@ -8,6 +8,7 @@ import {
     refreshToken as _refreshToken,
     register as _register,
     logout as _logout,
+    smsOTP as _smsOTP,
     login as _login,
     me as _me
 } from "../actions/auth";
@@ -124,4 +125,14 @@ export const finishMailVerify = async (req: Request, res: Response): Promise<voi
             message: result.message,
             code: result.code,
         });
+};
+
+export const smsOTP = async (req: Request, res: Response): Promise<void> => {
+    const result = await _smsOTP(req.body);
+
+    res.status(result.code)
+        .json({
+            message: result.message,
+            code: result.code
+        });
 };