Pārlūkot izejas kodu

Feature: Implement SMS sending functionality with validation and error handling

BedirhanOZCAN 1 mēnesi atpakaļ
vecāks
revīzija
af7e807950

+ 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 smsSend
+} from "./smsSend";

+ 77 - 0
src/actions/auth/smsSend/index.ts

@@ -0,0 +1,77 @@
+import {
+    User
+} from "../../../models/User";
+import redis from "../../../config/redis";
+import {
+    SmsSendResult,
+    SmsSendInput
+} from "./types";
+import {
+    verificationCode,
+    TTL_SECONDS
+} from "../../../utils";
+
+const smsSend = async (input: SmsSendInput): Promise<SmsSendResult> => {
+    try {
+        const {
+            userID
+        } = input;
+
+        const user = await User.findById(userID);
+        if (!user) {
+            return {
+                message: "user-not-found",
+                code: 404
+            };
+        }
+
+        if (user.isPhoneVerified) {
+            return {
+                message: "phone-already-verified",
+                code: 400
+            };
+        }
+
+        if (!user.phoneNumber) {
+            return {
+                message: "phone-number-missing",
+                code: 400
+            };
+        }
+
+        const redisKey = `sms-verify-${userID}`;
+
+        const existingTTL = await redis.ttl(redisKey);
+        if (existingTTL > 0) {
+            return {
+                message: "please-wait-before-requesting-again",
+                code: 429,
+                payload: {
+                    remainingTime: existingTTL
+                }
+            };
+        }
+
+        await redis.setex(redisKey, TTL_SECONDS, verificationCode);
+
+        // 6. SMS GÖNDERME İŞLEMİ
+        // await sendSMS(user.phoneNumber, `Giriş için doğrulama kodunuz: ${verificationCode}`);
+
+        return {
+            message: "sms-code-sent",
+            code: 200,
+            payload: {
+                remainingTime: TTL_SECONDS
+            }
+        };
+
+    } catch (error) {
+        console.error("SmsSend action error:", error);
+        return {
+            message: "internal-server-error",
+            code: 500
+        };
+    }
+};
+
+export default smsSend;

+ 16 - 0
src/actions/auth/smsSend/types.ts

@@ -0,0 +1,16 @@
+import {
+    IsNotEmpty,
+    IsString
+} from "class-validator";
+
+export class SmsSendInput {
+    @IsString()
+    @IsNotEmpty({ message: "userID-is-required" })
+    userID!: string;
+}
+
+export type SmsSendResult = {
+    message: string;
+    code: number;
+    payload?: any;
+};

+ 9 - 6
src/actions/auth/types/index.ts

@@ -1,15 +1,18 @@
 export {
-    RegisterInput 
+    RegisterInput
 } from "../../auth/register/types";
 export {
-    LoginInput 
+    LoginInput
 } from "../../auth/login/types";
 export {
-    FinishMailVerifyInput 
+    FinishMailVerifyInput
 } from "../../auth/finishMailVerify/types";
 export {
-    RefreshTokenInput 
+    RefreshTokenInput
 } from "../../auth/refreshToken/types";
 export {
-    StartMailVerifyInput 
-} from "../../auth/startMailVerify/types";
+    StartMailVerifyInput
+} from "../../auth/startMailVerify/types";
+export {
+    SmsSendInput
+} from "../../auth/smsSend/types";

+ 22 - 0
src/controllers/authController.ts

@@ -7,6 +7,7 @@ import {
     startMailVerify as _startMailVerify,
     refreshToken as _refreshToken,
     register as _register,
+    smsSend as _smsSend,
     logout as _logout,
     login as _login,
     me as _me
@@ -124,4 +125,25 @@ export const finishMailVerify = async (req: Request, res: Response): Promise<voi
             message: result.message,
             code: result.code,
         });
+};
+
+export const smsSend = async (req: Request, res: Response): Promise<void> => {
+    try {
+        const result = await _smsSend(req.body);
+
+        res.status(result.code).json({
+            message: result.message,
+            code: result.code,
+            ...(result.payload && {
+                payload: result.payload
+            }),
+        });
+
+    } catch (error) {
+        console.error("SmsSend controller error:", error);
+        res.status(500).json({
+            message: "internal-server-error",
+            code: 500
+        });
+    }
 };

+ 5 - 1
src/routes/authRoutes.ts

@@ -6,9 +6,10 @@ import {
     startMailVerify,
     refreshToken,
     register,
+    smsSend,
     logout,
     login,
-    me,
+    me
 } from "../controllers/authController";
 import {
     authMiddleware,
@@ -22,6 +23,7 @@ import {
     StartMailVerifyInput,
     RefreshTokenInput,
     RegisterInput,
+    SmsSendInput,
     LoginInput
 } from "../actions/auth/types/index";
 
@@ -34,6 +36,8 @@ router.post("/register", validateBody(RegisterInput), register);
 router.post("/login", validateBody(LoginInput), login);
 router.post("/logout", authMiddleware, logout);
 
+router.post("/smsSend", validateBody(SmsSendInput), smsSend);
+
 router.get("/validateToken", authMiddleware, (req: AuthRequest, res) => {
     res.status(200)
         .json({