skip auth

This commit is contained in:
Rama Priyanto 2025-07-22 10:29:28 +07:00
parent 504101b91c
commit 5807e389b4
2 changed files with 220 additions and 206 deletions

View File

@ -13,7 +13,8 @@ type AuthStep = "login" | "email-setup" | "otp";
const AuthPage = ({ params: { locale } }: { params: { locale: string } }) => { const AuthPage = ({ params: { locale } }: { params: { locale: string } }) => {
const [currentStep, setCurrentStep] = useState<AuthStep>("login"); const [currentStep, setCurrentStep] = useState<AuthStep>("login");
const [loginCredentials, setLoginCredentials] = useState<LoginFormData | null>(null); const [loginCredentials, setLoginCredentials] =
useState<LoginFormData | null>(null);
const { validateEmail } = useEmailValidation(); const { validateEmail } = useEmailValidation();
const { login } = useAuth(); const { login } = useAuth();
@ -23,6 +24,9 @@ const AuthPage = ({ params: { locale } }: { params: { locale: string } }) => {
try { try {
const result = await validateEmail(data); const result = await validateEmail(data);
switch (result) { switch (result) {
case "skip":
handleOTPSuccess();
break;
case "setup": case "setup":
setCurrentStep("email-setup"); setCurrentStep("email-setup");
break; break;
@ -112,11 +116,7 @@ const AuthPage = ({ params: { locale } }: { params: { locale: string } }) => {
} }
}; };
return ( return <AuthLayout>{renderCurrentStep()}</AuthLayout>;
<AuthLayout>
{renderCurrentStep()}
</AuthLayout>
);
}; };
export default AuthPage; export default AuthPage;

View File

@ -9,7 +9,7 @@ import {
AuthState, AuthState,
AuthContextType, AuthContextType,
EmailValidationData, EmailValidationData,
OTPData OTPData,
} from "@/types/auth"; } from "@/types/auth";
import { import {
login, login,
@ -17,7 +17,7 @@ import {
postEmailValidation, postEmailValidation,
postSetupEmail, postSetupEmail,
verifyOTPByUsername, verifyOTPByUsername,
doLogin doLogin,
} from "@/service/auth"; } from "@/service/auth";
import { import {
setAuthCookies, setAuthCookies,
@ -29,7 +29,7 @@ import {
showAuthError, showAuthError,
showAuthSuccess, showAuthSuccess,
loginRateLimiter, loginRateLimiter,
AUTH_CONSTANTS AUTH_CONSTANTS,
} from "@/lib/auth-utils"; } from "@/lib/auth-utils";
import { warning } from "@/lib/swal"; import { warning } from "@/lib/swal";
@ -46,33 +46,38 @@ export const useAuth = (): AuthContextType => {
useEffect(() => { useEffect(() => {
const checkAuth = async () => { const checkAuth = async () => {
try { try {
setState(prev => ({ ...prev, loading: true })); setState((prev) => ({ ...prev, loading: true }));
// Add logic to check if user is authenticated // Add logic to check if user is authenticated
// This could check for valid tokens, etc. // This could check for valid tokens, etc.
} catch (error) { } catch (error) {
setState(prev => ({ setState((prev) => ({
...prev, ...prev,
isAuthenticated: false, isAuthenticated: false,
user: null, user: null,
error: "Authentication check failed" error: "Authentication check failed",
})); }));
} finally { } finally {
setState(prev => ({ ...prev, loading: false })); setState((prev) => ({ ...prev, loading: false }));
} }
}; };
checkAuth(); checkAuth();
}, []); }, []);
const login = useCallback(async (credentials: LoginFormData): Promise<void> => { const login = useCallback(
async (credentials: LoginFormData): Promise<void> => {
try { try {
setState(prev => ({ ...prev, loading: true, error: null })); setState((prev) => ({ ...prev, loading: true, error: null }));
// Check rate limiting // Check rate limiting
if (!loginRateLimiter.canAttempt(credentials.username)) { if (!loginRateLimiter.canAttempt(credentials.username)) {
const remainingTime = loginRateLimiter.getRemainingTime(credentials.username); const remainingTime = loginRateLimiter.getRemainingTime(
credentials.username
);
const minutes = Math.ceil(remainingTime / (60 * 1000)); const minutes = Math.ceil(remainingTime / (60 * 1000));
throw new Error(`Too many login attempts. Please try again in ${minutes} minutes.`); throw new Error(
`Too many login attempts. Please try again in ${minutes} minutes.`
);
} }
// Attempt login // Attempt login
@ -137,17 +142,18 @@ export const useAuth = (): AuthContextType => {
// Navigate to appropriate dashboard // Navigate to appropriate dashboard
window.location.href = navigationPath; window.location.href = navigationPath;
} catch (error: any) { } catch (error: any) {
const errorMessage = error?.message || "Login failed"; const errorMessage = error?.message || "Login failed";
setState(prev => ({ setState((prev) => ({
...prev, ...prev,
loading: false, loading: false,
error: errorMessage error: errorMessage,
})); }));
showAuthError(error, "Login failed"); showAuthError(error, "Login failed");
} }
}, [router]); },
[router]
);
const logout = useCallback((): void => { const logout = useCallback((): void => {
clearAllCookies(); clearAllCookies();
@ -162,13 +168,13 @@ export const useAuth = (): AuthContextType => {
const refreshToken = useCallback(async (): Promise<void> => { const refreshToken = useCallback(async (): Promise<void> => {
try { try {
setState(prev => ({ ...prev, loading: true })); setState((prev) => ({ ...prev, loading: true }));
// Add token refresh logic here // Add token refresh logic here
// This would typically call an API to refresh the access token // This would typically call an API to refresh the access token
} catch (error) { } catch (error) {
logout(); logout();
} finally { } finally {
setState(prev => ({ ...prev, loading: false })); setState((prev) => ({ ...prev, loading: false }));
} }
}, [logout]); }, [logout]);
@ -185,7 +191,8 @@ export const useEmailValidation = () => {
const [loading, setLoading] = useState(false); const [loading, setLoading] = useState(false);
const [error, setError] = useState<string | null>(null); const [error, setError] = useState<string | null>(null);
const validateEmail = useCallback(async (credentials: LoginFormData): Promise<string> => { const validateEmail = useCallback(
async (credentials: LoginFormData): Promise<string> => {
try { try {
setLoading(true); setLoading(true);
setError(null); setError(null);
@ -205,6 +212,8 @@ export const useEmailValidation = () => {
return "otp"; return "otp";
case "Username & password valid": case "Username & password valid":
return "success"; return "success";
case "Skip to login":
return "skip";
default: default:
return "login"; return "login";
} }
@ -216,7 +225,9 @@ export const useEmailValidation = () => {
} finally { } finally {
setLoading(false); setLoading(false);
} }
}, []); },
[]
);
return { return {
validateEmail, validateEmail,
@ -230,7 +241,8 @@ export const useEmailSetup = () => {
const [loading, setLoading] = useState(false); const [loading, setLoading] = useState(false);
const [error, setError] = useState<string | null>(null); const [error, setError] = useState<string | null>(null);
const setupEmail = useCallback(async ( const setupEmail = useCallback(
async (
credentials: LoginFormData, credentials: LoginFormData,
emailData: EmailValidationData emailData: EmailValidationData
): Promise<string> => { ): Promise<string> => {
@ -269,7 +281,9 @@ export const useEmailSetup = () => {
} finally { } finally {
setLoading(false); setLoading(false);
} }
}, []); },
[]
);
return { return {
setupEmail, setupEmail,
@ -283,10 +297,8 @@ export const useOTPVerification = () => {
const [loading, setLoading] = useState(false); const [loading, setLoading] = useState(false);
const [error, setError] = useState<string | null>(null); const [error, setError] = useState<string | null>(null);
const verifyOTP = useCallback(async ( const verifyOTP = useCallback(
username: string, async (username: string, otp: string): Promise<boolean> => {
otp: string
): Promise<boolean> => {
try { try {
setLoading(true); setLoading(true);
setError(null); setError(null);
@ -310,7 +322,9 @@ export const useOTPVerification = () => {
} finally { } finally {
setLoading(false); setLoading(false);
} }
}, []); },
[]
);
return { return {
verifyOTP, verifyOTP,