Skip to content

[Auth] Add Google sign-in (evaluate Neon Auth vs. direct OAuth) #862

Description

@Ogstevyn

Problem

Sign-in currently only supports email + password (plus WebAuthn/biometrics for returning users — see registerWebAuthn/authenticateWebAuthn in app/login/page.tsx). There's no social/Google sign-in option, which is a real conversion-rate cost for a consumer app.

Current auth architecture (important context)

This is not NextAuth or any existing OAuth library. Auth is fully custom:

Any Google sign-in implementation needs to end up issuing our own JWT into that same cookie so the rest of the app (which reads useEmailAuth()/AuthUser) doesn't need to change.

Two possible approaches — pick one before writing code

This is an architecture decision, not just a feature add, so please post a short proposal comment on this issue with your chosen approach before starting implementation.

Option A — Neon Auth
We already use Neon for Postgres (lib/db/prisma.ts). Neon offers a hosted auth product ("Neon Auth") that can provide Google/social sign-in on the same Neon project. Potentially less code to maintain, but:

  • It's a genuinely different auth model (Neon-managed user records) that would need to coexist with or replace our own User table / bcrypt flow — needs real research into exactly how its users map onto our existing schema before committing to it.
  • Verify current Neon Auth capabilities directly against Neon's docs — don't assume feature parity with what's described here, product surface may have changed.

Option B — Direct Google OAuth 2.0
Smaller footprint: implement the standard OAuth "Sign in with Google" flow (authorization code grant), verify the returned ID token, find-or-create a User row, and issue our existing JWT exactly as login/signup do today. No new hosted-auth dependency, stays inside the current architecture.

Whichever is chosen, existing users who signed up with email+password should still be able to sign in as before — this is additive, not a replacement.

Scope for this issue

  • Decision comment posted (which of the two approaches, with reasoning) — get a maintainer 👍 before writing code, this is a bigger architectural change than a typical PR here
  • "Continue with Google" button on /login and /signup (match current light/dark brand styling — see the existing biometric-login button in app/login/page.tsx for the pattern)
  • New/existing users can complete sign-in via Google and land in the app authenticated exactly like email/password users
  • If the Google email matches an existing email/password account, decide and document the linking behavior (e.g. link accounts vs. reject with a clear message) rather than silently creating a duplicate account
  • Tests for the new callback/token-exchange route

Environment variables

Depending on the approach chosen, you'll eventually need either a Google Cloud OAuth client ID/secret, or Neon Auth project credentials. Do not request these up front. Post your approach decision first, get it confirmed, and only then ask a maintainer for the specific credentials your implementation needs.


Suggested labels: auth, feature, backend, complexity:HIGH, help wanted

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions