# Feature Specification: Authentication (SP-01)

**Feature Branch**: `feat/SP-01-authentication`

**Created**: 2026-06-01

**Status**: Draft

**Input**: Admin authentication via email/password with Bearer token, logout capability, and session invalidation.

## User Scenarios & Testing *(mandatory)*

### User Story 1 — Admin Login (Priority: P1)

As an Admin, I need to authenticate with my email and password credentials so that I receive a Bearer token to access all protected API endpoints.

**Why this priority**: Without authentication, no subsequent feature (SP-02 through SP-11) can be accessed. This is the foundational security layer for the entire system.

**Independent Test**: Can be fully tested by submitting valid credentials to the login endpoint and verifying a token is received and usable on protected routes.

**Acceptance Scenarios**:

1. **Given** the admin exists with correct credentials, **When** I submit valid email and password to the login endpoint, **Then** I receive a 200 response with a Bearer token, admin name, and admin email.

2. **Given** the admin exists but I submit an incorrect password, **When** I POST to the login endpoint, **Then** I receive a 401 unauthorized response with an error message.

3. **Given** I submit an email that does not match valid email format, **When** I POST to the login endpoint, **Then** I receive a 422 validation error response.

4. **Given** I submit an empty request body missing required fields, **When** I POST to the login endpoint, **Then** I receive a 422 validation error response.

5. **Given** I have attempted 5 failed login attempts within 60 seconds from the same IP, **When** I submit a 6th login attempt, **Then** I receive a 429 Too Many Requests response.

---

### User Story 2 — Admin Logout (Priority: P2)

As an authenticated Admin, I need to invalidate my current session token so that the token can no longer be used to access protected endpoints.

**Why this priority**: Session invalidation is a standard security requirement to ensure tokens can be revoked when the admin logs out or when security concerns arise.

**Independent Test**: Can be tested by authenticating, calling logout, then attempting to use the token on a protected endpoint and receiving a 401.

**Acceptance Scenarios**:

1. **Given** I am authenticated with a valid token, **When** I send a DELETE request to the logout endpoint, **Then** I receive a 200 success response and my token is deleted from the database.

2. **Given** I do not provide a valid authentication token, **When** I send a DELETE request to the logout endpoint, **Then** I receive a 401 unauthorized response.

---

### User Story 3 — Verify Current Session (Priority: P3)

As an authenticated Admin, I need to verify my token is still valid and retrieve my profile information.

**Why this priority**: Allows the admin to confirm their session status without performing any action. Useful for frontend session display and debugging.

**Independent Test**: Can be tested by authenticating, calling the /me endpoint, and verifying the response contains the admin's profile data.

**Acceptance Scenarios**:

1. **Given** I am authenticated with a valid token, **When** I send a GET request to the /me endpoint, **Then** I receive a 200 response with my admin profile (id, name, email, created_at).

2. **Given** I do not provide a valid authentication token, **When** I send a GET request to the /me endpoint, **Then** I receive a 401 unauthorized response.

---

### Edge Cases

- Login attempt with email that exists but password is empty string — treat as wrong password, return 401
- Logout when multiple tokens exist for same admin — delete only the current token used
- /me endpoint when admin data has been modified since token creation — return current admin data
- Rate limiting based on IP address — different IPs can each make 5 attempts per minute

## Requirements *(mandatory)*

### Functional Requirements

- **FR-001**: System MUST authenticate Admin users via email and password combination
- **FR-002**: System MUST return a Bearer token upon successful login
- **FR-003**: System MUST allow authenticated Admins to invalidate their own tokens via logout
- **FR-004**: System MUST allow authenticated Admins to verify their token validity and view their profile
- **FR-005**: System MUST rate-limit login attempts to 5 per minute per IP address
- **FR-006**: System MUST return appropriate HTTP status codes (200 success, 401 unauthorized, 422 validation error, 429 rate limited)
- **FR-007**: System MUST use a unified API response format for all endpoints
- **FR-008**: Token storage MUST be hashed — plain text tokens are prohibited
- **FR-009**: System MUST use Laravel Sanctum for token-based authentication
- **FR-010**: Admin account MUST be pre-seeded via environment variables (ADMIN_NAME, ADMIN_EMAIL, ADMIN_PASSWORD)

### Key Entities

- **Admin**: The single system user with name, email, and hashed password. Pre-seeded, not self-registered.
- **Personal Access Token**: Laravel Sanctum token associated with an Admin for API authentication.

## Success Criteria *(mandatory)*

### Measurable Outcomes

- **SC-001**: Admin can successfully authenticate and receive a token within 2 seconds of submitting valid credentials
- **SC-002**: Rate limiting blocks the 6th login attempt within 60 seconds — 6th request returns 429 within 100ms
- **SC-003**: A token invalidated via logout cannot be used on any protected endpoint — returns 401
- **SC-004**: All three auth endpoints (/login, /logout, /me) are reachable and return correct status codes
- **SC-005**: Feature tests achieve 100% pass rate on authentication scenarios (happy path, wrong credentials, missing fields, invalid token, rate limit)
- **SC-006**: System maintains single-admin constraint — no registration endpoint exists

## Assumptions

- Admin credentials (email/password) are provided via environment variables at deployment time
- Only one Admin account exists in the system
- The system timezone is Asia/Damascus as configured in config/app.php
- Token expiration follows Laravel Sanctum defaults (no remember-me functionality)
- Rate limiting applies per IP address using Laravel's built-in throttle middleware