# INVEETAIRE
## SPRINT 2 PLANNING DOCUMENT

| Field | Value |
|-------|-------|
| Document Type | Sprint Planning |
| Subject | Inveetaire Sprint 2 — Authentication & Authorization |
| Version | 1.0 |
| Status | Ready for Review |
| Prerequisite | Sprint 1 ✅ COMPLETE (commit `6616264`) |
| Framework | Frozen — immutable during Sprint 2 (except approved extension points) |
| Based On | MIB v1.1 · DBP v1.1 · AI.md v1.1 · ADR v1.0 · SPRINT1_ARCHITECTURE_REVIEW.md |

---

## 1. Sprint Objective

The primary objective of Sprint 2 is to deliver a secure, robust **Authentication & Authorization** layer for the Inveetaire platform. This covers unified secure login, session timeout enforcement, role-based access control (guards) for the three user roles (`couple`, `crew`, and `super_admin`), and forgot password flows.

This sprint establishes the boundary between anonymous guests and authenticated workspace operators. By the end of Sprint 2, the application must be able to securely authenticate users, isolate portal access using middleware, and enforce timeouts.

---

## 2. Sprint Scope

Sprint 2 is strictly scoped to:

1. **Pre-checklist Build Configuration (TD-006 / TD-007):** Commit `tailwind.config.js` and build scripts, ensuring reproducible asset compilation for the login and reset forms.
2. **AUTH-001 — Login Page & Logic:** Create the unified login page at `/login` with password verification, IP-based lockout protection, and CSRF protection.
3. **AUTH-002 — Logout & Session Destruction:** Implement secure session termination (POST `/logout`).
4. **AUTH-004 — Session Timeout & Regeneration (Middleware):** Create `AuthMiddleware` (for authentication checks) and `RoleMiddleware` (for authorization guards), and implement session absolute/inactivity timeouts.
5. **AUTH-003 — Password Reset Flow:** Implement forgot password requests, token generation, link distribution (simulated local cache/flash for MVP), and password update forms.

### Out of Scope for Sprint 2:
* Workspace provisioning, registration, or creation (Sprint 3).
* Theme loading or rendering configurations (Sprint 3).
* Guest CRUD or imports (Sprint 4).
* Database schema changes (the schema is frozen).

---

## 3. Sprint Deliverables

| Deliverable | Task ID | Type | File(s) |
|-------------|---------|------|---------|
| Build Configuration | TD-006/7 | New/Updated | `tailwind.config.js`, `build/README.md` (or script), `README.md` |
| Unified Login Page | AUTH-001 | New Module | `app/modules/Auth/AuthController.php`, `AuthService.php`, `AuthModel.php`, `views/login.php`, `routes.php` |
| Logout Action | AUTH-002 | Modified | `app/modules/Auth/AuthController.php`, `AuthService.php` |
| Security Middleware | AUTH-004 | New Files | `app/middleware/AuthMiddleware.php`, `app/middleware/RoleMiddleware.php` |
| Session Extensions | AUTH-004 | Modified | `app/core/Session.php` |
| Password Reset Views | AUTH-003 | New Files | `app/modules/Auth/views/forgot_password.php`, `app/modules/Auth/views/reset_password.php` |
| Password Reset Logic | AUTH-003 | Modified | `app/modules/Auth/AuthController.php`, `AuthService.php`, `AuthModel.php` |

---

## 4. Dependency & Extension Points Review

### 4.1 Prerequisites
All required database tables (`users`, `roles`, `sessions`, `support_sessions`, `crew_accounts`) are defined in PDD v1.0 and must be migrated and seeded in the database:
* **Roles Seeded:** ID 1 (`super_admin`), ID 2 (`couple`), ID 3 (`crew`).
* **Environment Keys:** `.env` must declare portal-specific timeout values (`SESSION_TIMEOUT_ADMIN`, `SESSION_TIMEOUT_COUPLE`, `SESSION_TIMEOUT_CREW`) and `SESSION_INACTIVITY_TIMEOUT` (default `7200`).

### 4.2 Extension Points Used
1. **Middleware Engine:** The `MiddlewarePipeline` and `Router` will resolve and wrap `AuthMiddleware` and `RoleMiddleware` by mapping route names.
2. **CSRF Integration:** The POST `/login`, POST `/logout`, POST `/forgot-password`, and POST `/reset-password` routes will register `CsrfMiddleware` to protect inputs.
3. **Module Autoloading:** The PSR-4 autoloader maps `App\Modules\Auth\...` to `app/modules/Auth/`.

