Files
PROJECT-CONTORL/openspec/specs/user-auth/spec.md
beabigegg 3bdc6ff1c9 feat: implement 8 OpenSpec proposals for security, reliability, and UX improvements
## Security Enhancements (P0)
- Add input validation with max_length and numeric range constraints
- Implement WebSocket token authentication via first message
- Add path traversal prevention in file storage service

## Permission Enhancements (P0)
- Add project member management for cross-department access
- Implement is_department_manager flag for workload visibility

## Cycle Detection (P0)
- Add DFS-based cycle detection for task dependencies
- Add formula field circular reference detection
- Display user-friendly cycle path visualization

## Concurrency & Reliability (P1)
- Implement optimistic locking with version field (409 Conflict on mismatch)
- Add trigger retry mechanism with exponential backoff (1s, 2s, 4s)
- Implement cascade restore for soft-deleted tasks

## Rate Limiting (P1)
- Add tiered rate limits: standard (60/min), sensitive (20/min), heavy (5/min)
- Apply rate limits to tasks, reports, attachments, and comments

## Frontend Improvements (P1)
- Add responsive sidebar with hamburger menu for mobile
- Improve touch-friendly UI with proper tap target sizes
- Complete i18n translations for all components

## Backend Reliability (P2)
- Configure database connection pool (size=10, overflow=20)
- Add Redis fallback mechanism with message queue
- Add blocker check before task deletion

## API Enhancements (P3)
- Add standardized response wrapper utility
- Add /health/ready and /health/live endpoints
- Implement project templates with status/field copying

## Tests Added
- test_input_validation.py - Schema and path traversal tests
- test_concurrency_reliability.py - Optimistic locking and retry tests
- test_backend_reliability.py - Connection pool and Redis tests
- test_api_enhancements.py - Health check and template tests

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-10 22:13:43 +08:00

9.1 KiB
Raw Blame History

User Authentication & Authorization

Purpose

使用者認證與授權系統,透過外部認證 API 進行身份驗證,提供細部權限控制。

Requirements

Requirement: API-Based Authentication

