From 454fb1b52cfc7bd5cf0a43240f438260723dd41b Mon Sep 17 00:00:00 2001 From: Ryan Chen Date: Mon, 27 Oct 2025 12:24:10 -0400 Subject: [PATCH] Add authentication validation on login screen load MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add validateToken() method to userService to check if refresh token is valid - Automatically redirect to chat if user already has valid session - Show 'Checking authentication...' loading state during validation - Prevents unnecessary login if user is already authenticated - Improves UX by skipping login screen when not needed 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- raggr-frontend/src/api/userService.ts | 15 +++++++ raggr-frontend/src/components/LoginScreen.tsx | 40 ++++++++++++++++++- 2 files changed, 53 insertions(+), 2 deletions(-) diff --git a/raggr-frontend/src/api/userService.ts b/raggr-frontend/src/api/userService.ts index 131f710..632a633 100644 --- a/raggr-frontend/src/api/userService.ts +++ b/raggr-frontend/src/api/userService.ts @@ -55,6 +55,21 @@ class UserService { return data.access_token; } + async validateToken(): Promise { + const refreshToken = localStorage.getItem("refresh_token"); + + if (!refreshToken) { + return false; + } + + try { + await this.refreshToken(); + return true; + } catch (error) { + return false; + } + } + async fetchWithAuth( url: string, options: RequestInit = {}, diff --git a/raggr-frontend/src/components/LoginScreen.tsx b/raggr-frontend/src/components/LoginScreen.tsx index d3d9ebe..ecc52a7 100644 --- a/raggr-frontend/src/components/LoginScreen.tsx +++ b/raggr-frontend/src/components/LoginScreen.tsx @@ -1,4 +1,4 @@ -import { useState } from "react"; +import { useState, useEffect } from "react"; import { userService } from "../api/userService"; type LoginScreenProps = { @@ -9,8 +9,23 @@ export const LoginScreen = ({ setAuthenticated }: LoginScreenProps) => { const [username, setUsername] = useState(""); const [password, setPassword] = useState(""); const [error, setError] = useState(""); + const [isChecking, setIsChecking] = useState(true); + + useEffect(() => { + // Check if user is already authenticated + const checkAuth = async () => { + const isValid = await userService.validateToken(); + if (isValid) { + setAuthenticated(true); + } + setIsChecking(false); + }; + checkAuth(); + }, [setAuthenticated]); + + const handleLogin = async (e?: React.FormEvent) => { + e?.preventDefault(); - const handleLogin = async () => { if (!username || !password) { setError("Please enter username and password"); return; @@ -28,6 +43,25 @@ export const LoginScreen = ({ setAuthenticated }: LoginScreenProps) => { } }; + const handleKeyPress = (e: React.KeyboardEvent) => { + if (e.key === "Enter") { + handleLogin(); + } + }; + + // Show loading state while checking authentication + if (isChecking) { + return ( +
+
+
+

Checking authentication...

+
+
+
+ ); + } + return (
@@ -52,6 +86,7 @@ export const LoginScreen = ({ setAuthenticated }: LoginScreenProps) => { name="username" value={username} onChange={(e) => setUsername(e.target.value)} + onKeyPress={handleKeyPress} className="border border-s-slate-950 p-3 rounded-md min-h-[44px]" />