diff --git a/hive-c0re/src/matrix.rs b/hive-c0re/src/matrix.rs index a2750e88..30a40165 100644 --- a/hive-c0re/src/matrix.rs +++ b/hive-c0re/src/matrix.rs @@ -378,6 +378,14 @@ fn extract_new_password(bot_message: &str) -> Option { "reset to:", "set to: ", "set to:", + // Generic "… to: " form. tuwunel's actual reset-password reply is + // "Successfully reset password for @user:server to: " — the + // password follows " to: " but no recognised verb sits adjacent to it, + // so the markers above miss it. Matrix user ids / server names can't + // contain " to: ", so this only ever anchors on the prose delimiter. + // Placed after the specific verb markers and before the bare + // "password:" last resort. + " to: ", // Bare "new password:" without "is": "new password: ", "new password:", @@ -459,6 +467,23 @@ mod extract_new_password_tests { assert_eq!(extract_new_password(msg).as_deref(), Some("hunter2")); } + #[test] + fn tuwunel_reset_password_for_to_variant() { + // The actual tuwunel admin-room reply observed in production — the + // verb ("reset") is not adjacent to "to:", so only the generic + // " to: " marker catches it. + let msg = "Successfully reset password for @atlas:pr1ma.darkest.space to: N3wP@ssw0rd"; + assert_eq!(extract_new_password(msg).as_deref(), Some("N3wP@ssw0rd")); + } + + #[test] + fn to_marker_not_confused_by_user_id() { + // The user id contains no " to: " so the marker only fires on the + // real delimiter; the password is the token right after it. + let msg = "Successfully reset password for @sock:pr1ma.darkest.space to: abc123XYZ"; + assert_eq!(extract_new_password(msg).as_deref(), Some("abc123XYZ")); + } + #[test] fn bare_new_password_colon() { let msg = "New password: P@ssword1";