Init
This commit is contained in:
228
tasks/03-authentication.md
Normal file
228
tasks/03-authentication.md
Normal file
@@ -0,0 +1,228 @@
|
||||
# Phase 3: Authentication (Cidaas OAuth2/OIDC)
|
||||
|
||||
**Status:** ⏳ Todo
|
||||
**Progress:** 0/18 tasks (0%)
|
||||
**Started:** -
|
||||
**Completed:** -
|
||||
**Assigned to:** -
|
||||
|
||||
---
|
||||
|
||||
## Overview
|
||||
|
||||
Implement complete Cidaas OAuth2/OIDC authentication with custom UI: login, registration, logout, session management, JWT validation, and rate limiting.
|
||||
|
||||
**Goal:** Fully functional authentication system with custom experimenta-branded login/registration UI.
|
||||
|
||||
---
|
||||
|
||||
## Dependencies
|
||||
|
||||
- ✅ Phase 1: Foundation must be completed
|
||||
- ✅ Phase 2: Database must be completed (users table needed)
|
||||
- ⚠️ **Required:** Cidaas credentials (CLIENT_ID, CLIENT_SECRET, BASE_URL)
|
||||
|
||||
---
|
||||
|
||||
## Tasks
|
||||
|
||||
### Dependencies Installation
|
||||
|
||||
- [ ] Install nuxt-auth-utils + jose
|
||||
|
||||
```bash
|
||||
pnpm add nuxt-auth-utils jose
|
||||
```
|
||||
|
||||
- [ ] Configure Cidaas environment variables in .env
|
||||
|
||||
```bash
|
||||
CIDAAS_BASE_URL=https://experimenta.cidaas.de
|
||||
CIDAAS_CLIENT_ID=xxx
|
||||
CIDAAS_CLIENT_SECRET=xxx
|
||||
CIDAAS_REDIRECT_URI=http://localhost:3000/api/auth/callback
|
||||
```
|
||||
|
||||
- [ ] Add Cidaas config to nuxt.config.ts runtimeConfig
|
||||
```typescript
|
||||
runtimeConfig: {
|
||||
cidaas: {
|
||||
baseUrl: process.env.CIDAAS_BASE_URL,
|
||||
clientId: process.env.CIDAAS_CLIENT_ID,
|
||||
clientSecret: process.env.CIDAAS_CLIENT_SECRET,
|
||||
redirectUri: process.env.CIDAAS_REDIRECT_URI,
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
### Server Utilities
|
||||
|
||||
- [ ] Create PKCE generator utility
|
||||
- File: `server/utils/pkce.ts`
|
||||
- Functions: `generatePKCE()` → returns { verifier, challenge }
|
||||
- Implementation: See [CIDAAS_INTEGRATION.md](../docs/CIDAAS_INTEGRATION.md#5-server-utilities)
|
||||
|
||||
- [ ] Create Cidaas API client utility
|
||||
- File: `server/utils/cidaas.ts`
|
||||
- Functions:
|
||||
- `exchangeCodeForToken(code, verifier)` → tokens
|
||||
- `fetchUserInfo(accessToken)` → user data
|
||||
- `registerUser(userData)` → registration result
|
||||
- See: [CIDAAS_INTEGRATION.md](../docs/CIDAAS_INTEGRATION.md#5-server-utilities)
|
||||
|
||||
- [ ] Create JWT validation utility
|
||||
- File: `server/utils/jwt.ts`
|
||||
- Function: `verifyIdToken(idToken)` → payload
|
||||
- Uses: jose library with JWKS
|
||||
- See: [CLAUDE.md: JWT Validation Pattern](../CLAUDE.md#jwt-validation-pattern)
|
||||
|
||||
### Auth API Endpoints
|
||||
|
||||
- [ ] Create /api/auth/login.post.ts endpoint
|
||||
- Generates PKCE challenge & state
|
||||
- Stores in HTTP-only cookies (5min TTL)
|
||||
- Returns Cidaas authorization URL
|
||||
- See: [CLAUDE.md: OAuth2 Login Flow](../CLAUDE.md#oauth2-login-flow-pattern)
|
||||
|
||||
- [ ] Create /api/auth/callback.get.ts endpoint
|
||||
- Validates state (CSRF protection)
|
||||
- Exchanges code for tokens (with PKCE)
|
||||
- Validates ID token (JWT)
|
||||
- Fetches user info from Cidaas
|
||||
- Creates/updates user in local DB
|
||||
- Creates encrypted session (nuxt-auth-utils)
|
||||
- Redirects to homepage
|
||||
- See: [CLAUDE.md: OAuth2 Callback](../CLAUDE.md#oauth2-callback-pattern)
|
||||
|
||||
- [ ] Create /api/auth/register.post.ts endpoint
|
||||
- Validates registration data (Zod schema)
|
||||
- Calls Cidaas registration API
|
||||
- Returns success/error
|
||||
- See: [CLAUDE.md: User Registration](../CLAUDE.md#user-registration-pattern)
|
||||
|
||||
- [ ] Create /api/auth/logout.post.ts endpoint
|
||||
- Clears session via clearUserSession()
|
||||
- Optional: Single Sign-Out at Cidaas
|
||||
- Returns success
|
||||
|
||||
- [ ] Create /api/auth/me.get.ts endpoint
|
||||
- Protected endpoint (requires session)
|
||||
- Returns current user data
|
||||
- Uses: requireUserSession()
|
||||
|
||||
### Client-Side Composables
|
||||
|
||||
- [ ] Create useAuth composable
|
||||
- File: `composables/useAuth.ts`
|
||||
- Functions:
|
||||
- `login(email)` → redirects to Cidaas
|
||||
- `logout()` → clears session, redirects
|
||||
- `register(data)` → calls registration API
|
||||
- Uses: useUserSession from nuxt-auth-utils
|
||||
- Returns: { user, loggedIn, login, logout, register }
|
||||
- See: [CLAUDE.md: OAuth2 Login Flow](../CLAUDE.md#oauth2-login-flow-pattern)
|
||||
|
||||
### UI Components
|
||||
|
||||
- [ ] Create LoginForm component
|
||||
- File: `components/Auth/LoginForm.vue`
|
||||
- Fields: Email input
|
||||
- Button: "Login with Cidaas"
|
||||
- Calls: `login(email)` from useAuth
|
||||
- See: [CIDAAS_INTEGRATION.md: UI Components](../docs/CIDAAS_INTEGRATION.md#8-ui-components)
|
||||
|
||||
- [ ] Create RegisterForm component
|
||||
- File: `components/Auth/RegisterForm.vue`
|
||||
- Fields: Email, Password, Confirm Password, First Name, Last Name
|
||||
- Validation: VeeValidate + Zod
|
||||
- Calls: `register(data)` from useAuth
|
||||
- See: [CIDAAS_INTEGRATION.md: UI Components](../docs/CIDAAS_INTEGRATION.md#8-ui-components)
|
||||
|
||||
- [ ] Create auth page with tabs
|
||||
- File: `pages/auth.vue`
|
||||
- Tabs: Login | Register (shadcn-nuxt Tabs component)
|
||||
- Embeds: LoginForm + RegisterForm
|
||||
- Styling: experimenta branding
|
||||
- See: [CIDAAS_INTEGRATION.md: UI Components](../docs/CIDAAS_INTEGRATION.md#8-ui-components)
|
||||
|
||||
### Middleware
|
||||
|
||||
- [ ] Create auth middleware
|
||||
- File: `middleware/auth.ts`
|
||||
- Redirects to /auth if not logged in
|
||||
- Stores intended destination for post-login redirect
|
||||
- See: [CLAUDE.md: Protected Route Middleware](../CLAUDE.md#protected-route-middleware-pattern)
|
||||
|
||||
- [ ] Create rate-limit middleware
|
||||
- File: `server/middleware/rate-limit.ts`
|
||||
- Limits:
|
||||
- /api/auth/login: 5 attempts / 15min per IP
|
||||
- /api/auth/register: 3 attempts / 1hour per IP
|
||||
- Returns 429 on exceed
|
||||
- See: [CLAUDE.md: Rate Limiting](../CLAUDE.md#rate-limiting-pattern)
|
||||
|
||||
### Testing
|
||||
|
||||
- [ ] Test OAuth2 flow end-to-end
|
||||
- Start at /auth page
|
||||
- Click "Login"
|
||||
- Redirect to Cidaas (if credentials configured)
|
||||
- Complete login
|
||||
- Verify callback works
|
||||
- Verify user created in DB
|
||||
- Verify session works
|
||||
|
||||
- [ ] Test session management
|
||||
- Verify session persists across page reloads
|
||||
- Verify session expires after 30 days (or config)
|
||||
- Test logout clears session
|
||||
|
||||
- [ ] Document authentication flow
|
||||
- Add detailed flow diagram to docs/CIDAAS_INTEGRATION.md (already exists)
|
||||
- Document any deviations from plan
|
||||
- Document Cidaas-specific quirks encountered
|
||||
|
||||
---
|
||||
|
||||
## Acceptance Criteria
|
||||
|
||||
- [x] nuxt-auth-utils and jose are installed
|
||||
- [x] All utilities (PKCE, Cidaas client, JWT) are implemented
|
||||
- [x] All 5 auth endpoints work correctly
|
||||
- [x] useAuth composable is functional
|
||||
- [x] LoginForm and RegisterForm components are styled and functional
|
||||
- [x] /auth page shows tabs with both forms
|
||||
- [x] auth middleware protects routes correctly
|
||||
- [x] rate-limit middleware works and returns 429 when exceeded
|
||||
- [x] OAuth2 flow works end-to-end (login → callback → session)
|
||||
- [x] Session management works (persist, expire, clear)
|
||||
- [x] User is created/updated in local DB on first login
|
||||
- [x] JWT tokens are validated correctly
|
||||
- [x] PKCE flow prevents authorization code interception
|
||||
- [x] State parameter prevents CSRF attacks
|
||||
- [x] Authentication is fully documented
|
||||
|
||||
---
|
||||
|
||||
## Notes
|
||||
|
||||
- **Cidaas Credentials:** You'll need to request CLIENT_ID and CLIENT_SECRET from experimenta admin
|
||||
- **Redirect URI:** Must be registered in Cidaas Admin Panel: `http://localhost:3000/api/auth/callback` (dev), `https://my.experimenta.science/api/auth/callback` (prod)
|
||||
- **Session Duration:** Configured to 30 days (can be adjusted in nuxt-auth-utils config)
|
||||
- **Custom UI:** We're NOT using Cidaas hosted pages - fully custom experimenta-branded UI
|
||||
|
||||
---
|
||||
|
||||
## Blockers
|
||||
|
||||
- ⚠️ **Cidaas Credentials Missing:** Cannot test OAuth2 flow without CLIENT_ID/SECRET
|
||||
- **Workaround:** Implement everything, test with mock/manual verification until credentials available
|
||||
|
||||
---
|
||||
|
||||
## Related Documentation
|
||||
|
||||
- [docs/CIDAAS_INTEGRATION.md](../docs/CIDAAS_INTEGRATION.md) - Complete implementation guide
|
||||
- [docs/ARCHITECTURE.md: Section 3.6](../docs/ARCHITECTURE.md#36-authentication--authorization-cidaas-oauth2oidc)
|
||||
- [CLAUDE.md: Authentication Patterns](../CLAUDE.md#authentication-patterns)
|
||||
- [docs/PRD.md: US-001, US-002](../docs/PRD.md#51-authentifizierung--benutzerverwaltung)
|
||||
Reference in New Issue
Block a user