diff --git a/src/Auth/Controller/AuthController.php b/src/Auth/Controller/AuthController.php index 3fe3a399..852e2679 100644 --- a/src/Auth/Controller/AuthController.php +++ b/src/Auth/Controller/AuthController.php @@ -89,48 +89,30 @@ class AuthController extends BaseController #[OA\Post( path: '/api/v1/user/send-code', - summary: 'Send OTP code to mobile number', + summary: 'مرحله ۱ — ارسال کد OTP به موبایل', + description: "**جریان لاگین با موبایل (OTP):**\n\n**مرحله ۱:** ارسال کد → **مرحله ۲:** تأیید کد (`/api/v1/user/verify-code`) → **مرحله ۳:** دریافت JWT (`/oauth/token`)\n\n> ⚠️ در محیط **dev** پیامکی ارسال نمی‌شود و کد همیشه `12345` است.", requestBody: new OA\RequestBody( required: true, content: new OA\JsonContent( required: ['mobile'], properties: [ - new OA\Property(property: 'mobile', type: 'string', example: '09123456789'), + new OA\Property(property: 'mobile', type: 'string', example: '09120671713', description: 'شماره موبایل ۱۱ رقمی'), ] ) ), responses: [ new OA\Response( response: 200, - description: 'OTP sent successfully', + description: 'کد OTP ارسال شد — uuid را برای مرحله بعد نگه دارید', content: new OA\JsonContent( properties: [ - new OA\Property(property: 'uuid', type: 'string', format: 'uuid'), + new OA\Property(property: 'uuid', type: 'string', format: 'uuid', description: 'شناسه یکتا برای verify-code و oauth/token'), new OA\Property(property: 'message', type: 'string', example: 'کد تایید با موفقیت ارسال شد.'), ] ) ), - new OA\Response( - response: 422, - description: 'Invalid mobile format', - content: new OA\JsonContent( - properties: [ - new OA\Property(property: 'success', type: 'boolean', example: false), - new OA\Property( - property: 'errors', - type: 'array', - items: new OA\Items( - properties: [ - new OA\Property(property: 'code', type: 'string'), - new OA\Property(property: 'message', type: 'string'), - ], - type: 'object' - ) - ), - ] - ) - ), - new OA\Response(response: 429, description: 'Rate limit exceeded'), + new OA\Response(response: 422, description: 'فرمت موبایل نادرست'), + new OA\Response(response: 429, description: 'تعداد درخواست از حد مجاز گذشت (۳ بار در ۵ دقیقه)'), ] )] #[Route('/api/v1/user/send-code', methods: ['POST'])] @@ -155,55 +137,35 @@ class AuthController extends BaseController #[OA\Post( path: '/api/v1/user/verify-code', - summary: 'Verify OTP code', + summary: 'مرحله ۲ — تأیید کد OTP', + description: "uuid را از مرحله ۱ (`/api/v1/user/send-code`) وارد کنید.\n\n> در محیط **dev** کد همیشه `12345` است.\n\nپس از تأیید موفق، به مرحله ۳ (`/oauth/token`) بروید.", requestBody: new OA\RequestBody( required: true, content: new OA\JsonContent( required: ['uuid', 'code'], properties: [ - new OA\Property(property: 'uuid', type: 'string', format: 'uuid'), - new OA\Property(property: 'code', type: 'string', example: '12345'), + new OA\Property(property: 'uuid', type: 'string', format: 'uuid', description: 'uuid دریافت‌شده از send-code'), + new OA\Property(property: 'code', type: 'string', example: '12345', description: 'کد ۵ رقمی — در dev همیشه 12345'), ] ) ), responses: [ new OA\Response( response: 200, - description: 'Code verified successfully', + description: 'کد تأیید شد — به مرحله ۳ بروید', content: new OA\JsonContent( properties: [ new OA\Property(property: 'success', type: 'boolean', example: true), - new OA\Property( - property: 'data', - properties: [ - new OA\Property(property: 'message', type: 'string', example: 'کد با موفقیت تایید شد.'), - ], - type: 'object' - ), - new OA\Property(property: 'errors', type: 'array', items: new OA\Items()), - ] - ) - ), - new OA\Response( - response: 422, - description: 'Missing or invalid uuid/code', - content: new OA\JsonContent( - properties: [ - new OA\Property(property: 'success', type: 'boolean', example: false), - new OA\Property( - property: 'errors', - type: 'array', - items: new OA\Items( - properties: [ - new OA\Property(property: 'code', type: 'string'), - new OA\Property(property: 'message', type: 'string'), - ], - type: 'object' - ) - ), + new OA\Property(property: 'data', properties: [ + new OA\Property(property: 'message', type: 'string', example: 'کد با موفقیت تایید شد.'), + new OA\Property(property: 'is_new_user', type: 'boolean', example: false, description: 'اگر true باشد کاربر جدید است و باید ثبت‌نام کند (`/api/v1/user/register`)'), + ], type: 'object'), ] ) ), + new OA\Response(response: 400, description: 'کد نادرست یا uuid منقضی'), + new OA\Response(response: 422, description: 'uuid یا code ارسال نشده'), + new OA\Response(response: 429, description: 'تعداد تلاش از حد مجاز گذشت (۵ بار)'), ] )] #[Route('/api/v1/user/verify-code', methods: ['POST'])] @@ -217,9 +179,13 @@ class AuthController extends BaseController return $this->error(ErrorCodes::ERR_VALIDATION_002, 'uuid و code الزامی است', 422); } - $this->otpService->verifyCode($uuid, $code); + $otpData = $this->otpService->verifyCode($uuid, $code); + $isNewUser = $this->userRepo->findByMobile($otpData['mobile']) === null; - return $this->success(['message' => 'کد با موفقیت تایید شد.']); + return $this->success([ + 'message' => 'کد با موفقیت تایید شد.', + 'is_new_user' => $isNewUser, + ]); } #[OA\Post( @@ -303,7 +269,8 @@ class AuthController extends BaseController #[OA\Post( path: '/oauth/token', - summary: 'Issue access and refresh tokens using OTP-verified UUID', + summary: 'مرحله ۳ — دریافت JWT با uuid تأییدشده', + description: 'uuid را از مرحله ۱ (`/api/v1/user/send-code`) وارد کنید — **بعد از** اینکه در مرحله ۲ (`/api/v1/user/verify-code`) تأیید شد. access_token را در header درخواست‌های بعدی استفاده کنید: `Authorization: Bearer `', requestBody: new OA\RequestBody( required: true, content: new OA\JsonContent(