Skip to content

Staging#80

Merged
Shashank0701-byte merged 6 commits intomainfrom
staging
Mar 15, 2026
Merged

Staging#80
Shashank0701-byte merged 6 commits intomainfrom
staging

Conversation

@Shashank0701-byte
Copy link
Owner

@Shashank0701-byte Shashank0701-byte commented Mar 15, 2026

Summary by CodeRabbit

  • New Features

    • Email/password sign-up, sign-in, and password reset added alongside Google/GitHub
    • Account creation captures display name with inline success/error messaging
    • Multi-path auth UI: sign in, sign up, and reset-password flows with provider-specific loading states
  • Improvements

    • Auto-redirect to dashboard after authentication or successful sign-in
    • Navbar hides auth prompts on auth pages and updates primary CTA to sign-up
    • Improved form validation and clearer user feedback during flows

@vercel
Copy link

vercel bot commented Mar 15, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
system-craft Ready Ready Preview, Comment Mar 15, 2026 2:46pm

@coderabbitai
Copy link

coderabbitai bot commented Mar 15, 2026

📝 Walkthrough

Walkthrough

Adds email/password signup, signin, and password-reset flows across Firebase helpers, the AuthCard UI (multi-path auth + state/redirects), and the User model; Navbar hides auth CTAs on auth pages and Get Started links to /signup.

Changes

Cohort / File(s) Summary
Auth UI (multi-path)
components/AuthCard.tsx
Replaces single-path flow with multi-path email/Google/GitHub auth: adds email/password form state, displayName, reset-password UI, per-provider loading, success/error messaging, navigation guards, and calls syncUserWithDB(...,'email').
Navbar adjustments
components/Navbar.tsx
Adds pathname check to hide auth CTAs on /login and /signup; shows loading skeleton when auth loading; updates Get Started link to /signup.
Firebase email auth helpers
src/lib/firebase/auth.ts
Adds signUpWithEmail, signInWithEmail, and resetPassword using Firebase email/password APIs with mapped error messages and logging.
DB model update
src/lib/db/models/User.ts
Extends IUser and UserSchema provider enum to include 'email'.

Sequence Diagram

sequenceDiagram
    participant User
    participant AuthCard
    participant Firebase as "Firebase Auth"
    participant DB as "MongoDB"
    participant Context as "AuthContext"

    User->>AuthCard: submit email + password (+ displayName) / request reset
    AuthCard->>Firebase: signUpWithEmail / signInWithEmail / resetPassword
    Firebase-->>AuthCard: returns User / ack reset
    AuthCard->>DB: syncUserWithDB(user, 'email')
    DB-->>AuthCard: user persisted
    AuthCard->>Context: update auth state
    Context-->>AuthCard: auth state confirmed
    AuthCard-->>User: show success / redirect to dashboard
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

  • Staging #2 — Modifies the same authentication surface (components/AuthCard.tsx, components/Navbar.tsx, src/lib/firebase/auth.ts); likely overlapping auth-flow work.
  • Staging #4 — Overlaps in AuthCard/firebase auth changes and error-handling around sign-in/up flows.

Poem

🐰 I hopped through keys and DX light,

Emails, passwords—now they take flight,
Firebase carrots, DB burrows snug,
Buttons hide where logins once tug,
A little hop, a successful sight! 🥕

