Skip to content

Auth — session helpers + error page #498

Description

@adityapat24

Context

Last sprint shipped auth routing, admin/user redirects, logout, and magic-link email delivery. What's left is the reusable session helpers every other endpoint needs, plus the friendly error page.

Tasks

Session helpers

  • Implement getSession() in src/lib/auth/session.ts that returns the typed Session (email, isAdmin) or null. Use NextAuth's getServerSession under the hood.
    • What this accomplishes: Any server component or route handler can call one function to know who's signed in. Encapsulates the NextAuth API so if it changes, only one file needs updating.
  • Implement requireUser() in src/lib/auth/guards.ts. Calls getSession(), returns the user if present, throws a typed error if not. The error should be catchable by route handlers and convertible to a 401 response.
    • What this accomplishes: One line at the top of any protected route handler enforces authentication. This is the helper every other ticket is waiting for.
  • Implement requireAdmin() in the same file. Calls requireUser(), then throws if the email doesn't end with @hackbeanpot.com. Converts to a 403 response in route handlers.
    • What this accomplishes: Same pattern for admin-only routes. Domain-based admin check keeps the rule dead simple.
  • Wire requireUser() into src/app/api/v1/user/route.ts (currently probably returns mock or unguarded data).
    • What this accomplishes: The endpoint the frontend uses to fetch the current user now actually returns real session data and correctly 401s when unauthed.

Session lifecycle

  • Confirm the logout flow (already shipped) actually invalidates the session in Mongo, not just the client cookie. Check the sessions collection after a logout to confirm the row is deleted.
    • What this accomplishes: Prevents the security bug where a "logged out" user's session token, if intercepted, would still be valid. Session invalidation on the server matters.
  • Confirm sessions have a reasonable expiration (e.g., 30 days). Set via NextAuth config session.maxAge if not already set.
    • What this accomplishes: Long-lived sessions mean users don't have to sign in every visit, but not so long that a stolen cookie is a lifetime problem.

Error page

  • src/app/auth/error/page.tsx reads the error query param and displays a specific message for each NextAuth error code (Verification = expired/reused link, EmailSignin = SMTP failure, AccessDenied = admin-only route, etc.). Include a "back to sign-in" link.
    • What this accomplishes: Users who hit an error (expired link, bad SMTP, etc.) see something useful instead of a cryptic code. Reduces support burden during application season.

Documentation

  • Add comments to getSession, requireUser, requireAdmin documenting return types, exceptions thrown, and one-line usage examples.
    • What this accomplishes: Every other ticket owner about to wire these in doesn't need to read the source or ping you to understand how they work.

Definition of done

  • getSession(), requireUser(), and requireAdmin() are exported and usable by any ticket.
  • The /api/v1/user endpoint uses requireUser() and returns the real session user.
  • Logout invalidates the session server-side (verified by checking the sessions collection).
  • The error page shows friendly messages for each error code.
  • Helpers are documented with comments.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions