Repository navigation
-Added complete Google OAuth flow for login and signup - #72
Conversation
-Fixed token generation using appropriate create_access_token() function -Generated secure random passwords for Google OAuth users -Made usernames unique with random suffixes -Added proper error handling for OAuth callback -Integrated with existing authentication system
👷 Deploy request for u-connect pending review.Visit the deploys page to approve it
|
📝 WalkthroughSummary by CodeRabbit
WalkthroughBeep. New Google OAuth flow added. Backend mounts google_auth router, enables sessions, and allows nullable user passwords. Frontend wraps app with GoogleOAuthProvider, updates Login page to use GoogleLogin and handle token redirect. Package dependency added. .gitignore whitespace adjusted. Changes
Sequence Diagram(s)sequenceDiagram
autonumber
participant U as User Browser
participant F as Frontend (Login.jsx)
participant G as Google OAuth
participant B as Backend (/auth/google)
participant DB as Database
U->>F: Click "Sign in with Google"
F->>B: GET /auth/google/login
B-->>U: 302 Redirect to Google
U->>G: OAuth consent + auth code
G-->>B: Redirect to /auth/google/callback?code=...
B->>G: Exchange code for tokens
G-->>B: Tokens + userinfo
B->>DB: Find or create User (nullable password)
DB-->>B: User record
B-->>U: 302 Redirect to Frontend with ?token=JWT
U->>F: Load app with token
F->>F: Store token (localStorage) and navigate to dashboard
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Poem
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✨ Finishing touches
🧪 Generate unit tests
Warning There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure. 🔧 Ruff (0.13.1)backend/main.py�[1;31mruff failed�[0m backend/models/user.py�[1;31mruff failed�[0m backend/routes/google_auth.py�[1;31mruff failed�[0m Tip 👮 Agentic pre-merge checks are now available in preview!Pro plan users can now enable pre-merge checks in their settings to enforce checklists before merging PRs.
Please see the documentation for more information. Example: reviews:
pre_merge_checks:
custom_checks:
- name: "Undocumented Breaking Changes"
mode: "warning"
instructions: |
Pass/fail criteria: All breaking changes to public APIs, CLI flags, environment variables, configuration keys, database schemas, or HTTP/GraphQL endpoints must be documented in the "Breaking Change" section of the PR description and in CHANGELOG.md. Exclude purely internal or private changes (e.g., code not exported from package entry points or explicitly marked as internal).Please share your feedback with us on this Discord post. 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 |
There was a problem hiding this comment.
Actionable comments posted: 14
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
frontend/src/pages/Login.jsx (2)
124-135: Replace GoogleLogin component with a plain redirect button (server‑redirect mode).Simple, deterministic, no mixed flows.
- <button - type="button" - className="w-full flex items-center justify-center gap-2 border border-gray-300 rounded-full py-2 mb-3 hover:bg-gray-100" - > - - <GoogleLogin - onSuccess={handleGoogleSuccess} - onError={() => setError("Google login failed")} - useOneTap - /> - </button> + <button + type="button" + onClick={() => { window.location.href = `${import.meta.env.VITE_API_URL}/auth/google/login`; }} + className="w-full flex items-center justify-center gap-2 border border-gray-300 rounded-full py-2 mb-3 hover:bg-gray-100" + aria-label="Continue with Google" + > + <img alt="" src="https://www.gstatic.com/images/branding/product/1x/gsa_64dp.png" className="w-5 h-5" /> + <span>Continue with Google</span> + </button>
64-96: Remove token/user PII logs.Avoid leaking secrets in console.
- console.log("Token stored:", data.access_token); @@ - console.log("User response:", userResponse); - console.log("User data:", userResponse.data); @@ - console.log("Extracted user data:", { userId, userEmail, userName }); @@ - console.log("localStorage after setting:", { - user_id: localStorage.getItem("user_id"), - user_email: localStorage.getItem("user_email"), - username: localStorage.getItem("username"), - });
📜 Review details
Configuration used: CodeRabbit UI
Review profile: ASSERTIVE
Plan: Pro
📒 Files selected for processing (8)
.gitignore(0 hunks)backend/main.py(2 hunks)backend/models/user.py(1 hunks)backend/routes/google_auth.py(1 hunks)frontend/package.json(1 hunks)frontend/src/App.jsx(1 hunks)frontend/src/index.jsx(1 hunks)frontend/src/pages/Login.jsx(3 hunks)
💤 Files with no reviewable changes (1)
- .gitignore
🧰 Additional context used
🧬 Code graph analysis (3)
frontend/src/pages/Login.jsx (3)
frontend/src/api/axios.js (1)
token(15-15)frontend/src/api.js (1)
token(17-17)frontend/src/api/auth.js (1)
token(10-10)
frontend/src/index.jsx (1)
frontend/src/App.jsx (1)
GOOGLE_CLIENT_ID(18-18)
backend/routes/google_auth.py (2)
backend/models/user.py (1)
User(8-43)backend/core/security.py (2)
create_access_token(25-29)hash_password(17-18)
🔇 Additional comments (2)
backend/main.py (1)
38-38: Router mount LGTM.Mount path is correct and isolated under /auth/google.
frontend/package.json (1)
15-15: Verify compatibility: @react-oauth/google@^0.12.2 — React 19 OK; Vite 6 unverifiedPeer deps require react & react-dom >=16.8.0 → React 19 is satisfied. The package does not explicitly claim Vite/Vite 6 support and community threads report COOP/COEP / dev-server header issues that can affect Vite builds. Action: run full integration tests with Vite 6 (dev server + production build) or confirm absence of Vite-related issues in the upstream repo before merging.
Location: frontend/package.json (line 15).
| allow_methods=["*"], # Allow all methods (GET, POST, etc.) | ||
| allow_headers=["*"], # Allow all headers | ||
| ) | ||
| app.add_middleware(SessionMiddleware, secret_key="your_super_secret_key") |
There was a problem hiding this comment.
Hardcoded session secret. Danger detected.
Use env + secure cookie flags. This backs Authlib state protection.
+import os
@@
-app.add_middleware(SessionMiddleware, secret_key="your_super_secret_key")
+app.add_middleware(
+ SessionMiddleware,
+ secret_key=os.getenv("SESSION_SECRET_KEY", "change-me-in-prod"),
+ same_site="lax",
+ https_only=True,
+)📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| app.add_middleware(SessionMiddleware, secret_key="your_super_secret_key") | |
| import os | |
| app.add_middleware( | |
| SessionMiddleware, | |
| secret_key=os.getenv("SESSION_SECRET_KEY", "change-me-in-prod"), | |
| same_site="lax", | |
| https_only=True, | |
| ) |
🤖 Prompt for AI Agents
In backend/main.py around line 31, the app currently uses a hardcoded session
secret; replace that with a secret read from the environment (e.g.
SESSION_SECRET) and fail fast if it's missing, and when adding SessionMiddleware
set secure cookie flags (secure=True, httponly=True, samesite='lax' or 'strict')
so the session cookie is only sent over HTTPS and not accessible from JS; keep
the secret coming from os.environ (no hardcoded fallback in production) and
ensure the middleware call uses the env secret and the secure cookie options.
| username = Column(String, unique=True, index=True, nullable=False) | ||
| email = Column(String, unique=True, index=True, nullable=False) | ||
| hashed_password = Column(String, nullable=False) | ||
| hashed_password = Column(String, nullable=True) |
There was a problem hiding this comment.
🧩 Analysis chain
Reconsider making hashed_password nullable. Integrity compromised.
Current flow always sets a random password for Google users. Keep NOT NULL and migrate existing rows, or justify nulls and harden all auth paths accordingly.
- hashed_password = Column(String, nullable=True)
+ hashed_password = Column(String, nullable=False)🏁 Script executed:
#!/bin/bash
# Scan for places assuming non-null hashed_password or comparing to None.
rg -nP --type=py -C2 '\bhashed_password\b'Length of output: 7200
Make hashed_password NOT NULL and backfill existing rows
Auth paths assume a password exists (verify_password uses user.hashed_password; Google flow writes a hashed password). Backfill any NULL hashed_password rows (generate secure random passwords and hash them, or set an unusable hash + force reset) before altering the column to NOT NULL.
- hashed_password = Column(String, nullable=True)
+ hashed_password = Column(String, nullable=False)Locations: backend/models/user.py; backend/services/AuthHandler.py (verify_password usage); backend/routes/google_auth.py (hashed_password assignment); backend/tests/* (fixtures may need updates).
Committable suggestion skipped: line range outside the PR's diff.
| from fastapi import APIRouter, Request, Depends, HTTPException | ||
| from fastapi.responses import RedirectResponse | ||
| from authlib.integrations.starlette_client import OAuth | ||
| from starlette.config import Config | ||
| from starlette.requests import Request | ||
| from sqlalchemy.orm import Session | ||
| from core.dependencies import get_db | ||
| from models.user import User | ||
| from services.AuthHandler import AuthHandler | ||
| from core.security import create_access_token | ||
| import os | ||
|
|
||
| router = APIRouter() |
There was a problem hiding this comment.
🧹 Nitpick
Tidy imports. Remove duplicates/unused.
- Duplicate Request import.
- Unused AuthHandler.
- SECRET_KEY in config_data unused.
-from fastapi import APIRouter, Request, Depends, HTTPException
-from fastapi.responses import RedirectResponse
-from authlib.integrations.starlette_client import OAuth
-from starlette.config import Config
-from starlette.requests import Request
-from sqlalchemy.orm import Session
-from core.dependencies import get_db
-from models.user import User
-from services.AuthHandler import AuthHandler
-from core.security import create_access_token
-import os
+from fastapi import APIRouter, Request, Depends, HTTPException
+from fastapi.responses import RedirectResponse
+from authlib.integrations.starlette_client import OAuth
+from starlette.config import Config
+from sqlalchemy.orm import Session
+from sqlalchemy import exists
+from core.dependencies import get_db
+from models.user import User
+from core.security import create_access_token
+import os📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| from fastapi import APIRouter, Request, Depends, HTTPException | |
| from fastapi.responses import RedirectResponse | |
| from authlib.integrations.starlette_client import OAuth | |
| from starlette.config import Config | |
| from starlette.requests import Request | |
| from sqlalchemy.orm import Session | |
| from core.dependencies import get_db | |
| from models.user import User | |
| from services.AuthHandler import AuthHandler | |
| from core.security import create_access_token | |
| import os | |
| router = APIRouter() | |
| from fastapi import APIRouter, Request, Depends, HTTPException | |
| from fastapi.responses import RedirectResponse | |
| from authlib.integrations.starlette_client import OAuth | |
| from starlette.config import Config | |
| from sqlalchemy.orm import Session | |
| from sqlalchemy import exists | |
| from core.dependencies import get_db | |
| from models.user import User | |
| from core.security import create_access_token | |
| import os | |
| router = APIRouter() |
🤖 Prompt for AI Agents
In backend/routes/google_auth.py around lines 1 to 13, tidy up imports by
removing the duplicate Request import (keep only one from fastapi or starlette
as needed), remove the unused AuthHandler import, and delete or stop populating
the unused SECRET_KEY entry in any config_data or Config usage; ensure remaining
imports are minimal and only include Request, APIRouter, Depends, HTTPException,
RedirectResponse, OAuth, Config (if used), Session, get_db, User,
create_access_token, and os as required.
| config_data = { | ||
| "GOOGLE_CLIENT_ID": os.getenv("GOOGLE_CLIENT_ID"), | ||
| "GOOGLE_CLIENT_SECRET": os.getenv("GOOGLE_CLIENT_SECRET"), | ||
| "SECRET_KEY": os.getenv("SECRET_KEY", "secret"), | ||
| } | ||
| config = Config(environ=config_data) | ||
| oauth = OAuth(config) |
There was a problem hiding this comment.
🛠️ Refactor suggestion
Validate env at startup. Fail fast if missing.
Ensure client id/secret present to avoid runtime 500s.
config_data = {
"GOOGLE_CLIENT_ID": os.getenv("GOOGLE_CLIENT_ID"),
"GOOGLE_CLIENT_SECRET": os.getenv("GOOGLE_CLIENT_SECRET"),
- "SECRET_KEY": os.getenv("SECRET_KEY", "secret"),
}
config = Config(environ=config_data)
+if not config_data["GOOGLE_CLIENT_ID"] or not config_data["GOOGLE_CLIENT_SECRET"]:
+ raise RuntimeError("GOOGLE_CLIENT_ID/GOOGLE_CLIENT_SECRET must be set")📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| config_data = { | |
| "GOOGLE_CLIENT_ID": os.getenv("GOOGLE_CLIENT_ID"), | |
| "GOOGLE_CLIENT_SECRET": os.getenv("GOOGLE_CLIENT_SECRET"), | |
| "SECRET_KEY": os.getenv("SECRET_KEY", "secret"), | |
| } | |
| config = Config(environ=config_data) | |
| oauth = OAuth(config) | |
| config_data = { | |
| "GOOGLE_CLIENT_ID": os.getenv("GOOGLE_CLIENT_ID"), | |
| "GOOGLE_CLIENT_SECRET": os.getenv("GOOGLE_CLIENT_SECRET"), | |
| "SECRET_KEY": os.getenv("SECRET_KEY"), | |
| } | |
| if not config_data["GOOGLE_CLIENT_ID"] or not config_data["GOOGLE_CLIENT_SECRET"]: | |
| raise RuntimeError("GOOGLE_CLIENT_ID/GOOGLE_CLIENT_SECRET must be set") | |
| config = Config(environ=config_data) | |
| oauth = OAuth(config) |
🤖 Prompt for AI Agents
In backend/routes/google_auth.py around lines 15 to 21, the code constructs an
OAuth Config from environment variables but does not validate that
GOOGLE_CLIENT_ID and GOOGLE_CLIENT_SECRET are set; add a startup validation that
reads those two vars, and if either is missing log a clear error and fail fast
(raise a RuntimeError or call sys.exit(1)) with a descriptive message so the
application does not start and later produce 500s; leave SECRET_KEY default
behavior intact or validate it similarly if desired.
| @router.get("/login") | ||
| async def google_login(request: Request): | ||
| redirect_uri = os.getenv("GOOGLE_REDIRECT_URI") | ||
| return await oauth.google.authorize_redirect(request, redirect_uri) | ||
|
|
There was a problem hiding this comment.
🛠️ Refactor suggestion
Compute redirect URI via url_for. Robustness++
Avoid hardcoding GOOGLE_REDIRECT_URI; derive from routing.
@router.get("/login")
async def google_login(request: Request):
- redirect_uri = os.getenv("GOOGLE_REDIRECT_URI")
+ # Build absolute callback URL under current host
+ redirect_uri = str(request.url_for("google_callback"))
return await oauth.google.authorize_redirect(request, redirect_uri)📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| @router.get("/login") | |
| async def google_login(request: Request): | |
| redirect_uri = os.getenv("GOOGLE_REDIRECT_URI") | |
| return await oauth.google.authorize_redirect(request, redirect_uri) | |
| @router.get("/login") | |
| async def google_login(request: Request): | |
| # Build absolute callback URL under current host | |
| redirect_uri = str(request.url_for("google_callback")) | |
| return await oauth.google.authorize_redirect(request, redirect_uri) |
🤖 Prompt for AI Agents
In backend/routes/google_auth.py around lines 30 to 34, the redirect URI is
currently pulled from the environment; instead compute it from the router/app
routes to avoid hardcoding. Use the request.url_for (or
request.app.url_path_for) with the callback endpoint name (e.g.,
"google_callback") to build the full redirect URI and pass that to
oauth.google.authorize_redirect; keep a fallback to the env var if url_for
fails, and ensure the callback route is named or registered so url_for resolves
correctly.
| import { GoogleOAuthProvider } from '@react-oauth/google'; | ||
|
|
||
| const GOOGLE_CLIENT_ID = import.meta.env.VITE_GOOGLE_CLIENT_ID; | ||
|
|
||
| ReactDOM.createRoot(document.getElementById("root")).render( | ||
| <App /> | ||
| <GoogleOAuthProvider clientId={GOOGLE_CLIENT_ID}> | ||
| <App /> | ||
| </GoogleOAuthProvider> | ||
| ); |
There was a problem hiding this comment.
🧩 Analysis chain
Decide the flow: backend-redirect OR One‑Tap. Do not mix.
If you keep server‑redirect, you do not need GoogleOAuthProvider at all. If you keep One‑Tap, do not redirect in Login.jsx. Pick one.
Do you plan to use server‑redirect (Authlib) exclusively? If yes, I will generate a cleanup patch to remove the provider and dependency.
Affirmative. Initiating code inspection.
🏁 Script executed:
#!/bin/bash
# Locate Login.jsx in frontend source
LOGIN_FILE=$(find frontend/src -type f -name "Login.jsx" | head -n1)
echo "Login file: $LOGIN_FILE"
# Inspect for client-side redirect usage
if [[ -n "$LOGIN_FILE" ]]; then
rg -n "redirect" "$LOGIN_FILE" || echo "No 'redirect' usage found"
rg -n "location" "$LOGIN_FILE" || echo "No 'location' usage found"
else
echo "Login.jsx not found"
fi
# Check for One-Tap references and provider imports
rg -n "OneTap" -tjs frontend/src || echo "No OneTap references found"
rg -n "@react-oauth/google" -tjs frontend/src || echo "No provider import references found"Length of output: 639
Choose one auth flow: backend-redirect OR One‑Tap — do not mix.
Detected mixing in repo:
- frontend/src/pages/Login.jsx — server redirect: window.location.href =
${import.meta.env.VITE_API_URL}/auth/google/login(line 21); client redirect to "/dashboard/posts" (line 43). - frontend/src/pages/Login.jsx — imports GoogleLogin, googleLogout (line 7) and uses useOneTap (line 132).
- frontend/src/index.jsx — imports GoogleOAuthProvider (line 5).
Action required:
- Pick one flow.
- Backend-redirect: remove GoogleOAuthProvider and all @react-oauth/google usages (index.jsx and pages/Login.jsx imports/usages).
- One‑Tap: remove the server redirect in Login.jsx and use client-side One‑Tap token flow exclusively.
I will generate a cleanup patch to remove the provider and client One‑Tap code if you confirm server-redirect only.
🤖 Prompt for AI Agents
In frontend/src/index.jsx around lines 5-13 there is a GoogleOAuthProvider
wrapper while the app also uses a server-redirect flow in pages/Login.jsx — you
must not mix One‑Tap/client SDK and backend-redirect. Pick backend-redirect:
remove the GoogleOAuthProvider and any @react-oauth/google import/usages from
frontend/src/index.jsx (replace the wrapped render with a plain App render) and
then in frontend/src/pages/Login.jsx remove GoogleLogin, googleLogout imports
and any useOneTap/One‑Tap-related code paths so only the server redirect
(window.location.href = `${import.meta.env.VITE_API_URL}/auth/google/login`)
remains; ensure no leftover references to the provider/SDK and run the app to
verify login still redirects to the backend endpoint.
| import './index.css'; | ||
| import { GoogleOAuthProvider } from '@react-oauth/google'; | ||
|
|
||
| const GOOGLE_CLIENT_ID = import.meta.env.VITE_GOOGLE_CLIENT_ID; |
There was a problem hiding this comment.
🧹 Nitpick
Guard missing client ID to fail fast.
Emit a warning if VITE_GOOGLE_CLIENT_ID is absent.
-const GOOGLE_CLIENT_ID = import.meta.env.VITE_GOOGLE_CLIENT_ID;
+const GOOGLE_CLIENT_ID = import.meta.env.VITE_GOOGLE_CLIENT_ID;
+if (!GOOGLE_CLIENT_ID) {
+ console.warn("VITE_GOOGLE_CLIENT_ID is missing. Google login will not work.");
+}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| const GOOGLE_CLIENT_ID = import.meta.env.VITE_GOOGLE_CLIENT_ID; | |
| const GOOGLE_CLIENT_ID = import.meta.env.VITE_GOOGLE_CLIENT_ID; | |
| if (!GOOGLE_CLIENT_ID) { | |
| console.warn("VITE_GOOGLE_CLIENT_ID is missing. Google login will not work."); | |
| } |
🤖 Prompt for AI Agents
In frontend/src/index.jsx around line 7, the GOOGLE_CLIENT_ID is read directly
from import.meta.env without a guard; add a runtime check right after this line
that verifies VITE_GOOGLE_CLIENT_ID is present and non-empty, and if not call
console.warn with a clear message about the missing env var and stop further
Google auth initialization (fail fast by returning early or throwing an Error
depending on surrounding flow) so the app emits a warning and avoids continuing
with an undefined client ID.
| import axios from "axios"; | ||
| import { useAuth } from "../context/AuthContext"; | ||
| import Navbar from "../components/Navbar"; | ||
| import { GoogleLogin, googleLogout } from '@react-oauth/google'; |
There was a problem hiding this comment.
🧹 Nitpick
Remove unused import.
googleLogout is not used.
-import { GoogleLogin, googleLogout } from '@react-oauth/google';
+import { GoogleLogin } from '@react-oauth/google';📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| import { GoogleLogin, googleLogout } from '@react-oauth/google'; | |
| import { GoogleLogin } from '@react-oauth/google'; |
🤖 Prompt for AI Agents
In frontend/src/pages/Login.jsx around line 7, the import statement includes
googleLogout which is not used; remove googleLogout from the import (keep
GoogleLogin) to eliminate the unused import and update any related code/comments
if needed.
| const handleGoogleSuccess = async (credentialResponse) => { | ||
| try { | ||
| // Option 1: Use backend OAuth flow (recommended) | ||
| window.location.href = `${import.meta.env.VITE_API_URL}/auth/google/login`; | ||
|
|
||
| // Option 2: If using Google One Tap and want to POST token to backend: | ||
| // const { credential } = credentialResponse; | ||
| // const res = await axios.post(`${import.meta.env.VITE_API_URL}/auth/google/onetap`, { token: credential }); | ||
| // Handle login as usual with res.data.access_token | ||
| } catch (error) { | ||
| setError("Google login failed"); | ||
| } | ||
| }; |
There was a problem hiding this comment.
Flow mismatch: GoogleLogin onSuccess triggers server redirect. Illogical.
Pick one:
- Server‑redirect (Authlib): no GoogleLogin; just a button/link to /auth/google/login.
- One‑Tap: keep GoogleLogin and POST credential to backend /onetap.
Current mix will misfire. Recommend server‑redirect cleanup below.
- const handleGoogleSuccess = async (credentialResponse) => {
- try {
- // Option 1: Use backend OAuth flow (recommended)
- window.location.href = `${import.meta.env.VITE_API_URL}/auth/google/login`;
-
- // Option 2: If using Google One Tap and want to POST token to backend:
- // const { credential } = credentialResponse;
- // const res = await axios.post(`${import.meta.env.VITE_API_URL}/auth/google/onetap`, { token: credential });
- // Handle login as usual with res.data.access_token
- } catch (error) {
- setError("Google login failed");
- }
- };
+ // If using server-redirect, no handler needed here.Committable suggestion skipped: line range outside the PR's diff.
🤖 Prompt for AI Agents
In frontend/src/pages/Login.jsx around lines 18 to 30, the Google login handler
mixes two incompatible flows: it triggers a server redirect while being used as
a GoogleLogin onSuccess handler. Remove the redirect from the onSuccess handler
and choose one flow: either replace the GoogleLogin control with a plain
link/button that navigates to
`${import.meta.env.VITE_API_URL}/auth/google/login` (server OAuth redirect
flow), or keep the GoogleLogin component and change the handler to POST the
credential to your backend endpoint (e.g. `/auth/google/onetap`) and handle the
returned token; implement the chosen flow consistently and remove the
dead/commented alternative to avoid confusion.
| useEffect(() => { | ||
| const params = new URLSearchParams(window.location.search); | ||
| const token = params.get("token"); | ||
| if (token) { | ||
| localStorage.setItem("token", token); | ||
| // Optionally fetch user and redirect | ||
| window.location.href = "/dashboard/posts"; | ||
| } | ||
| }, []); |
There was a problem hiding this comment.
🧹 Nitpick
Token via query string works, but leaks via Referer.
Safer options:
- Use URL fragment (#token=...) and parse it.
- Or set HttpOnly cookie from backend and redirect without token.
Front/back must align.
Do you prefer fragment or cookie? I can patch both sides accordingly.
🤖 Prompt for AI Agents
In frontend/src/pages/Login.jsx around lines 37 to 45 the current implementation
reads the auth token from the query string and stores it in localStorage then
redirects, which leaks the token via Referer; change to one of two safer flows:
(A) Client-side fragment flow — read token from window.location.hash (e.g. parse
#token=...), store it in localStorage/sessionStorage, then remove the fragment
from the URL (history.replaceState) before redirecting so the token never
appears in Referer; or (B) Server-set HttpOnly cookie flow — stop passing token
in the URL, have the backend set an HttpOnly, Secure cookie on successful auth
and simply redirect to /dashboard/posts (client reads no token), update backend
and front to rely on cookie-based auth; choose fragment if you want minimal
backend work or cookie if you prefer maximal security and update both sides
accordingly.
f893e31
into
Learnathon-By-Geeky-Solutions:main
-Fixed token generation using appropriate create_access_token() function -Generated secure random passwords for Google OAuth users -Made usernames unique with random suffixes
-Added proper error handling for OAuth callback
-Integrated with existing authentication system