From 26ef1378979d4d4739db597e697fc76dcd1c617c Mon Sep 17 00:00:00 2001 From: Jeet Vasoya Date: Wed, 3 Jun 2026 12:48:41 +0530 Subject: [PATCH 1/4] 634 commit 1 --- src/hooks/useGitHubAuth.ts | 45 +++++++++++++++++++++++++++++++++-- src/pages/Tracker/Tracker.tsx | 10 ++++++-- 2 files changed, 51 insertions(+), 4 deletions(-) diff --git a/src/hooks/useGitHubAuth.ts b/src/hooks/useGitHubAuth.ts index a0c24b2a..533e8c67 100644 --- a/src/hooks/useGitHubAuth.ts +++ b/src/hooks/useGitHubAuth.ts @@ -1,18 +1,57 @@ -import { useState, useMemo } from 'react'; +import { useState, useMemo, useEffect } from 'react'; import { Octokit } from '@octokit/core'; export const useGitHubAuth = () => { const [username, setUsername] = useState(''); const [token, setToken] = useState(''); + const [error, setError] = useState(''); const octokit = useMemo(() => { + setError(''); if (!username) return null; if(token){ - return new Octokit({ auth: token }); + return new Octokit({ auth: token }); } return new Octokit(); }, [username, token]); + // Validate token format and authentication on mount or change + useEffect(() => { + if (!token || !username) { + setError(''); + return; + } + + const validateAuth = async () => { + if (!octokit) return; + + try { + // Attempt a simple API call to verify the token is valid + await octokit.request('GET /user'); + setError(''); + } catch (err: unknown) { + const error = err as { + status?: number; + message?: string; + }; + + if (error.status === 401) { + setError('Invalid personal access token. Please check and try again.'); + } else if (error.status === 403) { + setError('Token has insufficient permissions or has expired.'); + } else if (error.message?.includes('Bad credentials')) { + setError('Bad credentials. Please verify your personal access token.'); + } else { + setError(`Authentication error: ${error.message || 'Unknown error'}`); + } + } + }; + + // Validate on token change (but with a small delay to avoid excessive API calls during typing) + const timeoutId = setTimeout(validateAuth, 500); + return () => clearTimeout(timeoutId); + }, [token, username, octokit]); + const getOctokit = () => octokit; return { @@ -20,6 +59,8 @@ export const useGitHubAuth = () => { setUsername, token, setToken, + error, + setError, getOctokit, }; }; diff --git a/src/pages/Tracker/Tracker.tsx b/src/pages/Tracker/Tracker.tsx index 576f39bf..26c18f99 100644 --- a/src/pages/Tracker/Tracker.tsx +++ b/src/pages/Tracker/Tracker.tsx @@ -324,9 +324,15 @@ const Home: React.FC = () => { - {(authError || dataError) && ( + {authError && ( - {authError || dataError} + Authentication Error: {authError} + + )} + + {dataError && !authError && ( + + Data Fetch Error: {dataError} )} From 478384873ec1dff01b27d49b4ae957a8f30eaf13 Mon Sep 17 00:00:00 2001 From: Jeet Vasoya Date: Wed, 3 Jun 2026 12:59:44 +0530 Subject: [PATCH 2/4] final commit 634 --- src/hooks/useGitHubAuth.ts | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/src/hooks/useGitHubAuth.ts b/src/hooks/useGitHubAuth.ts index 533e8c67..98267109 100644 --- a/src/hooks/useGitHubAuth.ts +++ b/src/hooks/useGitHubAuth.ts @@ -7,7 +7,6 @@ export const useGitHubAuth = () => { const [error, setError] = useState(''); const octokit = useMemo(() => { - setError(''); if (!username) return null; if(token){ return new Octokit({ auth: token }); @@ -15,21 +14,35 @@ export const useGitHubAuth = () => { return new Octokit(); }, [username, token]); + // Clear error when username or token changes, before validation runs + useEffect(() => { + setError(''); + }, [username, token]); + // Validate token format and authentication on mount or change useEffect(() => { if (!token || !username) { - setError(''); return; } + const controller = new AbortController(); + const validateAuth = async () => { if (!octokit) return; try { // Attempt a simple API call to verify the token is valid - await octokit.request('GET /user'); - setError(''); + await octokit.request('GET /user', { request: { signal: controller.signal } }); + // Only update state if request was not aborted + if (!controller.signal.aborted) { + setError(''); + } } catch (err: unknown) { + // Ignore if request was aborted + if (controller.signal.aborted) { + return; + } + const error = err as { status?: number; message?: string; @@ -49,7 +62,10 @@ export const useGitHubAuth = () => { // Validate on token change (but with a small delay to avoid excessive API calls during typing) const timeoutId = setTimeout(validateAuth, 500); - return () => clearTimeout(timeoutId); + return () => { + clearTimeout(timeoutId); + controller.abort(); + }; }, [token, username, octokit]); const getOctokit = () => octokit; From f22aea955fe6293026f3b9515e5f639176928a55 Mon Sep 17 00:00:00 2001 From: Jeet Vasoya Date: Wed, 3 Jun 2026 13:22:41 +0530 Subject: [PATCH 3/4] feat: handle GitHub auth token validation in useGitHubAuth hook --- src/pages/Contact/Contact.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/Contact/Contact.tsx b/src/pages/Contact/Contact.tsx index a0bfccbd..44fef87c 100644 --- a/src/pages/Contact/Contact.tsx +++ b/src/pages/Contact/Contact.tsx @@ -175,7 +175,7 @@ function Contact() { mode === "dark" ? "text-gray-400" : "text-gray-500" - }`} + }` } > {sub}

From f20bb8ed2d1412d5c51d064be865ddffb43866c6 Mon Sep 17 00:00:00 2001 From: Jeet Vasoya Date: Wed, 3 Jun 2026 13:41:04 +0530 Subject: [PATCH 4/4] fix(#634): separate auth and data error alerts on Tracker page --- src/pages/Contact/Contact.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pages/Contact/Contact.tsx b/src/pages/Contact/Contact.tsx index 44fef87c..a0bfccbd 100644 --- a/src/pages/Contact/Contact.tsx +++ b/src/pages/Contact/Contact.tsx @@ -175,7 +175,7 @@ function Contact() { mode === "dark" ? "text-gray-400" : "text-gray-500" - }` } + }`} > {sub}