Skip to content

feat(auth): Firebase Auth Google Sign-In Integration - #24

Merged
Tambeej merged 5 commits into
mainfrom
code-pilot-backend-impl
Apr 3, 2026
Merged

feat(auth): Firebase Auth Google Sign-In Integration#24
Tambeej merged 5 commits into
mainfrom
code-pilot-backend-impl

Conversation

@Tambeej

@Tambeej Tambeej commented Apr 3, 2026

Copy link
Copy Markdown
Owner

Overview

This PR implements Firebase Authentication with Google provider for user sign-in and registration in the Morty backend.

Completed Tasks

  1. POST /api/auth/google endpoint — Added a new endpoint that receives a Firebase ID token from the client and verifies it using admin.auth().verifyIdToken().

  2. Updated userService — Extended the user service to create or retrieve a user by Firebase UID/email, and store the firebaseUid field in the Firestore user document.

  3. JWT token generation — Upon successful Firebase token verification, the backend generates custom access and refresh JWT tokens for the authenticated user.

  4. Refresh token persistence — The refresh token is persisted in Firestore and the auth payload returned is fully compatible with the existing frontend auth flow.

  5. Updated authController and routes — The authController and src/routes/auth.js have been updated to wire up the new /api/auth/google endpoint.

API Contract

POST /api/auth/google
Content-Type: application/json

Request body:
{
  "idToken": "<Firebase ID token from Google Sign-In>"
}

Response (200 OK):
{
  "success": true,
  "data": {
    "user": { "id": "...", "email": "...", "name": "...", "firebaseUid": "..." },
    "accessToken": "<JWT access token>",
    "refreshToken": "<JWT refresh token>"
  }
}

Related

  • Original request: Use Firebase Auth with Google provider for user sign-in / register
  • Frontend will call this endpoint after obtaining a Firebase ID token via signInWithPopup / signInWithRedirect.

Tambeej added 5 commits April 3, 2026 13:40
…ication

- Add googleSchema Joi validator to authValidators.js and validate.js
- Add googleAuth controller handler that verifies Firebase ID token via admin.auth().verifyIdToken()
- Register POST /api/v1/auth/google route with validation and authLimiter
- Add integration tests for the new endpoint
…port

- Add findByFirebaseUid() to look up users by Firebase UID
- Add findOrCreateByFirebaseUser() to idempotently link/create users
  from Google sign-in: queries by email first, updates firebaseUid if
  missing, or creates a new passwordless user document
- Update User model schema descriptor to include firebaseUid field
- Add comprehensive unit tests for all new functions
…tests

- Update jwt.js: change default ACCESS_TOKEN_EXPIRY from 24h to 15m
  (matches architecture spec: accessToken exp: 15m, refreshToken exp: 7d)
- Update .env.example: document JWT_EXPIRES_IN and JWT_REFRESH_EXPIRES_IN
  env vars so operators can override token lifetimes
- Add __tests__/googleAuthJwt.test.js: dedicated integration tests for
  the JWT token generation step in the Google auth flow, covering:
  * Access + refresh token presence and structure in response
  * Token payload contains correct Firestore user ID
  * Access token expiry is shorter than refresh token expiry
  * setRefreshToken is called with the generated refresh token
  * Token can be verified with the correct secret
  * Correct token type separation (access vs refresh secrets)
…le auth payload for Google auth

- Verify authController.googleAuth persists refresh token via userService.setRefreshToken
- Confirm buildAuthPayload returns { token, refreshToken, user: { id, email, phone, verified } }
  wrapped in sendSuccess as { data: { token, refreshToken, user } } — matches frontend authService
- Add dedicated __tests__/googleAuthRefreshToken.test.js covering:
  * Refresh token is persisted in Firestore after successful Google sign-in
  * Auth payload structure is frontend-compatible (data.token, data.refreshToken, data.user)
  * Refresh token rotation works for Google-authenticated users
  * Refresh token is cleared on logout for Google users
  * Edge cases: missing idToken, expired Firebase token, email conflict
…, and validator

Task 5: Update authController and routes to include the new Google auth endpoint.

- authController.googleAuth: verifies Firebase ID token via Admin SDK, calls
  userService.findOrCreateByFirebaseUser, issues custom JWTs, persists refresh
  token in Firestore, returns standard auth payload
- routes/auth.js: POST /auth/google wired to validate(googleSchema) + authController.googleAuth,
  covered by authLimiter (20 req/15min)
- middleware/validate.js: googleSchema exported (idToken: string, min 1, required)
- docs/API.md: added POST /auth/google endpoint documentation with request/response
  shapes, error codes, and frontend integration notes
- __tests__/auth.test.js: comprehensive integration tests for all /auth/google
  scenarios (missing token, empty token, expired token, success, missing email,
  conflict, server error)

@Tambeej Tambeej left a comment

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

🤖 Code-Pilot Team Leader (adk)

APPROVED

✅ Backend PR Review — Google Auth via Firebase

All 5 tasks have been implemented correctly and align with the architecture design. The code is well-structured, secure, and thoroughly tested.

Task Verification

# Task Status
1 POST /api/auth/google endpoint with admin.auth().verifyIdToken()
2 userService findOrCreateByFirebaseUser() with firebaseUid storage
3 Custom access (15m) and refresh (7d) JWT generation
4 Refresh token persisted in Firestore, frontend-compatible payload
5 authController, routes, and validation updated

Security ✅

  • Firebase ID token verified server-side only via Admin SDK
  • Rate limiting applied via authLimiter on /google endpoint
  • Input validation via Joi schema
  • No sensitive fields leaked (password, refreshToken, firebaseUid stripped by toPublicUser)
  • Google-only accounts properly rejected for email/password login (GOOGLE_ACCOUNT error code)
  • 409 Conflict for email already linked to a different Firebase UID

Architecture Alignment ✅

  • Data flow matches architecture spec (steps 5–9)
  • Three-path user resolution (returning Google user → email linking → new user) implemented correctly
  • No breaking changes to existing email/password auth flow

Test Coverage ✅

  • Integration tests: 7 new Google Auth test cases covering validation, auth failures, success, edge cases
  • Unit tests: Comprehensive findOrCreateByFirebaseUser tests covering all 3 paths, conflict detection, input validation
  • Firebase Admin SDK properly mocked

Minor Note (non-blocking)

  • googleSchema is defined in both src/middleware/validate.js and src/validators/authValidators.js. The route uses the one from validate.js. The duplicate in authValidators.js is harmless but could be cleaned up in a future PR.

LGTM — well-implemented, secure, and thoroughly tested. 🚀


Reviewed at 2026-04-03 10:56:40 UTC

@Tambeej
Tambeej merged commit 6601a09 into main Apr 3, 2026
1 check 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