223 lines
13 KiB
Markdown
223 lines
13 KiB
Markdown
# Requirements — CMS Frontend
|
|
|
|
## Intent Analysis Summary
|
|
|
|
- **User Request**: Build a React-based admin frontend for SlpModularCms, based on an example app (ZIP file) that uses shadcn/ui, Tailwind CSS v4 with primary color `#ac0000`, and React Router v7. First version focuses on Identity management (login, user management, profile, system settings); CMS content management comes later.
|
|
- **Request Type**: New Feature (new React SPA project added to an existing .NET backend)
|
|
- **Scope Estimate**: Multiple Components — new frontend project with API integration, auth layer, routing, multiple pages
|
|
- **Complexity Estimate**: Moderate — established tech stack from example app, clear API contract, well-defined auth flow, some security requirements
|
|
|
|
---
|
|
|
|
## Functional Requirements
|
|
|
|
### FR-01: Authentication — Login
|
|
- The application MUST provide a login page at `/login`
|
|
- Users authenticate with email + password via `POST /auth/login`
|
|
- On success: access token stored **in memory** (React state/context), refresh token stored in **httpOnly cookie** (secure, not accessible via JavaScript)
|
|
- On failure: display clear error message without revealing whether email or password is incorrect
|
|
- The login page is publicly accessible (unauthenticated)
|
|
|
|
### FR-02: Authentication — Session Management
|
|
- The app MUST automatically refresh the access token using the refresh token cookie via `POST /auth/refresh` when the access token expires or returns a 401
|
|
- On logout: call `POST /auth/revoke` to invalidate the refresh token; clear in-memory access token; redirect to `/login`
|
|
- After a page refresh, the app MUST attempt to restore the session by calling `/auth/refresh` using the httpOnly cookie; if it fails, redirect to `/login`
|
|
|
|
### FR-03: System Initialization — Setup Flow
|
|
- On app startup, call `GET /setup/status` to check if the system has been initialized
|
|
- If NOT initialized: redirect all traffic to `/setup` (initialization page)
|
|
- The `/setup` page allows creating the first Owner account via `POST /setup/owner` (email + password)
|
|
- After successful initialization, redirect to `/login`
|
|
|
|
### FR-04: Route Security
|
|
- All routes except `/login`, `/setup`, and `/invite/complete` MUST require authentication
|
|
- If the user is not authenticated and tries to access a protected route, redirect to `/login`
|
|
- Role-based guards MUST be applied per page:
|
|
- System Settings page: Owner only
|
|
- CMS Management page: Owner only
|
|
- User Management page: Owner and Admin
|
|
- Profile page: Any authenticated user
|
|
- Dashboard: Any authenticated user
|
|
|
|
### FR-05: Dashboard
|
|
- Authenticated users see a dashboard at `/` (or `/dashboard`)
|
|
- Dashboard shows:
|
|
- Welcome message with user's name and role
|
|
- Quick stats/overview widgets (user count, system status indicator)
|
|
- **System availability status indicator**: Shows current status (Available / Maintenance / Unavailable) with reason, sourced from `GET /availability/status`
|
|
|
|
### FR-06: User Management
|
|
- Accessible at `/users` (Owner and Admin only)
|
|
- Displays a list of users with name, email, role, and active status
|
|
- **Invite user**: Dialog/form to invite a new user by email + role selection; calls `POST /users/invite`; shows the generated invite link for sharing
|
|
- Future extensibility: edit user, deactivate user (backend not yet available)
|
|
|
|
### FR-07: User Invitation Completion Flow
|
|
- Public page at `/invite/complete?token={token}`
|
|
- On page load: validate the token via `GET /users/validate-invitation?token={token}`
|
|
- If valid: show a form to set a display name and password; submit via `POST /users/complete-setup`
|
|
- If invalid/expired: show appropriate error message with no form
|
|
- On success: show confirmation message and link to `/login`
|
|
|
|
### FR-08: Profile / Account Settings
|
|
- Accessible at `/profile` (any authenticated user)
|
|
- Displays current user's name, email, and role (read-only for now)
|
|
- Placeholder for future: change password, update display name
|
|
|
|
### FR-09: System Settings
|
|
- Accessible at `/settings` (Owner only)
|
|
- First version: read-only overview of system configuration (initialized status, current availability status)
|
|
- Placeholder structure for future settings categories (modules, CMS config, etc.)
|
|
- **Note**: The CMS availability master module (for managing multiple client CMS instances) has not been built yet. System Settings only shows the current global availability status from `GET /availability/status`.
|
|
|
|
### FR-10: Navigation
|
|
- Authenticated pages use a sidebar navigation layout (based on example app)
|
|
- Sidebar shows only navigation items relevant to the user's role:
|
|
- Dashboard: all authenticated users
|
|
- User Management: Owner and Admin
|
|
- System Settings: Owner only
|
|
- CMS Management: Owner only (multi-CMS management feature; restricted from the start even though it is a placeholder in v1)
|
|
- Profile: all authenticated users
|
|
- Logout button: all authenticated users
|
|
- Mobile-responsive: sidebar collapses on small screens
|
|
|
|
### FR-11: Dark / Light Theme
|
|
- Users can toggle between dark and light theme via a button in the UI
|
|
- Preference is persisted in `localStorage` (theme preference only — not auth data)
|
|
- Default: system preference
|
|
|
|
### FR-12: CMS Management (Placeholder)
|
|
- Page at `/cms` accessible to **Owner only**
|
|
- Non-Owner roles attempting to access `/cms` are redirected to an "Access Denied" page or back to `/`
|
|
- Shows a "Work in Progress" placeholder describing that this section will allow managing multiple client CMS instances
|
|
- CMS Management is NOT shown in the sidebar for Admin or User roles
|
|
|
|
---
|
|
|
|
## Non-Functional Requirements
|
|
|
|
### NFR-01: Technology Stack
|
|
- **Framework**: React 18 + TypeScript
|
|
- **Routing**: TanStack Router (file-based or code-based routing with full TypeScript support)
|
|
- **UI Components**: shadcn/ui (Radix UI primitives)
|
|
- **Styling**: Tailwind CSS v4, primary color `#ac0000`
|
|
- **Build tool**: Vite
|
|
- **Package manager**: pnpm
|
|
- **Theme**: next-themes (dark/light mode)
|
|
- **Icons**: lucide-react
|
|
- **Forms**: react-hook-form
|
|
- **Notifications**: sonner (toast)
|
|
|
|
> **Note**: The example app in the ZIP uses React Router v7. Route definitions and `<Link>` components must be migrated to TanStack Router equivalents during implementation.
|
|
|
|
### NFR-02: Project Location
|
|
- The React app is placed in `frontend/` at the root of the solution (sibling to `src/` and `SlpModularCms.sln`)
|
|
|
|
### NFR-03: API Configuration
|
|
- API base URL configured via `.env` file using `VITE_API_BASE_URL`
|
|
- A `.env.example` file is committed to version control as a template
|
|
- The actual `.env` is added to `.gitignore`
|
|
- No secrets or sensitive data are hardcoded in source code
|
|
|
|
### NFR-04: Authentication Security (SECURITY-12) + Documentation Updates
|
|
- Access token stored **in memory only** (React context/state) — never in localStorage or sessionStorage
|
|
- Refresh token sent as **httpOnly cookie** — the backend must set `Set-Cookie: refreshToken=...; HttpOnly; Secure; SameSite=Strict`
|
|
- **Note**: The backend currently returns the refresh token in the JSON response body. A CORS + cookie configuration update on the backend may be required in a later phase.
|
|
- Session invalidated on logout (token revoked, cookie cleared)
|
|
- **Documentation update requirement**: After implementation, verify that the API documentation in `aidlc-docs/features/slp-modular-cms-api/` is still accurate. If the backend requires changes to support httpOnly cookie-based refresh tokens (e.g., CORS policy updates, `Set-Cookie` header changes), update the relevant docs in that feature's directory. Also update `aidlc-docs/_shared/reverse-engineering/api-documentation.md` if any endpoint contracts change.
|
|
|
|
### NFR-05: HTTP Security Headers (SECURITY-04) + README Instructions
|
|
- The app's dev server and production build must serve with security headers
|
|
- The project root `README.md` MUST include a **Frontend Development** section with at minimum:
|
|
- Prerequisites (Node.js version, pnpm installation)
|
|
- How to install dependencies (`pnpm install`)
|
|
- How to configure the `.env` file (reference `.env.example`)
|
|
- How to start the dev server (`pnpm dev`)
|
|
- How to run the production build (`pnpm build`)
|
|
- When deployed, a web server or reverse proxy (nginx, etc.) MUST set:
|
|
- `Content-Security-Policy: default-src 'self'`
|
|
- `Strict-Transport-Security: max-age=31536000; includeSubDomains`
|
|
- `X-Content-Type-Options: nosniff`
|
|
- `X-Frame-Options: DENY`
|
|
- `Referrer-Policy: strict-origin-when-cross-origin`
|
|
|
|
### NFR-06: Input Validation (SECURITY-05)
|
|
- All form inputs are validated client-side using react-hook-form before submission
|
|
- Password fields enforce the **exact backend rules** (verified in `ServiceCollectionExtensions.cs`):
|
|
- Minimum length: **8 characters**
|
|
- At least **1 uppercase letter** (`RequireUppercase = true`)
|
|
- At least **1 lowercase letter** (`RequireLowercase = true`)
|
|
- At least **1 digit** (`RequireDigit = true`)
|
|
- At least **1 non-alphanumeric character** (`RequireNonAlphanumeric = true`, e.g. `!@#$%^&*`)
|
|
- Inline per-rule validation messages indicate which specific rule is not yet met
|
|
- Validation also includes: required fields, email format, max lengths
|
|
- Server-side validation errors are displayed to the user without exposing internal details
|
|
|
|
### NFR-07: Access Control (SECURITY-08)
|
|
- Frontend enforces role-based access as a UX layer (hide menu items, redirect on unauthorized access)
|
|
- Backend authorization is the authoritative access control — frontend enforcement is defense-in-depth only
|
|
- No sensitive operations are performed based solely on client-side role information
|
|
|
|
### NFR-08: Error Handling (SECURITY-15, SECURITY-09)
|
|
- API errors shown to users use generic messages; technical details logged to the browser console only in development
|
|
- Global error boundary catches unexpected React errors and shows a user-friendly fallback UI
|
|
- 401 responses trigger token refresh or redirect to login
|
|
- 403 responses show an "Access Denied" page without internal details
|
|
- 404 responses show a "Not Found" page
|
|
|
|
### NFR-09: Structured Logging (SECURITY-03)
|
|
- API client logs requests/responses at debug level (not in production builds)
|
|
- Auth errors, token refresh events, and navigation failures logged at warning level
|
|
- No passwords, tokens, or PII in any log output
|
|
|
|
### NFR-10: Dependency Management (SECURITY-10)
|
|
- A `pnpm-lock.yaml` lock file is committed to version control
|
|
- Only packages from official npm registry are used
|
|
- No unused dependencies included
|
|
|
|
### NFR-11: Structured Application Logging (SECURITY-11)
|
|
- Auth and route guard logic is isolated in dedicated modules (`src/auth/`, `src/router/`)
|
|
- API communication is centralized in a dedicated API client (`src/api/`)
|
|
- No auth or security logic scattered across component files
|
|
|
|
---
|
|
|
|
## Security Baseline Compliance Summary (at Requirements stage)
|
|
|
|
| Rule | Status | Notes |
|
|
|------|--------|-------|
|
|
| SECURITY-01 (Encryption at Rest/Transit) | N/A | Frontend SPA — no data store; backend handles this |
|
|
| SECURITY-02 (Access Logging) | N/A | Frontend SPA — infrastructure concern handled at deployment |
|
|
| SECURITY-03 (Application Logging) | Compliant | NFR-09 addresses structured logging |
|
|
| SECURITY-04 (HTTP Security Headers) | Compliant | NFR-05 addresses required headers |
|
|
| SECURITY-05 (Input Validation) | Compliant | NFR-06 addresses client-side validation |
|
|
| SECURITY-06 (Least Privilege) | N/A | Frontend SPA — no IAM policies |
|
|
| SECURITY-07 (Network Configuration) | N/A | Frontend SPA — infrastructure concern |
|
|
| SECURITY-08 (Application Access Control) | Compliant | NFR-07 addresses role-based access |
|
|
| SECURITY-09 (Hardening) | Compliant | NFR-08 addresses error handling; NFR-03 addresses no hardcoded secrets |
|
|
| SECURITY-10 (Supply Chain) | Compliant | NFR-10 addresses lock file and trusted sources |
|
|
| SECURITY-11 (Secure Design) | Compliant | NFR-11 addresses separation of concerns |
|
|
| SECURITY-12 (Authentication) | Compliant | NFR-04 addresses secure token storage; FR-01/FR-02 address session management |
|
|
| SECURITY-13 (Data Integrity) | N/A | No external script loading from CDN; SRI not applicable |
|
|
| SECURITY-14 (Alerting/Monitoring) | N/A | Frontend SPA — infrastructure/backend concern |
|
|
| SECURITY-15 (Exception Handling) | Compliant | NFR-08 addresses error boundaries and fail-safe defaults |
|
|
|
|
---
|
|
|
|
## Constraints and Assumptions
|
|
|
|
- The example React app (from ZIP) serves as the design and structural foundation; all pages must match its visual style
|
|
- The backend API already provides all required endpoints (auth, setup, users, availability)
|
|
- The backend may need a minor update to support httpOnly cookie-based refresh token delivery (backend change is out of scope for this feature; FR-04 auth can use body-based refresh token temporarily)
|
|
- CMS content management functionality is explicitly out of scope for the first version
|
|
- The availability "master module" (multi-CMS management) is not yet built; dashboard only shows current single-instance status
|
|
|
|
---
|
|
|
|
## Open Questions / Future Work
|
|
|
|
- Backend CORS + httpOnly cookie support for refresh tokens (currently tokens are returned in response body)
|
|
- User list endpoint (`GET /users`) — not yet confirmed in API documentation; needs backend verification
|
|
- Availability master module (managing multiple CMS instances) — placeholder in System Settings for now
|
|
- Profile editing (change password, display name update) — backend endpoints not yet confirmed
|