Furnic/usernames#13
Conversation
…ion to change-password - Check account lockout before verifying current password - Record failed attempts on wrong current password - Reset failure count on success - Require minimum 8-character password (server + frontend)
freesig
left a comment
There was a problem hiding this comment.
Passwords sent in plaintext over WebSocket
ClientMessage::ChangePassword sends current_password and new_password as plaintext strings over the wire. These should ideally be hashed client-side before transmission so that raw passwords never travel over the WebSocket connection — even with TLS, defense-in-depth matters (logging, memory dumps, intermediary proxies, etc.).
|
When changing the user name it looks like it's just changed locally and not on the sync server? |
| } | ||
| ServerMessage::PasswordChanged => { | ||
| // Acknowledgment only — the subsequent AuthToken resolves the pending auth oneshot | ||
| None |
There was a problem hiding this comment.
If the sync server crashes or the connection drops between sending PasswordChanged and the subsequent AuthToken, the auth oneshot in change_password() will hang indefinitely (or until the WebSocket close is detected and tears things down).
Since PasswordChanged is purely informational and nothing reads it, consider either:
- Removing the
PasswordChangedmessage entirely and just relying on theAuthTokenresponse to signal success, or - Having
PasswordChangeditself resolve the pending auth oneshot (and treatAuthTokenas a bonus refresh), so the client isn't dependent on two messages arriving in sequence.
| pub db_path: String, | ||
| pub sync_url: Option<String>, | ||
| pub log_prompts: Option<String>, | ||
| pub user_name: Option<String>, |
There was a problem hiding this comment.
This field is always set to None in both main.rs files — there's no CLI flag wired up to populate it, so the priority logic added below (config.user_name > DB setting) is dead code from the user's perspective.
I'd suggest removing user_name from ServerConfig entirely for now rather than shipping an unused field. The DB-based persistence already works, and the username is editable via the new Account panel. If we need a CLI override later we can add it then with the actual --user-name flag.
|
Might be worth adding an integration test for this workflow |
Summary
Adds an Account panel to the web UI so users can view and edit their username and sync password at any time — not just on first launch.
Note: The remote sync server must be redeployed with the updated spec-forest-sync crate for this to work. The ChangePassword wire message is new and will be
rejected by older server builds.
What changed
ChangePassword and PasswordChanged wire messages added to the protocol. The sync server handles password changes with verification, argon2 hashing, account lockout on repeated failures, and fresh token issuance. The client-side SyncHandle gets a change_password() method with PasswordChanged handling in the receive loop. A new POST /api/sync/change-password REST endpoint bridges the frontend to the sync protocol. On the frontend, a new AccountPanel component provides username editing, sync status display, and password management, wired into the gallery header via App.tsx and SpecGallery.tsx.
Closes #6