Skip to content

feat(auth): add authentication and authorization guards - #28

Merged
rd-code-23 merged 1 commit into
mainfrom
feature/auth
Aug 19, 2026
Merged

rd-code-23 merged 1 commit into
mainfrom
feature/auth

Conversation

@rd-code-23

Copy link
Copy Markdown
Owner

What changed

  • add typed requireAuthentication middleware backed by request.session.userId
  • add reusable fail-closed requireAuthorization middleware
  • define safe 401 authentication_required and 403 forbidden responses
  • add a reusable authenticated-session test helper that is excluded from production builds
  • add integration coverage for anonymous, allowed, cross-user, spoofed-owner, and unresolved-ownership requests
  • document the API’s concise 401 versus 403 policy

Why

Future routines, workouts, history, and settings endpoints need one standard server-side boundary for identity and resource ownership. The guards ensure ownership queries use the user ID from the server-side session rather than trusting client-provided values.

Developer impact

Protected routes attach requireAuthentication. User-owned resource routes additionally attach requireAuthorization and scope their ownership query with the typed session user ID.

No fake protected endpoint was added to the production application; representative protected behavior exists only in integration tests.

Validation

  • scoped Prettier check
  • pnpm --filter @goforlift/api lint
  • pnpm --filter @goforlift/api typecheck
  • pnpm --filter @goforlift/api test — 47 tests passed
  • pnpm --filter @goforlift/api build

Closes #11

@rd-code-23
rd-code-23 marked this pull request as ready for review August 19, 2026 04:33
@rd-code-23
rd-code-23 merged commit fc1a78d into main Aug 19, 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.

[Auth][Phase 2] Add reusable authentication and authorization guards

1 participant