Skip to content

Auth service implementation gaps block Jaanify login flow (L-31, L-32, L-33) #151

@parhumm

Description

@parhumm

The Problem

Jaanify's login/auth UI is fully integrated — the /login page renders, the middleware guards routes, the navbar shows session state — but clicking "Continue with Google" leads to a dead end. The OAuth callback route doesn't exist, the auth service functions are TODO stubs, and the session hydration endpoint (/users/me) returns 404.

Three P1 gaps from Cycle 14 gap analysis block the login flow:

L-31: Google OAuth Callback Route Missing

The login page generates a valid Google OAuth URL and redirects users to Google's consent screen. But when Google redirects back to /login/callback, there's no handler — users hit a 404.

What's needed:

  • Frontend callback page at apps/web/src/app/login/callback/page.tsx that reads the code query param and sends it to the API
  • Backend googleAuth() implementation that exchanges the authorization code for an ID token, verifies it, upserts the user in Prisma, and returns a token pair

The frontend route prefix /login/ is already marked as public in the middleware. The backend route /v1/auth/google exists but calls a stub function.

L-32: Auth Service Stubs Still TODO

apps/api/src/routes/auth/auth.service.ts has 4 stub functions that the route handlers call:

  • googleAuth() — needs to exchange Google auth code → verify ID token → upsert user → generateTokenPair()
  • refreshToken() — needs to call verifyRefreshToken() → check user exists → generateTokenPair()
  • register() — needs to create user from anonymous session → generateTokenPair()
  • logout() — needs to invalidate refresh token in DB

The building blocks are already there: auth-tokens.ts has generateTokenPair(), verifyAccessToken(), verifyRefreshToken(). The Prisma User and RefreshToken models exist. The route handlers already call setAuthCookies(reply, tokens) with the return value. The service layer just needs to compose these pieces.

L-33: /users/me Endpoint Missing

The Zustand auth store calls apiClient.get("/users/me") on page load to check if the session is valid and populate user info for the navbar. But no /users/me route exists — the request fails and the navbar always shows "Sign In" even for authenticated users.

What's needed:

  • A GET /v1/users/me route that reads request.userId (set by the auth plugin) and returns the user profile from Prisma
  • This is a thin endpoint — the auth plugin already handles token verification and sets request.userId

What We Already Have

Jaanify has invested 14 co-evolution cycles using jaan-to skills to build:

  • 80+ deliverables across 20 categories
  • 21 API endpoints defined in OpenAPI 3.1
  • 8 Prisma models including User and RefreshToken
  • auth-tokens.ts with generateTokenPair(), verifyAccessToken(), verifyRefreshToken() using jose HS256
  • secure-cookies.ts with setAuthCookies(), clearAuthCookies() for HttpOnly Secure SameSite cookies
  • Auth plugin with dual-mode token extraction (Authorization header + cookie)
  • Cookie helpers with getRefreshToken() for reading refresh tokens from cookies
  • Build passes: both tsc --noEmit and turbo build succeed

The inputs are all there. The auth route handlers exist, the cookie management exists, the token generation exists, the Prisma models exist. What's missing is the service layer glue that composes these pieces into working auth flows.

The Ask

The backend-service-implement skill (scored 4.7/5 in Jaanify testing) should be able to generate the auth service implementations from the existing specs, schemas, and scaffold code. Specifically:

  1. Implement googleAuth() — Google code exchange → user upsert → token pair
  2. Implement refreshToken() — verify → rotate → new token pair
  3. Implement register() — anonymous → registered user flow
  4. Implement logout() — invalidate refresh token
  5. Add GET /v1/users/me route — return authenticated user profile
  6. Add /login/callback frontend page — handle OAuth redirect

Context

  • jaan-to version: v7.2.0-1-g3c10276
  • Full gap report: gap-reports/14-cycle/14-launch-gaps.md
  • Tech stack: Fastify v5, Next.js 15, Prisma v6, jose, pnpm monorepo
  • Critical path: L-32 → L-31 → L-33 → Working Login → Revenue

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions