fix: guest-safe homepage and public read-only access for unauthenticated users#191
Conversation
|
Warning Rate limit exceeded
⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. 📒 Files selected for processing (11)
WalkthroughThe PR introduces authentication-aware components and robust null-safety handling across the frontend. A Changes
Estimated code review effort🎯 4 (Complex) | ⏱️ ~50 minutes Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Update for https://github.com/VarshiniGunti/Leaderboard-Pro/actions/runs/22402957101/attempts/1 Accepted in #1 (comment) Signed-off-by: check-spelling-bot <check-spelling-bot@users.noreply.github.com> on-behalf-of: @check-spelling <check-spelling-bot@check-spelling.dev>
772d797 to
594da9b
Compare
This comment has been minimized.
This comment has been minimized.
There was a problem hiding this comment.
Actionable comments posted: 2
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (6)
app/src/components/LeetcodeTable.jsx (1)
112-127:⚠️ Potential issue | 🟠 MajorPlease harden friend API handlers against non-JSON/error responses.
Unprotected
fetch/JSON parsing can still fail at runtime. Add try/catch and response/content-type guards to keep this path crash-safe.Also applies to: 129-172
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@app/src/components/LeetcodeTable.jsx` around lines 112 - 127, Wrap the network and parsing logic in getltfriends with robust guards: check accessToken as before, then perform fetch inside a try/catch, verify response.ok and that response.headers.get("content-type") includes "application/json" before calling await response.json(); on any failure (non-ok response, missing/invalid content-type, or JSON parse error) catch the error and call setLeetcodefriends([]) (or a safe fallback) and optionally log the error; apply the same pattern to the other friend-related handlers in this file (lines ~129-172) to prevent crashes from non-JSON or error responses.app/src/components/OpenlakeTable.jsx (1)
76-91:⚠️ Potential issue | 🟠 MajorGuard friend API calls against non-JSON/error responses.
response.json()and fetch calls are not wrapped for failure paths. A non-JSON response (401/502/html) or network error can still throw and reintroduce runtime instability.🛠️ Suggested hardening (apply same pattern to add/remove endpoints)
const getccfriends = async () => { if (!accessToken) { setOLFriends([]); return; } - const response = await fetch(BACKEND + "/openlakeFL/", { - method: "GET", - headers: { - "Content-Type": "application/json", - Authorization: "Bearer " + accessToken, - }, - }); - - const newData = await response.json(); - setOLFriends(newData); + try { + const response = await fetch(BACKEND + "/openlakeFL/", { + method: "GET", + headers: { + "Content-Type": "application/json", + Authorization: "Bearer " + accessToken, + }, + }); + const contentType = response.headers.get("content-type") || ""; + const payload = contentType.toLowerCase().includes("application/json") + ? await response.json().catch(() => null) + : null; + setOLFriends(response.ok && Array.isArray(payload) ? payload : []); + } catch { + setOLFriends([]); + } };Also applies to: 93-134
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@app/src/components/OpenlakeTable.jsx` around lines 76 - 91, The getccfriends function currently calls fetch and response.json() without error handling; wrap the network call and JSON parsing in a try/catch, check response.ok before calling response.json(), and fall back to reading response.text() or returning an empty array when the content is non-JSON or the status is not ok; ensure errors and non-JSON responses do not throw (log them) and call setOLFriends([]) on failure. Apply the same pattern to the add/remove endpoints referenced in the file so all fetch calls using BACKEND, accessToken, and state updaters like setOLFriends are guarded and resilient to network/HTML/error responses.app/src/components/GithubTable.jsx (1)
100-115:⚠️ Potential issue | 🟠 MajorHarden friend API handlers for non-JSON and fetch failures.
These handlers still assume successful JSON parsing and successful network calls. Please add try/catch + response/content-type checks to avoid unhandled failures.
Also applies to: 117-160
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@app/src/components/GithubTable.jsx` around lines 100 - 115, The getghfriends function currently assumes fetch succeeds and response is JSON; wrap the fetch+parsing in a try/catch, check response.ok and the Content-Type header before calling response.json(), and on any failure fall back to setGithubfriends([]) and optionally log the error; apply the same pattern to the other GitHub API handlers in this file (the functions around lines where getghfriends is defined) so each handler verifies response.ok, checks response.headers.get("content-type") includes "application/json" before parsing, and catches network/parse errors to avoid unhandled exceptions.app/src/components/CodechefTable.jsx (1)
108-123:⚠️ Potential issue | 🟠 MajorAdd defensive handling for friend API response parsing and network errors.
Like the other table components, these calls can still throw on non-JSON/error responses. Please guard fetch + parsing to prevent runtime instability.
Also applies to: 125-169
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@app/src/components/CodechefTable.jsx` around lines 108 - 123, The getccfriends function (and similar functions in lines 125-169) must defensively handle network and non-JSON responses: wrap the fetch + response.json() in a try/catch, check response.ok before parsing, verify the Content-Type includes "application/json" (or handle non-JSON by falling back), and on any error setCodecheffriends([]) and log or surface the error; ensure the Authorization header and BACKEND + "/codechefFL/" call are preserved and that successful JSON results still call setCodecheffriends(newData).app/src/App.jsx (2)
126-126:⚠️ Potential issue | 🟡 MinorStray
-character renders a literal hyphen on the profile page.
<Profile />-includes a text node"-"that will be visible to every authenticated user on/profile. This appears to be a leftover diff artifact.🐛 Proposed fix
- <Profile />- + <Profile />🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@app/src/App.jsx` at line 126, Remove the stray hyphen text node after the Profile component render; locate the JSX fragment where <Profile /> is rendered in App.jsx and delete the trailing "-" so the element reads only <Profile /> to prevent the literal hyphen from displaying on the /profile page.
91-95:⚠️ Potential issue | 🟠 Major
/is still gated byPrivateRoute, contradicting the PR objective — guests hitting the root URL still get redirected.The
/*catch-all at line 158 renders<HomePage />openly, but the explicit/route at lines 91-94 retains its<PrivateRoute>wrapper. React Router matches/exactly first, so a guest navigating to the root is still redirected to login, while navigating to any unrecognised path accidentally reaches<HomePage />. The fix described in the PR objective — making/publicly accessible — is not actually applied to the canonical route.🐛 Proposed fix
<Route exact path="/" - element={ - <PrivateRoute> - <HomePage /> - </PrivateRoute> - } + element={<HomePage />} />Also applies to: 158-158
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@app/src/App.jsx` around lines 91 - 95, The root route is still wrapped by PrivateRoute so guests are redirected; update the route rendering the path="/" in App.jsx to render HomePage directly instead of inside PrivateRoute (i.e., replace the element that currently uses <PrivateRoute><HomePage/></PrivateRoute> with one that renders HomePage openly), ensuring the existing catch-all that renders HomePage remains unchanged.
🧹 Nitpick comments (3)
.github/actions/spelling/expect.txt (1)
133-135: Avoid allowlisting plain-language typos in the global expect list.Entries like
discription,disscussion,Insitute,jumotron, andLeetocdecan hide real spelling regressions in future changes. Prefer fixing source text where possible, and keepexpect.txtfor intentional identifiers/terms only.Also applies to: 252-252, 269-269, 289-289
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In @.github/actions/spelling/expect.txt around lines 133 - 135, Remove plain-language typos from the global spelling exception list and fix the source text instead: delete entries like "discription", "discussionpost", "disscussion", "Insitute", "jumotron", and "Leetocde" from the expect list and correct the typos in the code/docs that introduced them; reserve the expect list only for intentional identifiers/brand names that cannot be changed. Locate the occurrences by searching for those exact tokens and update the original files to the correct spellings, then rerun the spelling action to ensure no legitimate contractions remain.app/src/App.jsx (2)
34-51: HoistfetchListSafelyto module scope.The function closes over no component state or props — only the module-level
BACKENDconstant. Defining it insideAppcreates a new reference every render and causes ESLint'sreact-hooks/exhaustive-depsrule to flag it as a missing dependency in all fiveuseEffectcalls below.♻️ Proposed refactor
const BACKEND = import.meta.env.VITE_BACKEND; + +const fetchListSafely = async (endpoint, setData) => { + if (!BACKEND) { + setData([]); + return; + } + try { + const res = await fetch(BACKEND + endpoint); + const contentType = res.headers.get("content-type") || ""; + if (!res.ok || !contentType.toLowerCase().includes("application/json")) { + setData([]); + return; + } + const data = await res.json(); + setData(Array.isArray(data) ? data : []); + } catch { + setData([]); + } +}; + function App() { ... - const fetchListSafely = async (endpoint, setData) => { - ... - };🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@app/src/App.jsx` around lines 34 - 51, Move the fetchListSafely function out of the App component to module scope since it only uses the module-level BACKEND constant; this prevents a new function reference on every render and stops ESLint's react-hooks/exhaustive-deps from flagging useEffect hooks. Keep the same signature (fetchListSafely(endpoint, setData)), preserve its error handling and JSON checks, and update any internal useEffect callers in App to use the hoisted fetchListSafely directly (no prop/state closures needed). Ensure BACKEND remains accessible at module scope and that no other component-local variables are referenced from fetchListSafely before hoisting.
53-69: Consider consolidating the five fetch effects into one.All five
useEffecthooks have identical[]dependency arrays and run at the same point in the lifecycle. Collapsing them reduces noise.♻️ Proposed refactor
- useEffect(() => { - fetchListSafely("/codeforces/", setCodeforcesUsers); - }, []); - useEffect(() => { - fetchListSafely("/codechef/", setCodechefUsers); - }, []); - useEffect(() => { - fetchListSafely("/leetcode/", setLeetcodeUsers); - }, []); - useEffect(() => { - fetchListSafely("/openlake/", setOpenlakeContributor); - }, []); - useEffect(() => { - fetchListSafely("/github/", setGithubUser); - }, []); + useEffect(() => { + fetchListSafely("/codeforces/", setCodeforcesUsers); + fetchListSafely("/codechef/", setCodechefUsers); + fetchListSafely("/leetcode/", setLeetcodeUsers); + fetchListSafely("/openlake/", setOpenlakeContributor); + fetchListSafely("/github/", setGithubUser); + }, []);🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@app/src/App.jsx` around lines 53 - 69, Multiple identical useEffect calls each call fetchListSafely for different endpoints; consolidate into a single useEffect that runs once and invokes fetchListSafely for all endpoints to reduce duplication. Replace the five useEffect blocks with one useEffect that calls fetchListSafely("/codeforces/", setCodeforcesUsers), fetchListSafely("/codechef/", setCodechefUsers), fetchListSafely("/leetcode/", setLeetcodeUsers), fetchListSafely("/openlake/", setOpenlakeContributor) and fetchListSafely("/github/", setGithubUser) inside the effect callback and keep the dependency array as [] so it runs once on mount.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@app/src/components/CodeforcesTable.jsx`:
- Around line 695-704: The helper text advising "Click Add Friend on any user in
the main leaderboard" is shown to guests even though the Add Friend action is
hidden; in CodeforcesTable.jsx update the JSX conditional around that helper
paragraph to only render it when isAuthenticated is true (or when logged-in UI
is visible). Locate the fragment that renders the empty-state message (uses
isAuthenticated and loggedInUser) and wrap or replace the lower helper <p> so it
is rendered only for authenticated users, otherwise show an alternative guest
hint or nothing.
In `@app/src/Context/AuthContext.jsx`:
- Around line 44-49: AuthContext currently calls jwtDecode directly (e.g., when
initializing user from authTokens and in other places) which can crash on
malformed tokens; implement a safe helper like safeJwtDecode(token) that returns
decoded payload or null on any error, then replace all direct jwtDecode usages
(the initialization that sets user from authTokens, plus the other call sites
referenced in this file) with safeJwtDecode to ensure startup and runtime code
paths (e.g., where authTokens is read/decoded) never throw—update references in
AuthContext.jsx for the five jwtDecode call sites so they all use the helper.
---
Outside diff comments:
In `@app/src/App.jsx`:
- Line 126: Remove the stray hyphen text node after the Profile component
render; locate the JSX fragment where <Profile /> is rendered in App.jsx and
delete the trailing "-" so the element reads only <Profile /> to prevent the
literal hyphen from displaying on the /profile page.
- Around line 91-95: The root route is still wrapped by PrivateRoute so guests
are redirected; update the route rendering the path="/" in App.jsx to render
HomePage directly instead of inside PrivateRoute (i.e., replace the element that
currently uses <PrivateRoute><HomePage/></PrivateRoute> with one that renders
HomePage openly), ensuring the existing catch-all that renders HomePage remains
unchanged.
In `@app/src/components/CodechefTable.jsx`:
- Around line 108-123: The getccfriends function (and similar functions in lines
125-169) must defensively handle network and non-JSON responses: wrap the fetch
+ response.json() in a try/catch, check response.ok before parsing, verify the
Content-Type includes "application/json" (or handle non-JSON by falling back),
and on any error setCodecheffriends([]) and log or surface the error; ensure the
Authorization header and BACKEND + "/codechefFL/" call are preserved and that
successful JSON results still call setCodecheffriends(newData).
In `@app/src/components/GithubTable.jsx`:
- Around line 100-115: The getghfriends function currently assumes fetch
succeeds and response is JSON; wrap the fetch+parsing in a try/catch, check
response.ok and the Content-Type header before calling response.json(), and on
any failure fall back to setGithubfriends([]) and optionally log the error;
apply the same pattern to the other GitHub API handlers in this file (the
functions around lines where getghfriends is defined) so each handler verifies
response.ok, checks response.headers.get("content-type") includes
"application/json" before parsing, and catches network/parse errors to avoid
unhandled exceptions.
In `@app/src/components/LeetcodeTable.jsx`:
- Around line 112-127: Wrap the network and parsing logic in getltfriends with
robust guards: check accessToken as before, then perform fetch inside a
try/catch, verify response.ok and that response.headers.get("content-type")
includes "application/json" before calling await response.json(); on any failure
(non-ok response, missing/invalid content-type, or JSON parse error) catch the
error and call setLeetcodefriends([]) (or a safe fallback) and optionally log
the error; apply the same pattern to the other friend-related handlers in this
file (lines ~129-172) to prevent crashes from non-JSON or error responses.
In `@app/src/components/OpenlakeTable.jsx`:
- Around line 76-91: The getccfriends function currently calls fetch and
response.json() without error handling; wrap the network call and JSON parsing
in a try/catch, check response.ok before calling response.json(), and fall back
to reading response.text() or returning an empty array when the content is
non-JSON or the status is not ok; ensure errors and non-JSON responses do not
throw (log them) and call setOLFriends([]) on failure. Apply the same pattern to
the add/remove endpoints referenced in the file so all fetch calls using
BACKEND, accessToken, and state updaters like setOLFriends are guarded and
resilient to network/HTML/error responses.
---
Nitpick comments:
In @.github/actions/spelling/expect.txt:
- Around line 133-135: Remove plain-language typos from the global spelling
exception list and fix the source text instead: delete entries like
"discription", "discussionpost", "disscussion", "Insitute", "jumotron", and
"Leetocde" from the expect list and correct the typos in the code/docs that
introduced them; reserve the expect list only for intentional identifiers/brand
names that cannot be changed. Locate the occurrences by searching for those
exact tokens and update the original files to the correct spellings, then rerun
the spelling action to ensure no legitimate contractions remain.
In `@app/src/App.jsx`:
- Around line 34-51: Move the fetchListSafely function out of the App component
to module scope since it only uses the module-level BACKEND constant; this
prevents a new function reference on every render and stops ESLint's
react-hooks/exhaustive-deps from flagging useEffect hooks. Keep the same
signature (fetchListSafely(endpoint, setData)), preserve its error handling and
JSON checks, and update any internal useEffect callers in App to use the hoisted
fetchListSafely directly (no prop/state closures needed). Ensure BACKEND remains
accessible at module scope and that no other component-local variables are
referenced from fetchListSafely before hoisting.
- Around line 53-69: Multiple identical useEffect calls each call
fetchListSafely for different endpoints; consolidate into a single useEffect
that runs once and invokes fetchListSafely for all endpoints to reduce
duplication. Replace the five useEffect blocks with one useEffect that calls
fetchListSafely("/codeforces/", setCodeforcesUsers),
fetchListSafely("/codechef/", setCodechefUsers), fetchListSafely("/leetcode/",
setLeetcodeUsers), fetchListSafely("/openlake/", setOpenlakeContributor) and
fetchListSafely("/github/", setGithubUser) inside the effect callback and keep
the dependency array as [] so it runs once on mount.
ℹ️ Review info
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (11)
.github/actions/spelling/excludes.txt.github/actions/spelling/expect.txtapp/src/App.jsxapp/src/Context/AuthContext.jsxapp/src/components/CodechefTable.jsxapp/src/components/CodeforcesTable.jsxapp/src/components/GithubTable.jsxapp/src/components/HomePage.jsxapp/src/components/LeetcodeTable.jsxapp/src/components/NavMenu.jsxapp/src/components/OpenlakeTable.jsx
@check-spelling-bot Report🔴 Please reviewSee the 📂 files view, the 📜action log, or 📝 job summary for details.Unrecognized words (15)These words are not needed and should be removedleetcoderankingccpsSome files were automatically ignored 🙈These sample patterns would exclude them: You should consider adding them to: File matching is via Perl regular expressions. To check these files, more of their words need to be in the dictionary than not. You can use To accept these unrecognized words as correct, update file exclusions, and remove the previously acknowledged and now absent words, you could run the following commands... in a clone of the git@github.com:VarshiniGunti/Leaderboard-Pro.git repository curl -s -S -L 'https://raw.githubusercontent.com/check-spelling/check-spelling/main/apply.pl' |
perl - 'https://github.com/OpenLake/Leaderboard-Pro/actions/runs/22405318286/attempts/1' &&
git commit -m 'Update check-spelling metadata'Available 📚 dictionaries could cover words (expected and unrecognized) not in the 📘 dictionaryThis includes both expected items (592) from .github/actions/spelling/expect.txt and unrecognized words (15)
Consider adding them (in with:
extra_dictionaries: |
cspell:django/dict/django.txt
cspell:software-terms/dict/softwareTerms.txt
cspell:python/src/common/extra.txt
cspell:npm/dict/npm.txt
cspell:fullstack/dict/fullstack.txtTo stop checking additional dictionaries, add (in check_extra_dictionaries: ""Warnings
|
| Count | |
|---|---|
| 1 |
See
If you see a bunch of garbage
If it relates to a ...
well-formed pattern
See if there's a pattern that would match it.
If not, try writing one and adding it to the patterns.txt file.
Patterns are Perl 5 Regular Expressions - you can test yours before committing to verify it will match your lines.
Note that patterns can't match multiline strings.
binary-ish string
Please add a file path to the excludes.txt file instead of just accepting the garbage.
File paths are Perl 5 Regular Expressions - you can test yours before committing to verify it will match your files.
^ refers to the file's path from the root of the repository, so ^README\.md$ would exclude README.md (on whichever branch you're using).
Fix: #182 Guest Access + Auth Null Crash Hardening
What this PR fixes
This PR resolves the crash for unauthenticated users and enables proper guest access across the app.
Key improvements
userNamesis missing.Cannot read properties of null.//codeforces/codechef/github/leetcode/openlakeUnexpected token '<').Why this matters
Users can now explore the platform as guests without blank-screen failures, while authenticated actions remain protected. This improves reliability, onboarding, and UX consistency across auth states.
Verification completed