UI/Feature polish (#3191)

Post release some small user issues arose

* Optimise the autofocus for logins with passkeys to limit clicks
* Sort login mechs by strength
* Fix cookies to persist between browser restarts
This commit is contained in:
Firstyear 2024-11-10 14:02:27 +10:00 committed by William Brown
parent a6ecff0caa
commit a6dcb960d7
5 changed files with 22 additions and 9 deletions

View file

@ -85,10 +85,10 @@ impl fmt::Debug for AuthCredential {
pub enum AuthMech {
Anonymous,
Password,
PasswordBackupCode,
// Now represents TOTP.
#[serde(rename = "passwordmfa")]
PasswordTotp,
PasswordBackupCode,
PasswordSecurityKey,
Passkey,
}

View file

@ -37,6 +37,8 @@ pub fn make_unsigned<'a>(
// then webauthn won't work anyway!
token_cookie.set_domain(state.domain.clone());
token_cookie.set_path(path);
// These last forever.
token_cookie.make_permanent();
token_cookie
}
@ -69,6 +71,8 @@ pub fn make_signed<'a, T: Serialize>(
token_cookie.set_http_only(true);
token_cookie.set_path(path);
token_cookie.set_domain(state.domain.clone());
// These last forever, we have our own internal expiration handling.
token_cookie.make_permanent();
Some(token_cookie)
}

View file

@ -99,6 +99,7 @@ struct LoginView {
pub struct Mech<'a> {
name: AuthMech,
value: &'a str,
autofocus: bool,
}
#[derive(Template)]
@ -754,7 +755,7 @@ async fn view_login_step(
safety -= 1;
match auth_state {
AuthState::Choose(allowed) => {
AuthState::Choose(mut allowed) => {
debug!("🧩 -> AuthState::Choose");
jar = add_session_cookie(&state, jar, &session_context)?;
@ -793,13 +794,22 @@ async fn view_login_step(
// Render the list of options.
_ => {
let mechs = allowed
allowed.sort_unstable();
// Put strongest first.
allowed.reverse();
let mechs: Vec<_> = allowed
.into_iter()
.map(|m| Mech {
.enumerate()
.map(|(i, m)| Mech {
value: m.to_value(),
name: m,
// Auto focus the first item, it's the strongest
// mechanism and the one we should optimise for.
autofocus: i == 0,
})
.collect();
LoginMechView { display_ctx, mechs }.into_response()
}
};

View file

@ -11,6 +11,7 @@
<form id="login" action="/ui/login/mech_choose" method="post">
<input type="hidden" id="mech" name="mech" value="(( mech.value ))" />
<button
(% if mech.autofocus %)autofocus(% endif %)
type="submit"
class="btn btn-dark"
>(( mech.name ))</button>

View file

@ -16,16 +16,14 @@
(% if passkey %)
<form id="cred-form" action="/ui/login/passkey" method="POST">
<input hidden="hidden" name="cred" id="cred">
<button hx-disable type="button" class="btn btn-dark"
<button hx-disable type="button" autofocus class="btn btn-dark"
id="start-passkey-button">Use Passkey</button>
</form>
(% else %)
<form id="cred-form" action="/ui/login/seckey" method="POST">
<input hidden="hidden" name="cred" id="cred">
<button type="button" class="btn btn-dark" id="start-seckey-button"
>Use Security Key</button>
<button hx-disable type="button" autofocus class="btn btn-dark"
id="start-seckey-button">Use Security Key</button>
</form>
(% endif %)
</div>