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}