Files
nobat724_front/.claude/prompt/fix-login-bugs.md
T

5.9 KiB
Raw Blame History

فیکس دو باگ در فلو login

پروژه

nobat724_front

زمینه

دو باگ مستقل در فلو login/auth وجود دارد. یکی نمایشی (شماره اضافه) و یکی عملکردی (redirect به /login بعد از refresh صفحه).

باگ ۱ — شماره موبایل با 09 اضافی

مشکل

در VerificationPage پیام «کد تایید برای شماره X ارسال شد» نمایش می‌دهد 0909xxxxxxxxx به جای 09xxxxxxxxx.

علت

components/register/verificationPage/index.js خط ۵۹:

کد تایید برای شماره <span dir="ltr">09{num}</span> ارسال شد.

اما num از state والد (RegisterPage) می‌آید که کل شماره را نگه می‌دارد (شامل 09). validatePhoneNumber در helper/index.js شماره را با ^09\d{9}$ validate می‌کند — پس num قبلاً 09 دارد. hard-code کردن 09 اضافه → double prefix.

فیکس

// فعلی (اشتباه):
کد تایید برای شماره <span dir="ltr">09{num}</span> ارسال شد.

// درست:
کد تایید برای شماره <span dir="ltr">{num}</span> ارسال شد.

باگ ۲ — redirect به /login بعد از refresh صفحه

مشکل

بعد از login موفق و رفتن به /dashboard، refresh صفحه → redirect به /login.

علت احتمالی

dashboard/page.js خط ۲۲:

if (!ability.can("access", "Dashboard") || !token) {
  return redirect("/login");
}

دو شرط می‌تواند fail شود:

شرط اولability.can("access", "Dashboard"): getUser() در lib/auth.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
lib/refreshCookie.js setRefreshCookie()

وضعیت فعلی

// 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
    }
  });
};
// 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 را حذف کن:

// قبل:
<span dir="ltr">09{num}</span>
// بعد:
<span dir="ltr">{num}</span>

در 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 درست است:

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 است:

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 انجام بده.