系統 SHALL 限定使用外部認證 API (https://pj-auth-api.vercel.app) 進行登入認證,不支援其他認證方式。

Scenario: API 登入成功

  • GIVEN 使用者擁有有效的企業帳號
  • WHEN 使用者透過前端提交憑證
  • THEN 系統呼叫 https://pj-auth-api.vercel.app 驗證憑證
  • AND 驗證成功後建立 session 並回傳 JWT token

Scenario: API 登入失敗

  • GIVEN 使用者提供無效的憑證
  • WHEN 使用者嘗試登入
  • THEN 認證 API 回傳錯誤
  • AND 系統拒絕登入並顯示錯誤訊息
  • AND 記錄失敗的登入嘗試

Scenario: 認證 API 無法連線

  • GIVEN 認證 API 服務無法連線
  • WHEN 使用者嘗試登入
  • THEN 系統顯示服務暫時無法使用的訊息
  • AND 記錄連線失敗事件

Requirement: System Administrator

系統 SHALL 預設一個系統管理員帳號,擁有所有權限。系統管理員帳號必須存在於外部認證系統,且登入流程仍需透過外部認證 API不允許本地繞過認證。

Scenario: 預設管理員帳號

  • GIVEN 系統初始化完成
  • WHEN 系統啟動
  • THEN 存在預設管理員帳號 ymirliu@panjit.com.tw
  • AND 該帳號擁有 super_admin 角色
  • AND 該帳號不可被刪除或降級

Scenario: 管理員登入流程

  • GIVEN 管理員帳號 ymirliu@panjit.com.tw 需要登入
  • WHEN 管理員提交憑證
  • THEN 系統仍需呼叫 https://pj-auth-api.vercel.app 驗證
  • AND 不存在任何本地繞過認證的機制
  • AND 驗證成功後才授予 super_admin 權限

Scenario: 管理員全域權限

  • GIVEN 管理員帳號 ymirliu@panjit.com.tw 已通過 API 認證並登入
  • WHEN 管理員存取任何資源
  • THEN 系統允許存取,無視部門隔離限制

Requirement: Role-Based Access Control

系統 SHALL 支援基於角色的存取控制 (RBAC)。

Scenario: 角色權限檢查

  • GIVEN 使用者被指派特定角色 (如工程師、主管、PMO)
  • WHEN 使用者嘗試存取受保護的資源
  • THEN 系統根據角色權限決定是否允許存取

Scenario: 角色指派

  • GIVEN 管理員擁有使用者管理權限
  • WHEN 管理員為使用者指派角色
  • THEN 系統更新使用者的角色設定
  • AND 新權限立即生效

Requirement: Department Isolation

系統 SHALL 實施部門級別的資料隔離,確保跨部門資料安全。

Scenario: 部門資料隔離

  • GIVEN 使用者屬於研發部門
  • WHEN 使用者嘗試存取廠務部門的專案
  • THEN 系統拒絕存取並顯示無權限訊息

Scenario: 跨部門專案存取

  • GIVEN 專案被設定為跨部門可見
  • WHEN 不同部門的使用者嘗試存取該專案
  • THEN 系統根據專案的 Security_Level 設定決定是否允許存取

Requirement: Session Management

系統 SHALL 管理使用者 session包含過期與登出機制。

Scenario: Session 過期

  • GIVEN 使用者已登入系統
  • WHEN Session 超過設定的有效期限
  • THEN 系統自動使 session 失效
  • AND 使用者需重新登入

Scenario: 主動登出

  • GIVEN 使用者已登入系統
  • WHEN 使用者執行登出操作
  • THEN 系統銷毀 session 並清除 token

Requirement: API Rate Limiting

The system SHALL implement rate limiting to protect against brute force attacks and DoS attempts.

Scenario: Login rate limit enforcement

  • GIVEN a client IP has made 5 login attempts within 1 minute
  • WHEN the client attempts another login
  • THEN the system returns HTTP 429 Too Many Requests
  • AND the response includes a Retry-After header

Scenario: Rate limit window reset

  • GIVEN a client has exceeded the rate limit
  • WHEN the rate limit window expires (1 minute)
  • THEN the client can make new requests

Scenario: Rate limit per IP

  • GIVEN rate limiting is IP-based
  • WHEN different IPs make requests
  • THEN each IP has its own rate limit counter

Requirement: Comprehensive API Rate Limiting

The system SHALL enforce rate limits on all sensitive API endpoints to prevent abuse and ensure service availability.

Scenario: Task creation rate limit exceeded

  • WHEN user exceeds 60 task creation requests per minute
  • THEN system returns 429 Too Many Requests
  • THEN response includes Retry-After header

Scenario: Report generation rate limit exceeded

  • WHEN user exceeds 5 report generation requests per minute
  • THEN system returns 429 Too Many Requests
  • THEN response includes rate limit headers

Scenario: Rate limit headers provided

  • WHEN user makes any rate-limited API request
  • THEN response includes X-RateLimit-Limit header
  • THEN response includes X-RateLimit-Remaining header
  • THEN response includes X-RateLimit-Reset header

Scenario: Rate limit window reset

  • WHEN rate limit window expires
  • THEN user can make requests again up to the limit
  • THEN X-RateLimit-Remaining resets to maximum

Requirement: Input Length Validation

The system SHALL enforce maximum length limits on all user-provided string inputs to prevent DoS attacks and database overflow.

Scenario: Task title exceeds maximum length

  • WHEN user submits a task with title longer than 500 characters
  • THEN system returns 422 Validation Error with descriptive message

Scenario: Description field within limits

  • WHEN user submits content with description under 10000 characters
  • THEN system accepts the input and processes normally

Requirement: Secure WebSocket Authentication

The system SHALL authenticate WebSocket connections without exposing tokens in URL query parameters.

Scenario: WebSocket connection with token in first message

  • WHEN client connects to WebSocket endpoint
  • THEN server waits for authentication message containing JWT token
  • THEN server validates token before accepting further messages

Scenario: WebSocket connection timeout without authentication

  • WHEN client connects but does not send authentication within 10 seconds
  • THEN server closes the connection with appropriate error code

Requirement: Path Traversal Protection

The system SHALL prevent file path traversal attacks by validating all file paths resolve within the designated storage directory.

Scenario: Path traversal attempt detected

  • WHEN request contains file path with "../" or absolute path outside storage
  • THEN system rejects request and logs security warning
  • THEN system returns 403 Forbidden error

Scenario: Valid file path within storage

  • WHEN request contains valid relative file path
  • THEN system resolves path and verifies it is within storage directory
  • THEN system processes file operation normally

Data Model

pjctrl_users
├── id: UUID (PK)
├── email: VARCHAR(200) UNIQUE
├── name: VARCHAR(200)
├── department_id: UUID (FK)
├── role_id: UUID (FK)
├── skills: JSON
├── capacity: DECIMAL (週工時上限)
├── is_active: BOOLEAN
├── is_system_admin: BOOLEAN DEFAULT false (不可修改的系統管理員標記)
├── created_at: TIMESTAMP
└── updated_at: TIMESTAMP

pjctrl_departments
├── id: UUID (PK)
├── name: VARCHAR(100)
├── parent_id: UUID (FK, self-reference)
└── created_at: TIMESTAMP

pjctrl_roles
├── id: UUID (PK)
├── name: VARCHAR(50)
├── permissions: JSON
├── is_system_role: BOOLEAN DEFAULT false
└── created_at: TIMESTAMP

Default Data (Seed)

-- 預設系統管理員角色
INSERT INTO pjctrl_roles (id, name, permissions, is_system_role) VALUES
('00000000-0000-0000-0000-000000000001', 'super_admin', '{"all": true}', true);

-- 預設系統管理員帳號
INSERT INTO pjctrl_users (id, email, name, role_id, is_active, is_system_admin) VALUES
('00000000-0000-0000-0000-000000000001', 'ymirliu@panjit.com.tw', 'System Administrator',
 '00000000-0000-0000-0000-000000000001', true, true);

External Dependencies

Authentication Flow

┌─────────┐     ┌─────────────┐     ┌──────────────────────────┐
│  User   │────▶│  Frontend   │────▶│  pj-auth-api.vercel.app  │
└─────────┘     └─────────────┘     └──────────────────────────┘
                      │                         │
                      │◀────── JWT Token ───────│
                      │
                      ▼
               ┌─────────────┐
               │   Backend   │ (驗證 JWT, 建立 Session)
               └─────────────┘