# فیکس دو باگ در فلو login ## پروژه `nobat724_front` ## زمینه دو باگ مستقل در فلو login/auth وجود دارد. یکی نمایشی (شماره اضافه) و یکی عملکردی (redirect به /login بعد از refresh صفحه). ## باگ ۱ — شماره موبایل با `09` اضافی ### مشکل در `VerificationPage` پیام «کد تایید برای شماره X ارسال شد» نمایش می‌دهد `0909xxxxxxxxx` به جای `09xxxxxxxxx`. ### علت `components/register/verificationPage/index.js` خط ۵۹: ```jsx کد تایید برای شماره 09{num} ارسال شد. ``` اما `num` از state والد (`RegisterPage`) می‌آید که کل شماره را نگه می‌دارد (شامل `09`). `validatePhoneNumber` در `helper/index.js` شماره را با `^09\d{9}$` validate می‌کند — پس `num` قبلاً `09` دارد. hard-code کردن `09` اضافه → double prefix. ### فیکس ```jsx // فعلی (اشتباه): کد تایید برای شماره 09{num} ارسال شد. // درست: کد تایید برای شماره {num} ارسال شد. ``` ## باگ ۲ — redirect به `/login` بعد از refresh صفحه ### مشکل بعد از login موفق و رفتن به `/dashboard`، refresh صفحه → redirect به `/login`. ### علت احتمالی `dashboard/page.js` خط ۲۲: ```js if (!ability.can("access", "Dashboard") || !token) { return redirect("/login"); } ``` دو شرط می‌تواند fail شود: **شرط اول** — `ability.can("access", "Dashboard")`: `getUser()` در `lib/auth.js` چک می‌کند: ```js const isAuthenticated = cookieStore.get("refresh_token") && cookieStore.get("userInfo"); ``` `refresh_token` = HttpOnly (از `/api/auth/token` server route) → OK. `userInfo` = js-cookie از client در `SendReq.js` → اگر این cookie درست سِت نشده باشد، `getUser()` null برمی‌گرداند. **شرط دوم** — `!token`: `getServerAccessToken()` از `refresh_token` HttpOnly token جدید می‌گیرد با `POST /oauth/token/refresh`. اگر این endpoint fail کند یا `refresh_token` expire شده باشد → `null` → redirect. ### فایل‌های مرتبط | فایل | نقش | |------|-----| | `components/register/verificationPage/index.js` | خط ۵۹ — باگ ۱ | | `components/register/verificationPage/SendReq.js` | سِت کردن cookies بعد از login | | `app/api/auth/token/route.js` | سِت کردن `refresh_token` HttpOnly | | `lib/auth.js` | `getUser()` — چک `refresh_token` + `userInfo` | | `lib/serverToken.js` | `getServerAccessToken()` — refresh با `oauth/token/refresh` | | `app/dashboard/page.js` | guard: `!ability || !token` → redirect | | `lib/refreshCookie.js` | `setRefreshCookie()` | ### وضعیت فعلی ```js // SendReq.js — بعد از login موفق const getInfo = (token, cookieOptions) => { request.getUserInfo(...).then((res) => { const userInfo = { ...profile, username: profile.mobile_number }; Cookies.set("userInfo", JSON.stringify(userInfo), cookieOptions); Cookies.set("uuid", profile.uuid, cookieOptions); if (setStep) { setStep(3); } else { window.location.href = "/"; // ← به / می‌رود، نه /dashboard } }); }; ``` ```js // lib/serverToken.js const res = await axiosInstance.post( `${process.env.NEXT_PUBLIC_API_URL}/oauth/token/refresh`, { refresh_token: refreshToken }, ... ); return res.data?.access_token ?? null; ``` ### وظایف برای دیباگ و فیکس #### ۱. فیکس باگ ۱ (قطعی) در `components/register/verificationPage/index.js` خط ۵۹ `09` را حذف کن: ```jsx // قبل: 09{num} // بعد: {num} ``` #### ۲. بررسی `userInfo` cookie در `SendReq.js` بررسی کن `cookieOptions` درست است: - در localhost: `domain` = undefined (✓ فعلاً چنین است) - `sameSite: "lax"` در Next.js 15 App Router با server component ممکن است مشکل داشته باشد اگر `userInfo` cookie سِت نمی‌شود، `getUser()` null برمی‌گرداند → `ability.can("access","Dashboard")` = false → redirect. برای تشخیص: بعد از login در DevTools → Application → Cookies چک کن `userInfo` و `refresh_token` هر دو موجودند. #### ۳. بررسی endpoint `/oauth/token/refresh` در `lib/serverToken.js` چک کن آیا endpoint درست است: ```js POST /oauth/token/refresh body: { refresh_token: "..." } ``` با curl یا DevTools Network تأیید کن این endpoint در backend موجود است و `refresh_token` valid برمی‌گرداند. اگر ۴۰۱/۴۰۴ → `getServerAccessToken()` null برمی‌گرداند → `!token` → redirect. #### ۴. redirect بعد از login فعلاً `window.location.href = "/"` به صفحه خانه می‌رود. اگر هدف dashboard است: ```js window.location.href = "/dashboard"; ``` اما اگر کوکی‌ها درست سِت شده باشند، redirect به `/` و سپس دستی رفتن به `/dashboard` باید کار کند. ## نکات مهم - `refresh_token` = HttpOnly → فقط از server قابل خواندن. از DevTools مستقیم قابل مشاهده نیست اما در Network tab response headers قابل دیدن است. - `getUser()` هر دو `refresh_token` AND `userInfo` می‌خواهد — اگر فقط یکی موجود باشد، null برمی‌گرداند. - `getServerAccessToken()` هر بار صفحه load می‌شود یک refresh token request می‌زند — اگر backend rate-limit داشته باشد یا endpoint اشتباه باشد، fail می‌شود. - در DEV_MODE بررسی باگ ۲ را با Network tab و Console انجام بده.