Implement: User Authentication – Separate Login and Register Pages #12

Merged
crisleo94 merged 5 commits from feature/user-auth into main 2026-05-26 20:25:06 +00:00
Owner

Implemented separate login and register pages with:

Backend:

  • Custom User model using email as USERNAME_FIELD
  • POST /api/auth/register/ with email validation, password min 8 chars, confirm match, duplicate check
  • POST /api/auth/login/ with JWT token generation
  • Django PBKDF2 password hashing
  • No user enumeration on login

Frontend:

  • LoginPage with email/password form, error states, loading spinner
  • RegisterPage with name/email/password/confirm form + client-side validation
  • AuthContext with useReducer pattern, localStorage token management
  • Route state passes success message from registration to login
  • VITE_API_URL env var (fixed Vite prefix in docker-compose)

Fixes vs prior attempt:

  • AuthContext.register no longer sets AUTH_SUCCESS (user must log in after registering)
  • LoginPage displays successMessage from route state (from RegisterPage redirect)
  • docker-compose REACT_APP_API_URL -> VITE_API_URL
  • Django settings: added admin, messages, staticfiles apps
  • Spec document: docs/auth-implementation.md
  • web/.env.example for API URL config

Issue: crisleo-hermes/job-tracker#3

Implemented separate login and register pages with: **Backend:** - Custom User model using email as USERNAME_FIELD - POST /api/auth/register/ with email validation, password min 8 chars, confirm match, duplicate check - POST /api/auth/login/ with JWT token generation - Django PBKDF2 password hashing - No user enumeration on login **Frontend:** - LoginPage with email/password form, error states, loading spinner - RegisterPage with name/email/password/confirm form + client-side validation - AuthContext with useReducer pattern, localStorage token management - Route state passes success message from registration to login - VITE_API_URL env var (fixed Vite prefix in docker-compose) **Fixes vs prior attempt:** - AuthContext.register no longer sets AUTH_SUCCESS (user must log in after registering) - LoginPage displays successMessage from route state (from RegisterPage redirect) - docker-compose REACT_APP_API_URL -> VITE_API_URL - Django settings: added admin, messages, staticfiles apps - Spec document: docs/auth-implementation.md - web/.env.example for API URL config Issue: crisleo-hermes/job-tracker#3
marko added 2 commits 2026-05-26 04:36:44 +00:00
- Custom User model with email as unique identifier (AUTH_USER_MODEL)

- POST /api/auth/register/ with email validation, password min 8 chars, duplicate rejection

- POST /api/auth/login/ returning JWT (access + refresh) tokens

- Passwords hashed via Django's make_password

- React LoginPage and RegisterPage with form validation

- AuthContext with useReducer for auth state management

- Axios API client with JWT token injection

- TypeScript conversion of frontend scaffold
marko added 1 commit 2026-05-26 06:08:00 +00:00
marko closed this pull request 2026-05-26 08:05:53 +00:00
reid reopened this pull request 2026-05-26 14:16:52 +00:00
marko added 1 commit 2026-05-26 17:05:16 +00:00
marko added 1 commit 2026-05-26 19:07:10 +00:00
Resolved merge conflicts integrating PR #13 (Home Page with MUI v2):

Backend changes:
- settings.py: Combined INSTALLED_APPS (accounts + jobs + corsheaders),
  kept HEAD's REST_FRAMEWORK (AllowAny + throttling) and SIMPLE_JWT,
  added origin/main's CORS config
- urls.py: Combined admin/, api/auth/, api/ routes
- pyproject.toml: Combined all dependencies (simplejwt + cors-headers)
- uv.lock: Regenerated with updated dependencies

Frontend changes:
- package.json: Combined all deps (axios + MUI + emotion)
- App.tsx: Integrated AuthProvider with MUI AppLayout, all routes
- HomePage.tsx: Show landing view when unauthenticated, MUI dashboard
  when authenticated
- main.tsx, tsconfig.json, vite-env.d.ts: Combined both versions
- yarn.lock: Kept origin/main's version (regenerated on install)
Owner

Reid's Review — PR #12

Verdict: 🔴 Changes Required (Update)


🔴 Blocking Issues

These MUST be resolved before this PR can be merged.

  • [File: api/project/settings.py | Line ~82] configuration error
    AUTH_USER_MODEL=*** is still a placeholder value. Django will fail at runtime when trying to resolve the custom user model. Must be changed to AUTH_USER_MODEL="accounts.User".

🟡 Suggestions (Non-Blocking)

These are recommendations for improvement. Not required for merge.

  • [File: api/accounts/admin.py] Consider adding list_filter for is_staff, is_active fields to improve admin usability.
  • [File: web/src/services/authApi.ts] Consider adding a response interceptor to handle 401 redirects globally.

📋 AC Coverage

Based on linked issue #3

  • POST /api/auth/register/ endpoint
  • POST /api/auth/login/ endpoint
  • Email validation with regex
  • Password minimum 8 characters enforced
  • Password confirmation match
  • Duplicate email rejection
  • Django PBKDF2 password hashing
  • JWT tokens on successful login
  • Separate LoginPage and RegisterPage
  • Redirects to dashboard after login
  • CSS modules used for styling (correct approach)
  • Rate limiting on auth endpoints
  • Permission classes on endpoints
## Reid's Review — PR #12 **Verdict:** 🔴 Changes Required (Update) --- ### 🔴 Blocking Issues > These MUST be resolved before this PR can be merged. - **[File: api/project/settings.py | Line ~82]** `configuration error` `AUTH_USER_MODEL=***` is still a placeholder value. Django will fail at runtime when trying to resolve the custom user model. Must be changed to `AUTH_USER_MODEL="accounts.User"`. --- ### 🟡 Suggestions (Non-Blocking) > These are recommendations for improvement. Not required for merge. - **[File: api/accounts/admin.py]** Consider adding `list_filter` for `is_staff`, `is_active` fields to improve admin usability. - **[File: web/src/services/authApi.ts]** Consider adding a response interceptor to handle 401 redirects globally. --- ### 📋 AC Coverage Based on linked issue #3 - [x] POST /api/auth/register/ endpoint - [x] POST /api/auth/login/ endpoint - [x] Email validation with regex - [x] Password minimum 8 characters enforced - [x] Password confirmation match - [x] Duplicate email rejection - [x] Django PBKDF2 password hashing - [x] JWT tokens on successful login - [x] Separate LoginPage and RegisterPage - [x] Redirects to dashboard after login - [x] CSS modules used for styling (correct approach) - [x] Rate limiting on auth endpoints - [x] Permission classes on endpoints
Author
Owner

AUTH_USER_MODEL blocker resolved.

The merge commit 48db53c (Merge branch main into feature/user-auth) already resolved this: AUTH_USER_MODEL is now set to "accounts.User" (inherited from main).

This specific blocker should be cleared — ready for re-review.

✅ **AUTH_USER_MODEL blocker resolved.** The merge commit `48db53c` (Merge branch `main` into `feature/user-auth`) already resolved this: `AUTH_USER_MODEL` is now set to `"accounts.User"` (inherited from main). This specific blocker should be cleared — ready for re-review.
crisleo94 merged commit a0b3ae7e34 into main 2026-05-26 20:25:06 +00:00
Sign in to join this conversation.
No Reviewers
No labels
2 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: HermesFactory/job-tracker#12