🚥 Pre-merge checks | ✅ 1 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 33.33% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Title check ❓ Inconclusive The title 'Staging' is vague and generic, not descriptive of the actual changes made in the pull request. Provide a descriptive title that summarizes the main change, such as 'Add email/password authentication support' or 'Implement multi-path authentication flow with email signup/login'.
✅ Passed checks (1 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch staging
📝 Coding Plan
  • Generate coding plan for human review comments

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
components/Navbar.tsx (1)

53-67: ⚠️ Potential issue | 🟡 Minor

Point the primary CTA at /signup.

With the new email sign-up flow in this PR, Get Started still routes unauthenticated users to /login, so the main navbar CTA drops new users on the wrong screen.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@components/Navbar.tsx` around lines 53 - 67, Update the primary CTA in
components/Navbar.tsx so unauthenticated users are routed to the signup flow:
change the href on the "Get Started" Link (the second Link inside the JSX branch
where isAuthPage ? null : !user) from "/login" to "/signup" while keeping the
same className and styling; ensure the "Sign In" Link remains pointing to
"/login" and only the "Get Started" Link is updated.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@components/AuthCard.tsx`:
- Around line 57-63: The redirect effect currently triggers on raw auth state
(useEffect using authLoading and currentUser); change it to wait for a
successful DB sync flag instead: introduce or use an existing "userSynced" /
"syncSuccess" boolean set by syncUserWithDB (or set on successful resolution
inside the sign-in flow), then update the useEffect condition to require
!authLoading && currentUser && userSynced before calling
router.push('/dashboard') and include userSynced in the dependency array;
likewise, update the sign-in success/unmount logic (the handler around
syncUserWithDB referenced at lines ~153-163) to set that same flag only on
successful sync and gate any unmount/next-step behavior on it so failures don’t
cause premature navigation or unmounting of AuthCard.
- Around line 91-116: The frontend now passes provider: 'email' from
handleEmailSubmit via syncUserWithDB but the backend model and API only allow
'google' | 'github', causing sync failures; update the backend contract to
include 'email' by: adding 'email' to the provider union/type in
src/lib/db/models/User.ts (the User model/type), and updating
app/api/user/route.ts to accept and validate 'email' in the upsert/write logic
so posted provider values from signInWithEmail/signUpWithEmail are persisted
without error. Ensure any type guards, DB upsert fields, and tests are adjusted
accordingly.

In `@src/lib/firebase/auth.ts`:
- Around line 79-84: signUpWithEmail creates the Firebase user first then
updates the profile, so if updateProfile(res.user, { displayName }) throws the
new account remains and future signups will error; catch errors from
updateProfile (and any post-create steps) and call deleteUser(res.user) to
remove the partially created account before rethrowing the error (use the
created user returned by createUserWithEmailAndPassword), ensuring you still
check auth presence and propagate the original error after cleanup.

---

Outside diff comments:
In `@components/Navbar.tsx`:
- Around line 53-67: Update the primary CTA in components/Navbar.tsx so
unauthenticated users are routed to the signup flow: change the href on the "Get
Started" Link (the second Link inside the JSX branch where isAuthPage ? null :
!user) from "/login" to "/signup" while keeping the same className and styling;
ensure the "Sign In" Link remains pointing to "/login" and only the "Get
Started" Link is updated.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: fd91d81b-a365-4783-bd41-0ad93d39f116

📥 Commits

Reviewing files that changed from the base of the PR and between e7fc53e and b833bdd.

📒 Files selected for processing (3)
  • components/AuthCard.tsx
  • components/Navbar.tsx
  • src/lib/firebase/auth.ts

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

♻️ Duplicate comments (1)
components/AuthCard.tsx (1)

61-69: ⚠️ Potential issue | 🟠 Major

A sync failure still gets treated like an authenticated success path.

The effect now waits during the in-flight attempt, but Line 174 still stops rendering the card as soon as currentUser becomes truthy, before userSynced is true. If syncUserWithDB() then fails, the error is stored in a component that returns null, and a later remount still redirects on raw auth state.

🧭 Suggested direction
     const [successMessage, setSuccessMessage] = useState<string | null>(null);
     const [userSynced, setUserSynced] = useState(false);
+    const [authFlowStarted, setAuthFlowStarted] = useState(false);

     useEffect(() => {
-        if (!authLoading && currentUser && !signingInRef.current) {
+        if (!authLoading && currentUser && (!authFlowStarted || userSynced)) {
             router.push('/dashboard');
         }
-        if (userSynced) {
-            router.push('/dashboard');
-        }
-    }, [authLoading, currentUser, userSynced, router]);
+    }, [authLoading, currentUser, userSynced, authFlowStarted, router]);

         setLoading(true);
         signingInRef.current = true;
+        setAuthFlowStarted(true);
 ...
         setIsLoadingEmail(true);
         signingInRef.current = true;
+        setAuthFlowStarted(true);
 ...
-    if (currentUser) return null;
+    if (currentUser && (!authFlowStarted || userSynced)) return null;

