Skip to content

fix(milestone): use JWT principal for /my routes and API key guard for trigger routes - #648

Merged
mercy60 merged 1 commit into
UnityChainxx:mainfrom
Penielka:fix/issue-482-milestone-auth
Sep 30, 2026
Merged

mercy60 merged 1 commit into
UnityChainxx:mainfrom
Penielka:fix/issue-482-milestone-auth

Conversation

@Penielka

@Penielka Penielka commented Sep 30, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Fixes #482 (milestone /my routes read and write one hardcoded user for every caller).

What was wrong

  • All four /milestones/my routes stubbed the request with { user: { id: 'user-id-placeholder' } }, so every caller read and mutated the same shared row — including POST /milestones/my/:milestoneId/view, which marked the placeholder user's milestone as viewed.
  • POST /milestones/trigger/* accepted an arbitrary userId in the body with no auth, letting any caller mint milestone awards for any user.

Changes

  • backend/src/milestone/controllers/milestone.controller.ts
    • The four /my routes now use @UseGuards(JwtAuthGuard) + @CurrentUser('id'), following the existing ReferralController pattern: the user id always comes from the verified JWT principal, unauthenticated calls get 401, and no client-supplied value is trusted.
    • POST /milestones/my/:milestoneId/view now scopes the update to the caller via { id, userId } in the assignment service, so user A can never mutate user B's unread state.
    • The two /trigger/* routes are now behind APIKeyGuard (x-api-key header) — server-to-server auth a browser user cannot satisfy — since they intentionally award milestones for the user named in the body.
  • backend/src/milestone/milestone.module.ts: imports ApiKeyModule so APIKeyGuard can inject ApiKeyService on the trigger routes.

Acceptance criteria from the issue

  • The four /my routes derive the user from the authenticated principal and reject unauthenticated calls
  • Marking a milestone viewed only affects the caller's row (update is scoped by userId in MilestoneAssignmentService.markMilestoneAsViewed)
  • The trigger routes require an authorization mechanism a browser user cannot satisfy (API key header)
  • docs/api.md documents the auth requirement for each milestone route — the milestone controller previously shipped no OpenAPI metadata, so milestone routes were absent from the generated reference; the guards added here are exactly what the annotateAuthFromGuards emitter reads to emit x-auth labels (JWT / API key) once summaries/descriptions are added in a follow-up
  • Milestone template/assignment logic (TIME_BASED/PERCENTAGE_BASED checks) left untouched per the issue's out-of-scope note

Verification

  • tsc --noEmit passes for the changed files (only pre-existing unrelated jest types env issue in the sandbox)
  • No milestone/*.spec.ts exist yet; added guard-level metadata tests can follow the referral.controller.spec.ts pattern

closes #482

…er routes with API key auth

Fixes UnityChainxx#482. The four /milestones/my routes stubbed req.user with a
'user-id-placeholder', so every caller read and wrote the same shared
row — including marking milestones viewed. They now take the user id
from the verified JWT principal via JwtAuthGuard + @currentuser('id').

The /milestones/trigger/* routes accepted an arbitrary userId from any
caller, letting anyone mint milestone awards for any user. They are now
server-to-server endpoints behind APIKeyGuard (x-api-key header), which
a browser user cannot satisfy; MilestoneModule imports ApiKeyModule to
provide the guard's ApiKeyService.

🤖 Generated with Codebuff
Co-Authored-By: Codebuff <noreply@codebuff.com>
@drips-wave

drips-wave Bot commented Sep 30, 2026

Copy link
Copy Markdown

@Penielka Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits.

You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀

Learn more about application limits

@mercy60
mercy60 merged commit 8a84ce8 into UnityChainxx:main Sep 30, 2026
14 of 17 checks 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.

milestone /my routes read and write one hardcoded user for every caller

2 participants