Ctrl K
ComunidadGuías…

specs/014-email-verification/tasks.md

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
# Email Verification Requirements

## Introduction

Email verification ensures users own the email address they register with. Users receive a verification link after registration and must click it before their account becomes fully active.

## Requirements

### REQ-1: Verification Token Generation

**User Story**: As a system, I want to generate secure verification tokens, so that email verification links cannot be guessed or forged.

**Acceptance Criteria**:
- Generate cryptographically secure random token on registration
- Token stored in database with expiration timestamp
- Token is single-use (invalidated after verification)
- Default expiration: 24 hours (configurable)

### REQ-2: Verification Email

**User Story**: As a new user, I want to receive a verification email after registration, so that I can activate my account.

**Acceptance Criteria**:
- Email sent immediately after registration
- Email contains clickable verification link
- Link format: `{APP_URL}/verify-email?token={token}`
- Email includes expiration information
- Uses existing EmailService infrastructure

### REQ-3: Unverified User State

**User Story**: As a system, I want to restrict unverified users, so that only verified email addresses can access the application.

**Acceptance Criteria**:
- New users created with `emailVerified = false`
- Unverified users cannot login (authentication fails with specific error)
- Unverified users can request new verification email
- JWT token NOT returned on registration (only after verification)

### REQ-4: Email Verification Endpoint

**User Story**: As a user, I want to verify my email by clicking the link, so that my account becomes active.

**Acceptance Criteria**:
- Public GET endpoint `/auth/verify-email?token={token}`
- Valid token: set `emailVerified = true`, delete token, return success
- Expired token: return error with option to resend
- Invalid/used token: return appropriate error
- On success, user can now login and the welcome email is sent to the user

### REQ-6: Registration Flow Change

**User Story**: As a user, I want clear feedback after registration, so that I know to check my email.

**Acceptance Criteria**:
- Registration returns success message (not JWT token)
- Response indicates verification email was sent
- Response includes email address (masked: `j***@example.com`)

### REQ-7: Admin Bypass

**User Story**: As an admin, I want to manually verify users, so that I can help users with email issues.

**Acceptance Criteria**:
- Admin endpoint to set `emailVerified = true`
- Add to existing AdminController
- Analytics event logged for audit

### REQ-8: Configuration

**User Story**: As a developer, I want to configure email verification behavior, so that I can adjust for different environments.

**Acceptance Criteria**:
- `application.email.verification.enabled` - Enable/disable feature (default: true)
- `application.email.verification.expiration-hours` - Token expiration (default: 24)
- When disabled, registration works as before (returns JWT immediately)

## Non-Functional Requirements

### Architecture

- New `EmailVerificationToken` entity with: id, token, userId, expiresAt, createdAt
- New `EmailVerificationTokenRepository`
- Extend `User` entity with `emailVerified` boolean field
- New Flyway migration for schema changes
- Verification logic in `AuthenticationService` or new `EmailVerificationService`

### Security

- Tokens must be cryptographically random (use `SecureRandom`)
- Tokens should be URL-safe (Base64 URL encoding)
- Token length: minimum 32 bytes
- Tokens stored hashed in database (like passwords)
- Rate limiting on resend endpoint to prevent abuse
- Verification endpoint should not leak user existence

### Database Changes

- Add `email_verified` column to users table (BOOLEAN, NOT NULL, DEFAULT FALSE)
- New `email_verification_tokens` table:
  - id (UUID, PK)
  - user_id (UUID, FK to users)
  - token_hash (VARCHAR, indexed)
  - expires_at (TIMESTAMP)
  - created_at (TIMESTAMP)

### API Design

- `POST /auth/register` - Returns message, not token
- `GET /auth/verify-email?token={token}` - Verify email
- `POST /auth/resend-verification` - Request new verification email
- `PUT /admin/users/{id}/verify-email` - Admin manual verification

### Email Template

- Template name: `email_verification`
- Variables: fullName, verificationLink, expirationHours, domain
- Clear call-to-action button
- Expiration warning