diff --git a/.trellis/spec/backend/database-guidelines.md b/.trellis/spec/backend/database-guidelines.md index 7ac6738..c9e8fe1 100644 --- a/.trellis/spec/backend/database-guidelines.md +++ b/.trellis/spec/backend/database-guidelines.md @@ -630,6 +630,14 @@ reports/dashboard.jsp <- ReportServlet <- ReportService <- ReportDao <- books/re - `users.username`: unique login identifier submitted by `LoginServlet`. - `users.password_hash`: PBKDF2 hash in `pbkdf2_sha256$iterations$saltBase64$hashBase64` format. +- Local scaffold demo users must have documented, known initial passwords for + new deployments: `admin/admin123`, `librarian/librarian123`, and + `reader/reader123`. Their `schema.sql` hashes must verify through + `PasswordHasher.verify` and must be treated as local/demo-only credentials, + never production credentials. +- `schema.sql` uses `INSERT IGNORE` for demo `users` rows. Replaying the schema + must not be assumed to reset existing account passwords; README reset + guidance must call this out explicitly. - `users.role_code`: foreign key to `roles.code`; supported scaffold values are `administrator`, `librarian`, and `reader`. - `users.active`: only rows with `active = 1` can authenticate. diff --git a/.trellis/tasks/04-28-windows-login-diagnostic-logs/prd.md b/.trellis/tasks/04-28-windows-login-diagnostic-logs/prd.md index 9cb6f86..c56413a 100644 --- a/.trellis/tasks/04-28-windows-login-diagnostic-logs/prd.md +++ b/.trellis/tasks/04-28-windows-login-diagnostic-logs/prd.md @@ -27,6 +27,11 @@ Add safe server-side diagnostic logs to the login/authentication path so a Windo * Preserve the current user-facing Chinese error message and login behavior. * Keep the implementation in the existing Servlet + service + DAO + JDBC stack. * Prefer `java.util.logging` patterns already used in the project. +* Document and seed explicit local/demo initial credentials so new deployments are not blocked by unrecoverable password hashes: + * `admin` / `admin123` + * `librarian` / `librarian123` + * `reader` / `reader123` +* Make clear that these demo passwords are for local scaffold verification only and must be changed or removed before non-local/production use. ## Acceptance Criteria @@ -36,6 +41,9 @@ Add safe server-side diagnostic logs to the login/authentication path so a Windo * [x] No log statement outputs a raw password, password hash, salt, or database password. * [x] Existing login success/failure behavior remains unchanged for users. * [x] `mvn test` or the closest available Maven verification command succeeds. +* [x] README lists the local/demo initial login accounts and passwords with an explicit non-production warning. +* [x] `schema.sql` seed user hashes verify against the documented demo passwords for new deployments. +* [x] Existing deployments have a documented SQL reset path or warning explaining that `INSERT IGNORE` will not overwrite existing user rows. ## Definition Of Done @@ -68,3 +76,7 @@ Add safe server-side diagnostic logs to the login/authentication path so a Windo * `/home/sjy/.sdkman/candidates/maven/current/bin/mvn package` passed with `BUILD SUCCESS` and produced `target/library-management.war`. * `git diff --check` passed. * Sensitive logger scan only found boolean password state fields, `password=`, and `password-mismatch` category labels. +* Verification completed at 2026-04-28 18:33 +0800: + * `PasswordHasher.verify` returned `true` for `admin/admin123`, `librarian/librarian123`, and `reader/reader123` against the updated `schema.sql` PBKDF2 hashes. + * `/home/sjy/.sdkman/candidates/maven/current/bin/mvn verify` passed with `BUILD SUCCESS`. + * `git diff --check` passed. diff --git a/README.md b/README.md index 65691ed..5243eca 100644 --- a/README.md +++ b/README.md @@ -109,7 +109,36 @@ src/main/resources/db/schema.sql mysql -u root -p < src/main/resources/db/schema.sql ``` -脚本内包含本地验证用的演示角色、权限、用户、读者、分类和图书数据。演示账户只用于本地脚手架验证;在非本地数据库中使用前应更换或删除这些数据。本文档不提供任何登录明文密码。 +脚本内包含本地验证用的演示角色、权限、用户、读者、分类和图书数据。演示账户只用于本地脚手架验证;在非本地数据库中使用前应更换或删除这些数据。 + +本地/demo 初始登录账号如下。这些是应用登录账号,不是 MySQL 数据库账号: + +| 角色 | 用户名 | 初始密码 | +| --- | --- | --- | +| 管理员 | `admin` | `admin123` | +| 馆员 | `librarian` | `librarian123` | +| 读者 | `reader` | `reader123` | + +这些明文密码只用于新部署本地环境的首次验证。非本地或生产环境上线前,必须通过系统用户管理功能改密,或删除/替换这些演示账号。 + +`schema.sql` 使用 `INSERT IGNORE INTO users` 写入演示账号。如果目标数据库里已经存在同名 `admin`、`librarian` 或 `reader` 行,重新执行脚本不会覆盖现有密码哈希。需要重置本地演示账号时,优先在系统用户管理功能中修改密码;如果无法登录,可在确认这是本地/demo 数据库后执行以下 SQL: + +```sql +UPDATE users +SET password_hash = 'pbkdf2_sha256$60000$Ren1B30RDysysnApRiFVaQ==$1XwzMHaALqC7dKffwjbQkilBedfAuiMOXbR/xTMr5+Y=', + active = 1 +WHERE username = 'admin'; + +UPDATE users +SET password_hash = 'pbkdf2_sha256$60000$PV/DJwZlMRm8vy0lKMAM4g==$+Aijfop3YoPp6HTePN5r4wG8N3qgxJE+yZHkTfzfbaw=', + active = 1 +WHERE username = 'librarian'; + +UPDATE users +SET password_hash = 'pbkdf2_sha256$60000$wBzxTIT4ep79hgEzYDV9aQ==$w3oO5iSKRSfG4++b4558yiTHy6Tz9BB2+wuV9UOAKhs=', + active = 1 +WHERE username = 'reader'; +``` ## 本地配置 @@ -327,9 +356,9 @@ Maven 当前将 WAR 产物命名为 `library-management.war`。Tomcat 通常会 不可以。`src/main/resources/db.properties` 是本地私密配置,已经被 `.gitignore` 忽略。只应提交 `src/main/resources/db.properties.example`。 -### README 为什么不列出演示账号密码? +### 重新执行 `schema.sql` 后演示账号密码为什么没变? -数据库脚本包含本地验证用演示数据,但项目要求 README 不写入未经确认的默认登录明文密码,也不扩散任何凭据。需要本地调试时,请由维护者按当前数据库脚本和安全要求单独确认或重置账号。 +`schema.sql` 使用 `INSERT IGNORE INTO users` 写入本地/demo 账号。已有同名用户时,MySQL 会跳过插入,不会覆盖现有密码哈希。需要重置时,请参考“数据库初始化”里的本地/demo 账号说明;不要在非本地数据库中直接恢复这些演示密码。 ## 维护提示 diff --git a/src/main/resources/db/schema.sql b/src/main/resources/db/schema.sql index 5d9dc04..7f611f7 100644 --- a/src/main/resources/db/schema.sql +++ b/src/main/resources/db/schema.sql @@ -179,12 +179,13 @@ INSERT IGNORE INTO role_permissions (role_code, permission_code) VALUES ('reader', 'view_catalog'), ('reader', 'borrow_books'); --- Demo accounts for local scaffold verification only. Change or remove them --- before using a non-local database. +-- Demo accounts for local scaffold verification only: +-- admin/admin123, librarian/librarian123, reader/reader123. +-- Change or remove them before using a non-local database. INSERT IGNORE INTO users (username, password_hash, display_name, role_code, active) VALUES - ('admin', 'pbkdf2_sha256$60000$bXpoLWFkbWluLWRlbW8tc2FsdA==$RwBCvhf3Wsc0jemnHlir4mdNZF4ZhHjrfHx/b1Bera0=', 'System Administrator', 'administrator', 1), - ('librarian', 'pbkdf2_sha256$60000$bXpoLWxpYnJhcmlhbi1kZW1vLXNhbHQ=$StIdJGDRIiF4aCr+qKuwvob5sL3+6j1caF2sQNqFi78=', 'Library Staff', 'librarian', 1), - ('reader', 'pbkdf2_sha256$60000$bXpoLXJlYWRlci1kZW1vLXNhbHQ=$iaiZPGhaIQ+2R2o9UQRj6wsrmYSJ4efqS3jCzM/XU7g=', 'Demo Reader', 'reader', 1); + ('admin', 'pbkdf2_sha256$60000$Ren1B30RDysysnApRiFVaQ==$1XwzMHaALqC7dKffwjbQkilBedfAuiMOXbR/xTMr5+Y=', 'System Administrator', 'administrator', 1), + ('librarian', 'pbkdf2_sha256$60000$PV/DJwZlMRm8vy0lKMAM4g==$+Aijfop3YoPp6HTePN5r4wG8N3qgxJE+yZHkTfzfbaw=', 'Library Staff', 'librarian', 1), + ('reader', 'pbkdf2_sha256$60000$wBzxTIT4ep79hgEzYDV9aQ==$w3oO5iSKRSfG4++b4558yiTHy6Tz9BB2+wuV9UOAKhs=', 'Demo Reader', 'reader', 1); INSERT IGNORE INTO readers (reader_identifier, user_id, full_name, phone, email, status, max_borrow_count) VALUES ('RD-0001', (SELECT id FROM users WHERE username = 'reader'), 'Demo Reader', '13800000000',