---

## 5. Task Definitions

### AUTH-001 — Build Login Page and Authentication Logic
* **Objective:** Authenticate user credentials and establish a secure session.
* **Scope:**
  * Route GET `/login` rendering the login form.
  * Route POST `/login` validating email (or username for crew), verifying password against bcrypt hash (`password_verify()`).
  * On Success: Regenerate session ID (`Session::regenerate()`), bind role and workspace ID snapshots into session, log success, and redirect to matching portal.
  * On Failure: Log warning, increment attempts, and apply temporary lockout (IP-based) after 5 consecutive failures.
  * POST route must be protected by `CsrfMiddleware`.
* **Prerequisites:** `INIT-009` (Middleware Pipeline), `INIT-010` (Session/CSRF), `INIT-012` (Database Connection), and resolving `TD-006`/`TD-007` to ensure CSS styling is generated.
* **Files Expected [NEW]:**
  * `app/modules/Auth/AuthController.php`
  * `app/modules/Auth/AuthService.php`
  * `app/modules/Auth/AuthModel.php`
  * `app/modules/Auth/views/login.php`
  * `app/modules/Auth/routes.php`
* **Files Modified:**
  * `routes/public.php` (load `app/modules/Auth/routes.php` or map `/login` routes)
  * *Note: The `Auth` module is already registered in `config/modules.php` in the baseline, so no modification is required for registration.*
* **Acceptance Criteria:**
  * Correct credentials for each role log in successfully and redirect to correct dashboards.
  * Session ID is regenerated on login.
  * 5 consecutive incorrect logins block IP temporarily.
  * Missing/invalid CSRF token returns 403.
* **Estimated AI Coding Sessions:** 2 sessions.

### AUTH-002 — Build Logout and Session Destruction
* **Objective:** Terminate sessions and destroy credentials.
* **Scope:**
  * Route POST `/logout` destroying the session (`Session::destroy()`), deleting the file in `storage/sessions/`, clearing the cookie, invalidating CSRF, and redirecting to `/login`.
* **Dependencies:** `AUTH-001`.
* **Files Expected:** None (uses Auth Controller & Service).
* **Files Modified:**
  * `app/modules/Auth/AuthController.php` (add logout action)
  * `app/modules/Auth/AuthService.php` (add session destruction logic)
* **Acceptance Criteria:**
  * POST `/logout` terminates session and invalidates cookie.
  * Accessing authenticated portal links after logout redirects to `/login`.
* **Estimated AI Coding Sessions:** 1 session.

### AUTH-004 — Build Session Timeout and Regeneration
* **Objective:** Enforce absolute and inactivity session boundaries.
* **Scope:**
  * Implement `AuthMiddleware.php` checking authentication presence.
  * Implement `RoleMiddleware.php` checking role snapshot mapping.
  * Enforce absolute timeouts (8h admin, 24h couple, 12h crew) and inactivity timeout (2h universal) using session timestamps.
  * Destroy expired sessions and redirect to `/login` with an expiry flash message.
  * Ensure session ID is regenerated on support mode entry/exit.
* **Dependencies:** `AUTH-001`.
* **Files Expected [NEW]:**
  * `app/middleware/AuthMiddleware.php`
  * `app/middleware/RoleMiddleware.php`
* **Files Modified:**
  * `app/core/Session.php` (timeout calculation and check helper)
  * `app/modules/Auth/AuthService.php` (integrate timeout properties)
* **Acceptance Criteria:**
  * Anonymous access is blocked by `AuthMiddleware`.
  * Unauthorized roles are blocked by `RoleMiddleware` with a 403 Forbidden page.
  * Manipulated session timestamps trigger redirection on next request.
* **Estimated AI Coding Sessions:** 1 session.

### AUTH-003 — Build Password Reset Flow
* **Objective:** Secure forgot-password retrieval for admin and couple users.
* **Scope:**
  * Route GET/POST `/forgot-password` generating a random secure 64-char hex token.
  * Store token with a 1-hour expiration.
  * Since shared hosting SMTP is omitted in MVP, reset links are written to secure files in `storage/logs/` and shown in flash messages for local testing.
  * Route GET/POST `/reset-password/{token}` checking expiration/existence and updating password bcrypt hash.
  * Crew users are excluded (passwords reset via Couple portal).
