feat: 添加密码管理功能,包括 API、数据库支持和前端界面

This commit is contained in:
2026-01-23 23:55:08 +08:00
parent 1a3bbac9ff
commit a8c96d84f0
43 changed files with 1957 additions and 110 deletions

View File

@@ -0,0 +1,33 @@
## Context
We need a password manager across extension and web, with admin visibility and per-user isolation. Non-admin users must re-verify their login password to view plaintext.
## Goals / Non-Goals
- Goals:
- Save credentials with explicit confirmation.
- Autofill selector for saved accounts per site.
- Admin can view all users credentials.
- Non-admin must re-verify password before plaintext reveal.
- Encrypt credentials at rest.
- Non-Goals:
- Browser-level credential integration outside the extension.
- Password sharing between users.
## Decisions
- Site key = URL origin (scheme + host + port).
- Storage model: one row per (user_id, site_origin, username), allowing multiple accounts per site.
- Encrypt password using AES-256-GCM with server-side master key (env), store iv + tag + ciphertext.
- Use a session-only toggle to reveal plaintext in the web UI (sessionStorage; reset on browser close).
- Extension content script detects login forms; popup asks to save; only on confirm does it call API.
## Risks / Trade-offs
- Storing decryptable passwords increases risk. Mitigation: encryption at rest, strict auth, session-only plaintext reveal, audit logging (future).
## Migration Plan
- Add DB migration for credential tables and indexes.
- Add API endpoints and update OpenAPI.
- Implement extension flows and web UI.
- Add tests for CRUD, reauth, admin access.
## Open Questions
- Confirm site matching scope (origin vs eTLD+1).
- Save prompt triggers on form submit (username + password present).

View File

@@ -0,0 +1,20 @@
# Change: Add password manager (Web + Extension)
## Why
Provide built-in credential saving and autofill for users, with centralized management and admin oversight.
## What Changes
- Add credential save + autofill flows in the extension (explicit user confirmation required).
- Add a Web password management page (desktop only) with view/edit/delete.
- Add APIs for credential CRUD and admin access; plaintext view available during the current browser session.
- Add database schema for credential storage (per-user, per-site, multiple accounts).
- Add tests for API and DB flows.
## Impact
- Affected specs: api, password-manager
- Affected code: apps/server, apps/web, apps/extension, migrations, spec/openapi.yaml
## Assumptions (confirm)
- “同一网站” is defined as the URL origin (scheme + host + port).
- The extension prompts on form submit after username + password are provided.
- Credentials are stored encrypted at rest and decrypted server-side for plaintext display.

View File

@@ -0,0 +1,41 @@
## ADDED Requirements
### Requirement: Credential storage API
The system SHALL provide authenticated CRUD APIs for credentials scoped to the current user.
#### Scenario: Create credential
- **WHEN** an authenticated user calls `POST /credentials` with `siteOrigin`, `username`, and `password`
- **THEN** the server stores the credential and returns the created record
#### Scenario: List credentials
- **WHEN** an authenticated user calls `GET /credentials?siteOrigin=...`
- **THEN** the server returns the matching credentials for that user
#### Scenario: Update credential
- **WHEN** an authenticated user calls `PATCH /credentials/{id}`
- **THEN** the server updates the credential and returns the updated record
#### Scenario: Delete credential
- **WHEN** an authenticated user calls `DELETE /credentials/{id}`
- **THEN** the server deletes the credential
### Requirement: Credential plaintext reveal
The system SHALL allow authenticated users to request plaintext passwords for their own credentials.
#### Scenario: User requests plaintext
- **GIVEN** an authenticated user
- **WHEN** the user requests plaintext credential data
- **THEN** the server returns plaintext passwords for that user
#### Scenario: Admin requests plaintext
- **GIVEN** an authenticated admin user
- **WHEN** the admin requests plaintext credential data
- **THEN** the server returns plaintext passwords for the target user
### Requirement: Admin credential access
The system SHALL allow an admin to list and manage any users credentials.
#### Scenario: Admin lists user credentials
- **GIVEN** an authenticated admin user
- **WHEN** the admin calls `GET /admin/users/{id}/credentials`
- **THEN** the server returns that users credentials

View File

@@ -0,0 +1,44 @@
## ADDED Requirements
### Requirement: Extension save prompt
The extension SHALL prompt the user to save credentials when a login form is detected and filled.
#### Scenario: Save confirmed
- **WHEN** the user confirms “保存/记住密码” in the prompt
- **THEN** the extension sends the credential to the server for storage
#### Scenario: Save canceled
- **WHEN** the user cancels or dismisses the prompt
- **THEN** the extension MUST NOT store the credential
### Requirement: Extension autofill selector
The extension SHALL show a credential selector near login fields for sites with saved accounts.
#### Scenario: Select credential
- **GIVEN** a site with multiple saved credentials
- **WHEN** the user opens the selector and chooses one
- **THEN** the username and password fields are filled with that credential
### Requirement: Web password manager (desktop only)
The web app SHALL provide a desktop-only password manager view.
#### Scenario: Desktop view
- **WHEN** the user visits the password manager page on desktop
- **THEN** the page is visible and provides list/edit/delete
#### Scenario: Mobile view hidden
- **WHEN** the user visits the password manager page on mobile
- **THEN** the page is hidden or redirects to a notice page
### Requirement: Plaintext visibility control
The system SHALL allow a user to reveal plaintext passwords for their own credentials during the current browser session.
#### Scenario: User reveals plaintext
- **GIVEN** a non-admin user
- **WHEN** the user chooses to reveal plaintext
- **THEN** the UI shows plaintext passwords during the current browser session
#### Scenario: Admin view
- **GIVEN** an admin user
- **WHEN** the admin views credentials
- **THEN** plaintext is visible

View File

@@ -0,0 +1,31 @@
## 1. Spec
- [x] 1.1 Update OpenSpec deltas for api/password-manager
- [x] 1.2 Update OpenAPI 3.1 contract (spec/openapi.yaml)
## 2. Database
- [x] 2.1 Add migrations for credential storage tables + indexes
## 3. Server
- [x] 3.1 Implement credential CRUD APIs
- [x] 3.2 Enable plaintext credential access
- [x] 3.3 Implement admin credential access APIs
## 4. Extension
- [x] 4.1 Add content script for detecting login forms
- [x] 4.2 Add save-credential prompt + confirm flow
- [x] 4.3 Add autofill selector UI on login fields
## 5. Web
- [x] 5.1 Add desktop-only password manager page
- [x] 5.2 Add session-based plaintext toggle
- [x] 5.3 Add admin view for all users
## 6. Tests
- [x] 6.1 API tests for CRUD + plaintext + admin access
- [x] 6.2 DB migration verification
## 7. Verification
- [x] 7.1 Specs updated in openspec/specs
- [x] 7.2 OpenAPI updated and validated
- [x] 7.3 DB migration applied
- [x] 7.4 Server tests executed