suhail
spoecs
9eafd9f
# Tasks: Authentication & API Security
**Input**: Design documents from `/specs/001-auth-security/`
**Prerequisites**: plan.md, spec.md, research.md, data-model.md, contracts/
**Organization**: Tasks are grouped by user story to enable independent implementation and testing.
## Format: `[ID] [P?] [Story] Description`
- **[P]**: Can run in parallel (different files, no dependencies)
- **[Story]**: Which user story this task belongs to (US1, US2, US3, US4)
- Include exact file paths in descriptions
---
## Phase 1: Setup (Shared Infrastructure)
**Purpose**: Project initialization and dependency installation
- [x] T001 Add PyJWT==2.8.0, passlib[bcrypt]==1.7.4, python-multipart==0.0.6 to backend/requirements.txt
- [x] T002 Install backend dependencies with pip install -r backend/requirements.txt
- [x] T003 [P] Add better-auth and @better-auth/react to frontend/package.json
- [x] T004 [P] Install frontend dependencies with npm install in frontend/
- [x] T005 [P] Add BETTER_AUTH_SECRET to backend/.env (generate 32+ char random string)
- [x] T006 [P] Add BETTER_AUTH_SECRET to frontend/.env.local (same value as backend)
---
## Phase 2: Foundational (Blocking Prerequisites)
**Purpose**: Core infrastructure that MUST be complete before ANY user story
**⚠️ CRITICAL**: No user story work can begin until this phase is complete
- [x] T007 Create backend/src/core/security.py with password hashing and JWT functions
- [x] T008 Update backend/src/core/config.py to add BETTER_AUTH_SECRET (required, not optional)
- [x] T009 Add password_hash field to User model in backend/src/models/user.py
- [x] T010 Create database migration backend/alembic/versions/002_add_user_password.py
- [x] T011 Run alembic upgrade head to apply password_hash migration
- [x] T012 Create backend/src/schemas/auth.py with SignupRequest, SigninRequest, TokenResponse schemas
- [x] T013 Create frontend/src/lib/auth.ts with Better Auth configuration (email/password + JWT plugin)
**Checkpoint**: Foundation ready - user story implementation can now begin in parallel
---
## Phase 3: User Story 1 - User Sign Up (Priority: P1) 🎯 MVP
**Goal**: New users can create accounts with email and password
**Independent Test**: Submit signup form with valid credentials and verify account creation in database
### Implementation for User Story 1
- [x] T014 [P] [US1] Create backend/src/services/auth_service.py with signup method (hash password, create user)
- [x] T015 [P] [US1] Create backend/src/api/routes/auth.py with POST /api/auth/signup endpoint
- [x] T016 [US1] Add email validation (RFC 5322 format) in signup endpoint
- [x] T017 [US1] Add password validation (min 8 chars, uppercase, lowercase, number) in signup endpoint
- [x] T018 [US1] Handle duplicate email error (409 Conflict) in signup endpoint
- [x] T019 [P] [US1] Create frontend/src/components/auth/SignUpForm.tsx with form fields and validation
- [x] T020 [P] [US1] Create frontend/src/app/auth/signup/page.tsx using SignUpForm component
- [x] T021 [US1] Connect SignUpForm to Better Auth signup API
**Checkpoint**: Users can successfully sign up and create accounts
---
## Phase 4: User Story 2 - User Sign In (Priority: P2)
**Goal**: Registered users can sign in and receive JWT tokens
**Independent Test**: Submit signin form with valid credentials and verify JWT token is issued
### Implementation for User Story 2
- [x] T022 [US2] Add signin method to backend/src/services/auth_service.py (verify password, create JWT)
- [x] T023 [US2] Add POST /api/auth/signin endpoint to backend/src/api/routes/auth.py
- [x] T024 [US2] Return JWT token with 7-day expiration in signin response
- [x] T025 [US2] Handle invalid credentials with generic error (401 Unauthorized)
- [x] T026 [P] [US2] Create frontend/src/components/auth/SignInForm.tsx with email/password fields
- [x] T027 [P] [US2] Create frontend/src/app/auth/signin/page.tsx using SignInForm component
- [x] T028 [US2] Connect SignInForm to Better Auth signin API
- [x] T029 [US2] Store JWT token in httpOnly cookie via Better Auth session
**Checkpoint**: Users can sign in and receive valid JWT tokens
---
## Phase 5: User Story 3 - Protected API Access (Priority: P3)
**Goal**: Authenticated users can access API with JWT tokens and only see their own data
**Independent Test**: Make API request with valid token and verify only authenticated user's tasks are returned
### Implementation for User Story 3
- [x] T030 [US3] Update backend/src/api/deps.py get_current_user to extract and verify JWT from Authorization header
- [x] T031 [US3] Add HTTPBearer security scheme to get_current_user dependency
- [x] T032 [US3] Extract user_id from JWT 'sub' claim in get_current_user
- [x] T033 [US3] Return 401 Unauthorized if token is missing in get_current_user
- [x] T034 [P] [US3] Update frontend/src/lib/api.ts fetchAPI to include Authorization: Bearer header
- [x] T035 [P] [US3] Get JWT token from Better Auth session in fetchAPI
- [x] T036 [US3] Verify all task endpoints filter by authenticated user_id (already implemented, just verify)
- [x] T037 [US3] Add GET /api/auth/me endpoint to return current user profile
**Checkpoint**: API requests require valid JWT tokens and enforce user data isolation
---
## Phase 6: User Story 4 - Invalid Token Handling (Priority: P4)
**Goal**: System rejects invalid, expired, or missing tokens with clear error responses
**Independent Test**: Make API requests with invalid/missing tokens and verify 401 responses
### Implementation for User Story 4
- [x] T038 [P] [US4] Handle expired token error (jwt.ExpiredSignatureError) in backend/src/core/security.py
- [x] T039 [P] [US4] Handle invalid signature error (jwt.InvalidTokenError) in backend/src/core/security.py
- [x] T040 [P] [US4] Handle malformed token error in backend/src/api/deps.py get_current_user
- [x] T041 [US4] Return 401 with error_code TOKEN_EXPIRED for expired tokens
- [x] T042 [US4] Return 401 with error_code TOKEN_INVALID for invalid tokens
- [x] T043 [US4] Return 401 with error_code TOKEN_MISSING for missing tokens
- [x] T044 [US4] Add 401 error handling in frontend/src/lib/api.ts to redirect to /auth/signin
**Checkpoint**: All authentication errors are handled gracefully with appropriate responses
---
## Phase 7: Polish & Cross-Cutting Concerns
**Purpose**: Integration, testing, and documentation
- [x] T045 [P] Create frontend/src/providers/AuthProvider.tsx to wrap app with Better Auth context
- [x] T046 [P] Update frontend/src/app/layout.tsx to include AuthProvider
- [x] T047 Protect frontend/src/app/page.tsx (task list) to require authentication
- [x] T047.1 Register auth router in backend/src/main.py (bugfix)
- [ ] T048 Test signup flow end-to-end (frontend → backend → database)
- [ ] T049 Test signin flow end-to-end (frontend → backend → JWT issuance)
- [ ] T050 Test protected API access (valid token → success, invalid → 401)
- [ ] T051 Test user data isolation (user A cannot access user B's tasks)
- [x] T052 Verify BETTER_AUTH_SECRET is identical in frontend and backend .env files
- [x] T053 Update backend/README.md with authentication setup instructions
- [x] T054 Update frontend/README.md with Better Auth configuration notes
---
## Dependencies & Execution Order
### Phase Dependencies
- **Setup (Phase 1)**: No dependencies - can start immediately
- **Foundational (Phase 2)**: Depends on Setup completion - BLOCKS all user stories
- **User Stories (Phase 3-6)**: All depend on Foundational phase completion
- User stories can proceed in parallel (if staffed)
- Or sequentially in priority order (P1 → P2 → P3 → P4)
- **Polish (Phase 7)**: Depends on all user stories being complete
### User Story Dependencies
- **User Story 1 (P1)**: Can start after Foundational - No dependencies on other stories
- **User Story 2 (P2)**: Can start after Foundational - Depends on US1 (needs User model with password_hash)
- **User Story 3 (P3)**: Can start after Foundational - Depends on US2 (needs JWT tokens to be issued)
- **User Story 4 (P4)**: Can start after US3 - Depends on JWT verification being implemented
### Within Each User Story
- Backend services before endpoints
- Backend endpoints before frontend components
- Frontend components before frontend pages
- Core implementation before error handling
### Parallel Opportunities
- **Phase 1**: T003, T004, T005, T006 can run in parallel
- **Phase 3 (US1)**: T014, T015 (backend) can run parallel with T019, T020 (frontend)
- **Phase 4 (US2)**: T026, T027 (frontend) can run parallel with backend work
- **Phase 5 (US3)**: T034, T035 (frontend) can run parallel with backend work
- **Phase 6 (US4)**: T038, T039, T040 can run in parallel
- **Phase 7**: T045, T046, T053, T054 can run in parallel
---
## Parallel Example: User Story 1
```bash
# Launch backend and frontend tasks together:
Task: "Create backend/src/services/auth_service.py with signup method"
Task: "Create backend/src/api/routes/auth.py with POST /api/auth/signup endpoint"
Task: "Create frontend/src/components/auth/SignUpForm.tsx"
Task: "Create frontend/src/app/auth/signup/page.tsx"
```
---
## Implementation Strategy
### MVP First (User Story 1 Only)
1. Complete Phase 1: Setup (T001-T006)
2. Complete Phase 2: Foundational (T007-T013) - CRITICAL
3. Complete Phase 3: User Story 1 (T014-T021)
4. **STOP and VALIDATE**: Test signup independently
5. Deploy/demo if ready
### Incremental Delivery
1. Setup + Foundational → Foundation ready
2. Add User Story 1 → Test independently → Deploy (MVP!)
3. Add User Story 2 → Test independently → Deploy
4. Add User Story 3 → Test independently → Deploy
5. Add User Story 4 → Test independently → Deploy
6. Polish → Final deployment
### Parallel Team Strategy
With multiple developers:
1. Team completes Setup + Foundational together
2. Once Foundational is done:
- Developer A: User Story 1 (signup)
- Developer B: User Story 2 (signin) - starts after US1 model is ready
- Developer C: User Story 3 (API protection) - starts after US2 tokens are ready
3. Stories integrate independently
---
## Notes
- Total tasks: 54
- MVP scope: Phase 1 + Phase 2 + Phase 3 (User Story 1) = 21 tasks
- [P] tasks = different files, no dependencies
- [Story] label maps task to specific user story
- Each user story should be independently testable
- Commit after each task or logical group
- Verify BETTER_AUTH_SECRET matches in both .env files
- Test authentication flow end-to-end before moving to next story