* **Prerequisites:** `AUTH-001`.
* **Design Choice (Database Isolation):** To respect the frozen database schema and avoid adding a new table or modifying the `users` table without a DRP, password reset tokens are stored as encrypted JSON payloads inside `storage/cache/` (fully protected from web access by `.htaccess` rules) named `reset_token_{token}.json`.
* **Files Expected [NEW]:**
  * `app/modules/Auth/views/forgot_password.php`
  * `app/modules/Auth/views/reset_password.php`
* **Files Modified:**
  * `app/modules/Auth/AuthController.php` (password reset actions)
  * `app/modules/Auth/AuthService.php` (token generation and check methods)
  * `app/modules/Auth/AuthModel.php` (update password hash queries)
* **Acceptance Criteria:**
  * Token expires after 1 hour or immediate usage.
  * Updating updates `users.password_hash` using bcrypt.
* **Estimated AI Coding Sessions:** 1 session.

---

## 6. Execution Order

The execution sequence must proceed according to strict dependencies:

```
[TD-006 & TD-007 Build Setup]
            │
            ▼
        [AUTH-001] (Unified Login & Logic)
            │
            ├──────────────────────┐
            ▼                      ▼
        [AUTH-002] (Logout)    [AUTH-004] (Session Timeout & Middleware Guards)
            │                      │
            └──────────┬───────────┘
                       ▼
                   [AUTH-003] (Password Reset Flow)
```

1. **Pre-checklist:** version build tools & Tailwind config (recompile CSS).
2. **Task 1: AUTH-001** (establish base Controller, Model, Service, and login forms).
3. **Task 2: AUTH-002** (secure logout endpoint).
4. **Task 3: AUTH-004** (middleware protection and session timeouts).
5. **Task 4: AUTH-003** (password reset flow).

---

## 7. Expected Repository Changes

### New Folders
None.

### New Files
* `app/modules/Auth/AuthController.php` (AUTH-001)
* `app/modules/Auth/AuthService.php` (AUTH-001)
* `app/modules/Auth/AuthModel.php` (AUTH-001)
* `app/modules/Auth/views/login.php` (AUTH-001)
* `app/modules/Auth/routes.php` (AUTH-001)
* `app/middleware/AuthMiddleware.php` (AUTH-004)
* `app/middleware/RoleMiddleware.php` (AUTH-004)
* `app/modules/Auth/views/forgot_password.php` (AUTH-003)
* `app/modules/Auth/views/reset_password.php` (AUTH-003)
* `tailwind.config.js` (TD-006)
* `build/README.md` (TD-007)

### Existing Files Modified
* `routes/public.php` (AUTH-001)
* `app/core/Session.php` (AUTH-004)
* `README.md` (TD-007)

### Files That Must NOT Be Modified (Kernel/Governance Freeze)
* `app/core/Bootstrap.php` (Kernel — Frozen)
* `app/core/Router.php` (Kernel — Frozen)
* `app/core/Database.php` (Kernel — Frozen)
* `app/core/BaseController.php` (Kernel — Frozen)
* `app/core/BaseModel.php` (Kernel — Frozen)
* `app/core/BaseService.php` (Kernel — Frozen)
* `app/core/ErrorHandler.php` (Kernel — Frozen)
* `app/core/Logger.php` (Kernel — Frozen)
* `app/core/MiddlewarePipeline.php` (Kernel — Frozen)
* `app/core/Request.php` (Kernel — Frozen)
* `app/core/Csrf.php` (Kernel — Frozen)
* `docs/ai/*` (Governance — Frozen)

---

## 8. Architectural Constraints

* **Kernel Immutability:** No core classes are modified except `Session.php` (extended for timeouts/regeneration checks as permitted by MIB AUTH-004).
* **Database Freeze:** The DB schema is immutable. No tables or columns are added. Temporary tokens are stored in `storage/cache/` JSON payloads.
* **Middleware Integrity:** The concrete middleware classes must implement `MiddlewareInterface` and return forbidden responses via `ErrorHandler::renderForbidden()`.
* **Output Escaping:** Every dynamic string printed on the login or password reset views must be wrapped in `escape_html()`.
* **Clean Controller Boundaries:** Controllers must remain under 20 lines. Database operations are strictly in `AuthModel`, and session lifecycle checks are in `AuthService`.

