Commit graph

5 commits

Author SHA1 Message Date
Lasse Rune Hansen
f1ed8a1a7a fix(backend/auth): Fix JWT claim mapping issue causing 401 on /me endpoint
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
PROBLEM:
- Login returns JWT token with 'sub' claim
- /me endpoint tries to read user ID from JWT
- Gets 401 Unauthorized because user ID claim cannot be found

ROOT CAUSE:
ASP.NET Core JWT middleware automatically maps JWT standard claims to .NET claim types:
- JwtRegisteredClaimNames.Sub ('sub') -> ClaimTypes.NameIdentifier ('http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier')

Controllers were looking for 'sub' or 'nameid' but JWT middleware creates the claim with the full URI.

SOLUTION:
Updated all controllers to use ClaimTypes.NameIdentifier with fallback to 'sub':
- AuthController.GetCurrentUser()
- AdminController.DeleteUserAsync()
- StoryController.GetUserId()

This ensures the user ID can be found regardless of how the JWT middleware maps the claims.

CHANGES:
- AuthService: Generates JWT tokens with JwtRegisteredClaimNames.Sub (JWT standard)
- AuthController: Uses ClaimTypes.NameIdentifier ?? 'sub' fallback
- AdminController: Uses ClaimTypes.NameIdentifier ?? 'sub' fallback
- StoryController: Uses ClaimTypes.NameIdentifier ?? 'sub' fallback
- LessonsEndpoints.cs: Added .RequireAuthorization() to all GET endpoints
- docs/features/admin-module.md: Updated acceptance criteria and requirements
- Added unit tests in JwtTokenValidationTests.cs to verify the fix

Generated by Mistral Vibe.
Co-Authored-By: Mistral Vibe <vibe@mistral.ai>
2026-06-14 18:25:49 +02:00
Lasse Rune Hansen
ef72cbea18 fix(backend/auth): Fix JWT token claim mapping for user ID
- Changed AuthService.GenerateJwtToken to use JWT standard claims:
  - JwtRegisteredClaimNames.Sub for user ID (instead of ClaimTypes.NameIdentifier)
  - JwtRegisteredClaimNames.Name for username
  - JwtRegisteredClaimNames.Email for email
  - JwtRegisteredClaimNames.UniqueName for additional username claim
  - Kept ClaimTypes.Role for role

- Updated AuthController.GetCurrentUser to use JwtRegisteredClaimNames.Sub
- Updated AdminController.DeleteUserAsync to use JwtRegisteredClaimNames.Sub

This fixes the 401 error when calling /me after login. The issue was that
tokens were being generated with ClaimTypes.NameIdentifier claim, but the
JWT middleware doesn't automatically map this to a claim that can be found
with User.FindFirst(). Using standard JWT claims (sub, name, email) ensures
proper compatibility with ASP.NET Core's JWT authentication.

Generated by Mistral Vibe.
Co-Authored-By: Mistral Vibe <vibe@mistral.ai>
2026-06-14 17:38:27 +02:00
Lasse Rune Hansen
42778ec34b fix(backend/auth): Fix authentication bugs
- Fix case-insensitive email lookups in AuthService (RegisterAsync, LoginAsync, CreateAdminUserAsync)
- Fix User.Create factory method to explicitly set Role property (C# object initializer behavior)
- Assign Admin role to seeded admin user in SeedDataExtension
- Add [AllowAnonymous] to Register and Login endpoints in AuthController (defensive programming)
- Increase JWT ClockSkew to 5 minutes for clock difference tolerance

These fixes resolve issues where:
- Login fails with 401 due to case-sensitive email comparison
- User role is null instead of 'User' or 'Admin'
- JWT token validation too strict on clock synchronization

Generated by Mistral Vibe.
Co-Authored-By: Mistral Vibe <vibe@mistral.ai>
2026-06-14 16:40:01 +02:00
Lasse Rune Hansen
6bcf592918 feat(backend): complete unit tests for User Authentication feature
- Fix MSTest compatibility with .NET 9.0 by upgrading to MSTest.TestFramework 4.2.3
- Move Tests directory to solution level (Tests/) to prevent test files from being compiled with GermanApp
- Update test project references to point to GermanApp/GermanApp.csproj
- Add InternalsVisibleTo attributes for test assemblies
- Make RefreshToken properties internal for testability
- Fix User.ChangeEmail null handling
- Add 46 comprehensive unit tests for User and RefreshToken domain entities
- All tests passing successfully

Generated by Mistral Vibe.
Co-Authored-By: Mistral Vibe <vibe@mistral.ai>
2026-06-05 17:07:15 +02:00
Lasse Rune Hansen
d508d498c0 feat(backend/auth): implement User Authentication feature
- Add DTOs: RegisterDto, LoginDto, AuthResponse
- Add IAuthService interface
- Implement AuthService with JWT token generation
- Create AuthController with register, login, me endpoints
- Add JWT configuration to appsettings.json
- Configure JWT Bearer authentication in Program.cs
- Add PasswordHasher for custom User entity
- Update User entity with ChangePassword method
- Add necessary NuGet packages for JWT auth

Generated by Mistral Vibe.
Co-Authored-By: Mistral Vibe <vibe@mistral.ai>
2026-06-05 13:27:43 +02:00