docs: update documentation of STA
This commit is contained in:
@@ -1,8 +1,8 @@
|
||||
# CORS Configuration Guide
|
||||
|
||||
**Last Updated**: 2026-01-03
|
||||
**Related Tasks**: T009 (Tests), T010 (Implementation)
|
||||
**Status**: Implemented (Phase 0.5)
|
||||
**Last Updated**: 2026-01-23
|
||||
**Related Tasks**: T009-T016
|
||||
**Status**: Complete (Phase 0.5)
|
||||
|
||||
## Overview
|
||||
|
||||
@@ -44,7 +44,7 @@ Relay Device (local network)
|
||||
|
||||
### CorsSettings Struct
|
||||
|
||||
Located in `backend/src/settings.rs` (lines 217-232):
|
||||
Located in `backend/src/settings/cors.rs`:
|
||||
|
||||
```rust
|
||||
#[derive(Debug, serde::Deserialize, Clone)]
|
||||
@@ -76,7 +76,7 @@ The implementation uses a **hybrid approach** (Option C from research):
|
||||
- `allow_credentials`: Whether to allow cookies/auth headers
|
||||
- `max_age_secs`: How long browsers cache preflight responses
|
||||
|
||||
**Hardcoded in Implementation** (will be in T014):
|
||||
**Hardcoded in Implementation**:
|
||||
- **Methods**: `GET`, `POST`, `PUT`, `PATCH`, `DELETE`, `OPTIONS` (API-specific)
|
||||
- **Headers**: `content-type`, `authorization` (minimum for API)
|
||||
|
||||
@@ -109,7 +109,7 @@ frontend_url: http://localhost:5173 # Vite default port
|
||||
|
||||
### Production Environment
|
||||
|
||||
**File**: `backend/settings/production.yaml` (to be created in T012)
|
||||
**File**: `backend/settings/production.yaml`
|
||||
|
||||
```yaml
|
||||
cors:
|
||||
@@ -129,23 +129,7 @@ frontend_url: "https://sta.example.com"
|
||||
|
||||
### Integration with Settings System
|
||||
|
||||
The `CorsSettings` struct is integrated into the main `Settings` struct (line 30):
|
||||
|
||||
```rust
|
||||
#[derive(Debug, serde::Deserialize, Clone, Default)]
|
||||
pub struct Settings {
|
||||
pub application: ApplicationSettings,
|
||||
pub debug: bool,
|
||||
pub frontend_url: String,
|
||||
pub rate_limit: RateLimitSettings,
|
||||
pub modbus: ModbusSettings,
|
||||
pub relay: RelaySettings,
|
||||
#[serde(default)] // Uses Default::default() if missing
|
||||
pub cors: CorsSettings,
|
||||
}
|
||||
```
|
||||
|
||||
The `#[serde(default)]` attribute ensures backward compatibility: if the `cors` section is missing from YAML, it uses the restrictive `Default` implementation.
|
||||
The `CorsSettings` struct is part of the settings module. Settings are loaded with `#[serde(default)]` to ensure backward compatibility: if the `cors` section is missing from YAML, it uses the restrictive `Default` implementation.
|
||||
|
||||
### Loading and Precedence
|
||||
|
||||
@@ -318,7 +302,7 @@ cargo test -p sta cors -- --nocapture
|
||||
|
||||
**Browser Security Policy**: When `allow_credentials: true`, wildcard origins (`*`) are **forbidden** by the CORS specification.
|
||||
|
||||
**Enforcement**: The upcoming `build_cors()` function (T014) will panic during startup if this constraint is violated:
|
||||
**Enforcement**: The `From<CorsSettings> for Cors` implementation panics during startup if this constraint is violated:
|
||||
|
||||
```rust
|
||||
if settings.allow_credentials && settings.allowed_origins.contains(&"*".to_string()) {
|
||||
@@ -427,11 +411,9 @@ cors:
|
||||
|
||||
### Preflight Requests Failing (OPTIONS)
|
||||
|
||||
**Cause**: Backend not allowing OPTIONS method (will be fixed in T014).
|
||||
**Cause**: Backend not allowing OPTIONS method.
|
||||
|
||||
**Temporary Workaround**: None - wait for T014 implementation.
|
||||
|
||||
**Permanent Solution**: The upcoming `build_cors()` function will hardcode:
|
||||
**Solution**: The `From<CorsSettings> for Cors` trait implementation hardcodes OPTIONS in the allowed methods:
|
||||
```rust
|
||||
cors.allow_methods(vec![
|
||||
Method::GET, Method::POST, Method::PUT,
|
||||
@@ -454,13 +436,13 @@ cors.allow_methods(vec![
|
||||
|
||||
### Headers Not Allowed
|
||||
|
||||
**Cause**: Custom headers not in allowed list (will be in T014).
|
||||
**Cause**: Custom headers not in allowed list.
|
||||
|
||||
**Current Allowed Headers** (to be implemented):
|
||||
**Current Allowed Headers**:
|
||||
- `content-type` (for JSON request bodies)
|
||||
- `authorization` (for Authelia authentication tokens)
|
||||
|
||||
**Adding Custom Headers**: Requires modifying `build_cors()` function (T014).
|
||||
**Adding Custom Headers**: Requires modifying the `From<CorsSettings> for Cors` trait implementation.
|
||||
|
||||
## Dependencies
|
||||
|
||||
@@ -481,37 +463,43 @@ serde_yaml = "0.9.34"
|
||||
|
||||
| File | Purpose |
|
||||
|------|---------|
|
||||
| `backend/src/settings.rs` | `CorsSettings` struct definition |
|
||||
| `backend/settings/base.yaml` | Baseline configuration (no CORS section yet) |
|
||||
| `backend/src/settings/cors.rs` | `CorsSettings` struct definition |
|
||||
| `backend/settings/base.yaml` | Baseline configuration |
|
||||
| `backend/settings/development.yaml` | Development CORS (permissive) |
|
||||
| `backend/settings/production.yaml` | Production CORS (restrictive) - to be created in T012 |
|
||||
| `backend/settings/production.yaml` | Production CORS (restrictive) |
|
||||
|
||||
## Next Steps (Remaining Tasks)
|
||||
## Completed Tasks
|
||||
|
||||
### T011: Update development.yaml
|
||||
- Add `cors:` section with permissive settings
|
||||
- Update `frontend_url` to `http://localhost:5173` (Vite default)
|
||||
All CORS configuration tasks (T009-T016) have been implemented and tested:
|
||||
|
||||
### T012: Create production.yaml
|
||||
- Add `cors:` section with restrictive settings
|
||||
- Use `https://sta.example.com` as allowed origin
|
||||
- Set `allow_credentials: true` for Authelia
|
||||
### T009-T010: CorsSettings Struct (Phase 0.5)
|
||||
- 5 unit tests written (TDD approach) and the `CorsSettings` struct implemented with fail-safe defaults
|
||||
- Located in `backend/src/settings/cors.rs`
|
||||
|
||||
### T013-T014: Implement build_cors() Function
|
||||
- Create `build_cors(settings: &CorsSettings) -> Cors` in `startup.rs`
|
||||
- Validate wildcard + credentials constraint
|
||||
- Hardcode methods (GET, POST, PUT, PATCH, DELETE, OPTIONS)
|
||||
- Hardcode headers (content-type, authorization)
|
||||
- Add structured logging
|
||||
### T011: Development YAML Configuration
|
||||
- Added `cors:` section with wildcard origin and `allow_credentials: false`
|
||||
- Updated `frontend_url` to `http://localhost:5173` (Vite default)
|
||||
- File: `backend/settings/development.yaml`
|
||||
|
||||
### T015: Replace Cors::new() in Middleware Chain
|
||||
- Update `startup.rs` line ~86
|
||||
- Call `build_cors(&value.settings.cors)`
|
||||
### T012: Production YAML Configuration
|
||||
- Added `cors:` section with specific origin and `allow_credentials: true`
|
||||
- File: `backend/settings/production.yaml`
|
||||
|
||||
### T013-T014: Cors Middleware Implementation
|
||||
- 6 unit tests written for the `From<CorsSettings> for Cors` trait
|
||||
- Implemented the conversion trait in `backend/src/settings/cors.rs`
|
||||
- Validates wildcard + credentials constraint (panics on misconfiguration)
|
||||
- Hardcodes methods (GET, POST, PUT, PATCH, DELETE, OPTIONS)
|
||||
- Hardcodes headers (content-type, authorization)
|
||||
- Adds structured logging
|
||||
|
||||
### T015: Middleware Chain Integration
|
||||
- Replaced `Cors::new()` with `Cors::from(settings.cors)` in startup.rs
|
||||
- CORS applied after rate limiting (order: RateLimit → CORS → Data)
|
||||
|
||||
### T016: Integration Tests
|
||||
- Write tests verifying CORS headers in HTTP responses
|
||||
- Test OPTIONS preflight requests
|
||||
- Verify `Access-Control-Allow-Origin` header
|
||||
- 9 comprehensive integration tests in `backend/tests/cors_test.rs`
|
||||
- Covers: preflight requests, actual request headers, max-age, credentials, methods, wildcard, multiple origins, unauthorized origin rejection
|
||||
|
||||
## References
|
||||
|
||||
@@ -533,7 +521,10 @@ serde_yaml = "0.9.34"
|
||||
| 2026-01-03 | T009 | Test suite written (5 tests, TDD approach) |
|
||||
| 2026-01-03 | T010 | `CorsSettings` struct implemented with defaults |
|
||||
| 2026-01-03 | Documentation | This guide created |
|
||||
| 2026-01-22 | T013-T014 | `From<CorsSettings> for Cors` trait implemented |
|
||||
| 2026-01-22 | T015 | CORS middleware integrated into startup chain |
|
||||
| 2026-01-22 | T016 | 9 integration tests written and passing |
|
||||
|
||||
---
|
||||
|
||||
**Maintainer Notes**: This configuration follows the project's **Type-Driven Development (TyDD)** and **Test-Driven Development (TDD)** principles. Tests were written first (T009), then the implementation (T010) was created to pass those tests. The upcoming `build_cors()` function (T014) will complete the CORS feature by applying these settings to the Poem middleware chain.
|
||||
**Maintainer Notes**: This configuration follows the project's **Type-Driven Development (TyDD)** and **Test-Driven Development (TDD)** principles. Tests were written first (T009, T013), then implementations were created to pass those tests. The CORS feature is fully implemented and tested across all environments.
|
||||
|
||||
Reference in New Issue
Block a user