fix both admin and company login
Build & Push / Pipeline Tests (push) Failing after 1m27s
Build & Push / Build & Push Docker Image (push) Has been skipped
Test / Type Check (all packages) (push) Successful in 55s
Test / API Unit Tests (push) Successful in 1m9s
Test / Homepage Unit Tests (push) Successful in 50s
Test / Carplace Unit Tests (push) Has been cancelled
Test / Admin Unit Tests (push) Has been cancelled
Test / Dashboard Unit Tests (push) Has been cancelled
Test / API Integration Tests (push) Has been cancelled

This commit is contained in:
root
2026-07-28 23:11:46 -04:00
parent 50c74b9007
commit eeec8f0a82
5 changed files with 167 additions and 117 deletions
@@ -101,17 +101,6 @@ const dicts: Record<string, Dict> = {
},
};
function isAdminDestination(value: string) {
if (!value) return false;
try {
const url = new URL(value, typeof window === 'undefined' ? 'http://localhost' : window.location.origin);
return url.pathname.startsWith('/admin');
} catch {
return value.startsWith('/admin');
}
}
export function SignInForm({
locale,
authMode = 'auto',
@@ -119,6 +108,7 @@ export function SignInForm({
locale: Locale;
authMode?: 'auto' | 'admin' | 'employee';
}) {
void authMode;
const dict = (dicts[locale] ?? dicts.en) as Dict;
const searchParams = useSearchParams();
const pathname = usePathname();
@@ -130,13 +120,27 @@ export function SignInForm({
const [step, setStep] = useState<'credentials' | 'totp'>('credentials');
const [loading, setLoading] = useState(false);
const [error, setError] = useState<string | null>(null);
const requestedPortal = searchParams.get('portal');
const requestedNext = searchParams.get('next') || searchParams.get('redirect') || '';
const employeeRedirect = searchParams.get('redirect') || '/dashboard';
const preferAdminAuth =
authMode === 'admin' ||
pathname.includes('/admin-sign-in') ||
(authMode === 'auto' && (requestedPortal === 'admin' || isAdminDestination(requestedNext)));
function completeLogin(data: any) {
if (data?.admin) {
window.location.href = `${window.location.origin}/admin/dashboard`;
return true;
}
if (data?.employee) {
localStorage.setItem(EMPLOYEE_PROFILE_KEY, JSON.stringify(data.employee));
const prefLang = data.employee?.preferredLanguage;
if (prefLang === 'en' || prefLang === 'fr' || prefLang === 'ar') {
document.cookie = `rentaldrivego-language=${prefLang}; path=/; max-age=31536000; samesite=lax`;
}
window.dispatchEvent(new CustomEvent('rentaldrivego:auth-changed'));
window.location.replace(employeeRedirect);
return true;
}
return false;
}
async function handleCredentials(e: React.FormEvent) {
e.preventDefault();
@@ -144,81 +148,35 @@ export function SignInForm({
setError(null);
try {
const tryAdminLogin = async () => {
const adminRes = await fetch(`${API_BASE}/admin/auth/login`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
credentials: 'include',
body: JSON.stringify({ email, password }),
});
const adminJson = await adminRes.json();
const res = await fetch(`${API_BASE}/auth/login`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
credentials: 'include',
body: JSON.stringify({ email, password }),
});
const json = await res.json();
if (adminRes.ok && adminJson?.data?.admin) {
window.location.href = `${window.location.origin}/admin/dashboard`;
return true;
}
if (res.ok && completeLogin(json?.data)) return;
if (adminRes.status === 401 && adminJson?.error === 'totp_required') {
setStep('totp');
return true;
}
if (adminRes.status === 429) {
setError(dict.tooManyRequests);
return true;
}
return false;
};
const tryEmployeeLogin = async () => {
const empRes = await fetch(`${API_BASE}/auth/employee/login`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
credentials: 'include',
body: JSON.stringify({ email, password }),
});
const empJson = await empRes.json();
if (empRes.ok && empJson?.data?.employee) {
if (empJson?.data?.employee) {
localStorage.setItem(EMPLOYEE_PROFILE_KEY, JSON.stringify(empJson.data.employee));
const prefLang = empJson.data.employee?.preferredLanguage;
if (prefLang === 'en' || prefLang === 'fr' || prefLang === 'ar') {
document.cookie = `rentaldrivego-language=${prefLang}; path=/; max-age=31536000; samesite=lax`;
}
}
window.dispatchEvent(new CustomEvent('rentaldrivego:auth-changed'));
window.location.replace(employeeRedirect);
return true;
}
if (empJson?.error === 'password_not_set') {
setError(dict.passwordNotSet);
return true;
}
if (empJson?.error === 'email_not_verified') {
setError(dict.emailNotVerified);
return true;
}
if (empRes.status === 429) {
setError(dict.tooManyRequests);
return true;
}
return false;
};
if (preferAdminAuth) {
if (await tryAdminLogin()) return;
setError(dict.invalidCredentials);
if (res.status === 401 && json?.error === 'totp_required') {
setStep('totp');
return;
}
if (await tryEmployeeLogin()) return;
if (await tryAdminLogin()) return;
if (json?.error === 'password_not_set') {
setError(dict.passwordNotSet);
return;
}
if (json?.error === 'email_not_verified') {
setError(dict.emailNotVerified);
return;
}
if (res.status === 429) {
setError(dict.tooManyRequests);
return;
}
setError(dict.invalidCredentials);
} catch {
@@ -239,7 +197,7 @@ export function SignInForm({
? { totpCode: normalizedCode }
: { recoveryCode: normalizedCode };
const adminRes = await fetch(`${API_BASE}/admin/auth/login`, {
const adminRes = await fetch(`${API_BASE}/auth/login`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
credentials: 'include',
@@ -247,10 +205,7 @@ export function SignInForm({
});
const adminJson = await adminRes.json();
if (adminRes.ok && adminJson?.data?.admin) {
window.location.href = `${window.location.origin}/admin/dashboard`;
return;
}
if (adminRes.ok && completeLogin(adminJson?.data)) return;
setError(dict.invalidCredentials);
} catch {