---

## 9. Testing Strategy

1. **Access Control Guards:**
   * Access portal routes (e.g. `/app/couple/dashboard`) anonymously → confirm 302 redirect to `/login`.
   * Access portal routes with wrong role (e.g. crew trying to open admin dashboard) → confirm 403 Forbidden.
2. **Credential Security:**
   * Test valid logins for `super_admin`, `couple`, and `crew` credentials.
   * Verify incorrect password displays standard validation error.
   * Test 5 failed attempts → verify IP lockout state.
3. **Session Management:**
   * Verify session ID changes before and after successful login (`session_regenerate_id`).
   * Verify session ID changes on support mode transitions.
   * Verify session files are deleted on logout.
4. **Timeout Verifications:**
   * Manually adjust session timestamp values inside session files.
   * Verify universal inactivity timeout (2h) triggers redirect.
   * Verify role-based absolute timeout triggers redirect.
5. **CSRF Validation:**
   * Attempt POST requests without a CSRF token → verify 403 Forbidden.

---

## 10. Security Checklist

This is a verification checklist to guide implementation and code reviews during Sprint 2:
* [ ] **password_hash()**: Always hash password inputs using `PASSWORD_BCRYPT`. Do not store raw or unsalted password strings.
* [ ] **password_verify()**: Used for credential authentication against hashed values retrieved from the `users` table.
* [ ] **session_regenerate_id(true)**: Execute via `Session::regenerate(true)` upon successful authentication and support session context changes to prevent session fixation.
* [ ] **Session::destroy()**: Invoked on logout to clean the `$_SESSION` array, remove cookie variables from the browser, and delete server session files.
* [ ] **hash_equals()**: Used in `Csrf::validate()` for constant-time comparisons, mitigating timing attacks on CSRF tokens.
* [ ] **escape_html()**: Encapsulate all output variables inside views/layouts to prevent cross-site scripting (XSS).
* [ ] **CsrfMiddleware**: Implement to guard POST routes, rendering a 403 Forbidden page via `ErrorHandler::renderForbidden()` on verification failure.
* [ ] **AuthMiddleware**: Block unauthenticated requests to portal folders and redirect them to `/login`.
* [ ] **RoleMiddleware**: Validate user portal access by checking role snapshots, rendering a 403 Forbidden page on mismatch.
* [ ] **Logger::info()**: Record non-sensitive audit events, including successful logins and logouts.
* [ ] **Logger::warning()**: Record authentication failures, lockout events, and failed CSRF token validations.
* [ ] **Logger::error()**: Record system-level failures, exceptions, or connection failures.
* [ ] **ErrorHandler**: Intercept unhandled exceptions, hide stack details on production, and delegate to Logger.
* [ ] **Secure session cookie flags**: Cookie is sent with `HttpOnly`, `SameSite=Strict`, and `Secure` (production) constraints.

---

## 11. Exit Criteria

Sprint 2 is successful when all the following are true:

| Criterion | Verification Method |
|-----------|---------------------|
| Build setup files committed (`tailwind.config.js`) | Git status / file inspection |
| Login view renders and verifies credentials against hashed passwords | Manual and functional test |
| Auth and Role middleware protect portal paths | Manual test |
| Logout removes cookie and destroys session file | File/browser check |
| Universal inactivity and role timeouts trigger logout | Simulated timeout check |
| Password reset link generated and token validation functional | Flash/file check and update check |
| All POST routes wire `CsrfMiddleware` | Route file audit |
| Code quality, escaping, and thin controllers verified | Peer code audit |

---

## 12. Technical Debt Management

### Resolved in Sprint 2:
* **TD-006 (Build Configuration Versioning):** resolved by committing `tailwind.config.js`.
* **TD-007 (Build Tooling Documentation):** resolved by writing `build/README.md`.
* **AF-001 (CSRF Middleware Routing):** resolved by routing POST endpoints through `CsrfMiddleware`.

### Deferred:
* **TD-002 (CSP):** Deferred to Sprint 3 pre-checklist.
* **TD-003 (Log Rotation):** Deferred to pre-launch.
* **TD-005 (Google Fonts local serving):** Deferred to Sprint 2+ (non-blocking).