Also applies to: 173-174

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@components/AuthCard.tsx` around lines 61 - 69, The redirect logic in the
AuthCard effect and the render gating currently treats a truthy currentUser as
success before sync completes, so change the useEffect and any render-return
that hides the card to wait for userSynced (and no sync error) as well: only
call router.push('/dashboard') when !authLoading && currentUser && userSynced &&
!signingInRef.current, and ensure any conditional that returns null (stopping
render) also checks that syncUserWithDB succeeded (no sync error flag) so a
failed sync doesn't cause a remount/instant redirect on raw auth state; update
references to AuthCard, useEffect, signingInRef, currentUser, userSynced,
syncUserWithDB and the sync error state accordingly.
🧹 Nitpick comments (1)
components/AuthCard.tsx (1)

139-160: Add a real pending state for password-reset submits.

This flow never flips a reset-specific loading flag, so the button stays enabled during slow responses and can fire multiple reset emails.

⏳ Suggested change
     const [isLoadingGitHub, setIsLoadingGitHub] = useState(false);
     const [isLoadingEmail, setIsLoadingEmail] = useState(false);
+    const [isResettingPassword, setIsResettingPassword] = useState(false);
 ...
-    const isLoading = isLoadingGoogle || isLoadingGitHub || isLoadingEmail;
+    const isLoading = isLoadingGoogle || isLoadingGitHub || isLoadingEmail || isResettingPassword;
 ...
     const handlePasswordReset = useCallback(async (e: React.FormEvent) => {
         e.preventDefault();
         setSignInError(null);
         setSuccessMessage(null);

         if (!email.trim()) {
             setSignInError('Please enter your email address.');
             return;
         }

+        setIsResettingPassword(true);
         try {
             await resetPassword(email);
             setSuccessMessage('Password reset email sent! Check your inbox.');
             setShowResetPassword(false);
         } catch (error) {
             setSignInError(
                 error instanceof Error
                     ? error.message
                     : 'Failed to send reset email.'
             );
+        } finally {
+            setIsResettingPassword(false);
         }
     }, [email]);

Also applies to: 220-223

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@components/AuthCard.tsx` around lines 139 - 160, The password-reset flow
lacks a dedicated loading flag; update handlePasswordReset to set and clear a
"resetting" state (e.g., isResetting / setIsResetting) around the async call to
resetPassword so the UI can disable the reset button while pending and prevent
duplicate submissions, and mirror the same pattern in the other reset handler
referenced (lines 220-223); ensure you setIsResetting(true) before awaiting
resetPassword, setIsResetting(false) in both success and catch branches (or
finally), and tie the reset button's disabled/aria-busy props to isResetting
while still calling setSignInError/setSuccessMessage and setShowResetPassword as
before.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@components/AuthCard.tsx`:
- Around line 100-137: The signup flow can leave a partially-created Firebase
auth user if syncUserWithDB fails; hoist the user variable out of the try so it
remains visible in the catch, and when mode === 'signup' and user was created
but syncUserWithDB throws, perform cleanup by deleting the just-created auth
account (or at minimum sign the user out) before surfacing the error; update
handleEmailSubmit to declare let user: User | null outside the try, check for a
created user in the catch, call the appropriate cleanup (deleteUser or signOut
via your auth SDK), then rethrow or setSignInError, ensuring signingInRef and
setIsLoadingEmail are still cleared in the finally block.

---

Duplicate comments:
In `@components/AuthCard.tsx`:
- Around line 61-69: The redirect logic in the AuthCard effect and the render
gating currently treats a truthy currentUser as success before sync completes,
so change the useEffect and any render-return that hides the card to wait for
userSynced (and no sync error) as well: only call router.push('/dashboard') when
!authLoading && currentUser && userSynced && !signingInRef.current, and ensure
any conditional that returns null (stopping render) also checks that
syncUserWithDB succeeded (no sync error flag) so a failed sync doesn't cause a
remount/instant redirect on raw auth state; update references to AuthCard,
useEffect, signingInRef, currentUser, userSynced, syncUserWithDB and the sync
error state accordingly.

---

Nitpick comments:
In `@components/AuthCard.tsx`:
- Around line 139-160: The password-reset flow lacks a dedicated loading flag;
update handlePasswordReset to set and clear a "resetting" state (e.g.,
isResetting / setIsResetting) around the async call to resetPassword so the UI
can disable the reset button while pending and prevent duplicate submissions,
and mirror the same pattern in the other reset handler referenced (lines
220-223); ensure you setIsResetting(true) before awaiting resetPassword,
setIsResetting(false) in both success and catch branches (or finally), and tie
the reset button's disabled/aria-busy props to isResetting while still calling
setSignInError/setSuccessMessage and setShowResetPassword as before.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 7440cca7-f33d-4928-83ab-1448db126fcb

📥 Commits

Reviewing files that changed from the base of the PR and between b833bdd and b4172a2.

📒 Files selected for processing (4)
  • components/AuthCard.tsx
  • components/Navbar.tsx
  • src/lib/db/models/User.ts
  • src/lib/firebase/auth.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • components/Navbar.tsx

Comment on lines +129 to +144
export const resetPassword = async (email: string) => {
if (!auth) throw new Error("Firebase Auth is not initialized.");
try {
await sendPasswordResetEmail(auth, email);
} catch (error) {
const authError = error as AuthError;
console.error("Password reset error:", {
code: authError.code,
message: authError.message,
});
if (authError.code === 'auth/user-not-found') {
throw new Error("No account found with this email.");
}
throw new Error(authError.message || "Failed to send reset email");
}
};
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Avoid revealing whether an email is registered from the reset flow.

This returns a distinct user-facing outcome when no account exists, which makes email enumeration trivial from the reset screen. Keep the external response the same for existent and nonexistent addresses, and switch the success copy in components/AuthCard.tsx to something generic like “If an account exists, you’ll receive a reset link.”

🔐 Suggested change
 export const resetPassword = async (email: string) => {
     if (!auth) throw new Error("Firebase Auth is not initialized.");
     try {
         await sendPasswordResetEmail(auth, email);
     } catch (error) {
         const authError = error as AuthError;
         console.error("Password reset error:", {
             code: authError.code,
             message: authError.message,
         });
-        if (authError.code === 'auth/user-not-found') {
-            throw new Error("No account found with this email.");
-        }
-        throw new Error(authError.message || "Failed to send reset email");
+        if (authError.code === 'auth/user-not-found') {
+            return;
+        }
+        throw new Error("Failed to send reset email");
     }
 };
📝 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.

Suggested change
export const resetPassword = async (email: string) => {
if (!auth) throw new Error("Firebase Auth is not initialized.");
try {
await sendPasswordResetEmail(auth, email);
} catch (error) {
const authError = error as AuthError;
console.error("Password reset error:", {
code: authError.code,
message: authError.message,
});
if (authError.code === 'auth/user-not-found') {
throw new Error("No account found with this email.");
}
throw new Error(authError.message || "Failed to send reset email");
}
};
export const resetPassword = async (email: string) => {
if (!auth) throw new Error("Firebase Auth is not initialized.");
try {
await sendPasswordResetEmail(auth, email);
} catch (error) {
const authError = error as AuthError;
console.error("Password reset error:", {
code: authError.code,
message: authError.message,
});
if (authError.code === 'auth/user-not-found') {
return;
}
throw new Error("Failed to send reset email");
}
};

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

♻️ Duplicate comments (1)
components/AuthCard.tsx (1)

63-71: ⚠️ Potential issue | 🟠 Major

Prevent premature/blocked redirects by managing syncFailed in provider flows.

handleProviderSignIn never resets syncFailed at start and never sets it on failure. That leaves redirect behavior inconsistent: provider sync failures can still navigate, and stale failures can block later success paths.

Suggested fix
 const handleProviderSignIn = useCallback(async (
     signInFn: () => Promise<User | null>,
     setLoading: (v: boolean) => void,
     provider: 'google' | 'github'
 ) => {
     setSignInError(null);
     setSuccessMessage(null);
+    setSyncFailed(false);
     setLoading(true);
     signingInRef.current = true;
     try {
         const user = await signInFn();
         if (!user) {
             setSignInError(`Failed to sign in with ${provider}. Please try again.`);
             return;
         }
         await syncUserWithDB(user, provider);
         setUserSynced(true);
     } catch (error) {
+        setSyncFailed(true);
         setSignInError(
             error instanceof Error
                 ? error.message
                 : `Failed to sign in with ${provider}. Please try again.`
         );
     } finally {
         signingInRef.current = false;
         setLoading(false);
     }
 }, []);

Also applies to: 73-100

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@components/AuthCard.tsx` around lines 63 - 71, The redirect logic in
AuthCard's useEffect is inconsistent because handleProviderSignIn never resets
syncFailed at the start nor sets it on failure; update handleProviderSignIn to
clear syncFailed (set false) immediately when starting a provider sign-in (and
set signingInRef appropriately), and on any sync error set syncFailed = true
(and stop signingInRef), so the useEffect conditions (checking syncFailed,
userSynced, currentUser, signingInRef) behave deterministically; ensure the same
reset/set behavior is applied to other provider flows referenced in this file so
stale syncFailed flags don't block later successful sign-ins or allow premature
redirects.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Duplicate comments:
In `@components/AuthCard.tsx`:
- Around line 63-71: The redirect logic in AuthCard's useEffect is inconsistent
because handleProviderSignIn never resets syncFailed at the start nor sets it on
failure; update handleProviderSignIn to clear syncFailed (set false) immediately
when starting a provider sign-in (and set signingInRef appropriately), and on
any sync error set syncFailed = true (and stop signingInRef), so the useEffect
conditions (checking syncFailed, userSynced, currentUser, signingInRef) behave
deterministically; ensure the same reset/set behavior is applied to other
provider flows referenced in this file so stale syncFailed flags don't block
later successful sign-ins or allow premature redirects.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: e44e936f-215d-4606-82a6-8e2f786cc100

📥 Commits

Reviewing files that changed from the base of the PR and between b4172a2 and 4ab6e8d.

📒 Files selected for processing (1)
  • components/AuthCard.tsx

@Shashank0701-byte Shashank0701-byte merged commit 1fa4f39 into main Mar 15, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant