mirror of
https://github.com/kanidm/kanidm.git
synced 2025-02-23 12:37:00 +01:00
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:
parent
1218abd8c6
commit
dfbcfa865f
|
@ -85,10 +85,10 @@ impl fmt::Debug for AuthCredential {
|
||||||
pub enum AuthMech {
|
pub enum AuthMech {
|
||||||
Anonymous,
|
Anonymous,
|
||||||
Password,
|
Password,
|
||||||
|
PasswordBackupCode,
|
||||||
// Now represents TOTP.
|
// Now represents TOTP.
|
||||||
#[serde(rename = "passwordmfa")]
|
#[serde(rename = "passwordmfa")]
|
||||||
PasswordTotp,
|
PasswordTotp,
|
||||||
PasswordBackupCode,
|
|
||||||
PasswordSecurityKey,
|
PasswordSecurityKey,
|
||||||
Passkey,
|
Passkey,
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,6 +37,8 @@ pub fn make_unsigned<'a>(
|
||||||
// then webauthn won't work anyway!
|
// then webauthn won't work anyway!
|
||||||
token_cookie.set_domain(state.domain.clone());
|
token_cookie.set_domain(state.domain.clone());
|
||||||
token_cookie.set_path(path);
|
token_cookie.set_path(path);
|
||||||
|
// These last forever.
|
||||||
|
token_cookie.make_permanent();
|
||||||
token_cookie
|
token_cookie
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -69,6 +71,8 @@ pub fn make_signed<'a, T: Serialize>(
|
||||||
token_cookie.set_http_only(true);
|
token_cookie.set_http_only(true);
|
||||||
token_cookie.set_path(path);
|
token_cookie.set_path(path);
|
||||||
token_cookie.set_domain(state.domain.clone());
|
token_cookie.set_domain(state.domain.clone());
|
||||||
|
// These last forever, we have our own internal expiration handling.
|
||||||
|
token_cookie.make_permanent();
|
||||||
Some(token_cookie)
|
Some(token_cookie)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -99,6 +99,7 @@ struct LoginView {
|
||||||
pub struct Mech<'a> {
|
pub struct Mech<'a> {
|
||||||
name: AuthMech,
|
name: AuthMech,
|
||||||
value: &'a str,
|
value: &'a str,
|
||||||
|
autofocus: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Template)]
|
#[derive(Template)]
|
||||||
|
@ -754,7 +755,7 @@ async fn view_login_step(
|
||||||
safety -= 1;
|
safety -= 1;
|
||||||
|
|
||||||
match auth_state {
|
match auth_state {
|
||||||
AuthState::Choose(allowed) => {
|
AuthState::Choose(mut allowed) => {
|
||||||
debug!("🧩 -> AuthState::Choose");
|
debug!("🧩 -> AuthState::Choose");
|
||||||
|
|
||||||
jar = add_session_cookie(&state, jar, &session_context)?;
|
jar = add_session_cookie(&state, jar, &session_context)?;
|
||||||
|
@ -793,13 +794,22 @@ async fn view_login_step(
|
||||||
|
|
||||||
// Render the list of options.
|
// Render the list of options.
|
||||||
_ => {
|
_ => {
|
||||||
let mechs = allowed
|
allowed.sort_unstable();
|
||||||
|
// Put strongest first.
|
||||||
|
allowed.reverse();
|
||||||
|
|
||||||
|
let mechs: Vec<_> = allowed
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|m| Mech {
|
.enumerate()
|
||||||
|
.map(|(i, m)| Mech {
|
||||||
value: m.to_value(),
|
value: m.to_value(),
|
||||||
name: m,
|
name: m,
|
||||||
|
// Auto focus the first item, it's the strongest
|
||||||
|
// mechanism and the one we should optimise for.
|
||||||
|
autofocus: i == 0,
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
LoginMechView { display_ctx, mechs }.into_response()
|
LoginMechView { display_ctx, mechs }.into_response()
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
<form id="login" action="/ui/login/mech_choose" method="post">
|
<form id="login" action="/ui/login/mech_choose" method="post">
|
||||||
<input type="hidden" id="mech" name="mech" value="(( mech.value ))" />
|
<input type="hidden" id="mech" name="mech" value="(( mech.value ))" />
|
||||||
<button
|
<button
|
||||||
|
(% if mech.autofocus %)autofocus(% endif %)
|
||||||
type="submit"
|
type="submit"
|
||||||
class="btn btn-dark"
|
class="btn btn-dark"
|
||||||
>(( mech.name ))</button>
|
>(( mech.name ))</button>
|
||||||
|
|
|
@ -16,16 +16,14 @@
|
||||||
(% if passkey %)
|
(% if passkey %)
|
||||||
<form id="cred-form" action="/ui/login/passkey" method="POST">
|
<form id="cred-form" action="/ui/login/passkey" method="POST">
|
||||||
<input hidden="hidden" name="cred" id="cred">
|
<input hidden="hidden" name="cred" id="cred">
|
||||||
|
<button hx-disable type="button" autofocus class="btn btn-dark"
|
||||||
<button hx-disable type="button" class="btn btn-dark"
|
|
||||||
id="start-passkey-button">Use Passkey</button>
|
id="start-passkey-button">Use Passkey</button>
|
||||||
</form>
|
</form>
|
||||||
(% else %)
|
(% else %)
|
||||||
<form id="cred-form" action="/ui/login/seckey" method="POST">
|
<form id="cred-form" action="/ui/login/seckey" method="POST">
|
||||||
<input hidden="hidden" name="cred" id="cred">
|
<input hidden="hidden" name="cred" id="cred">
|
||||||
|
<button hx-disable type="button" autofocus class="btn btn-dark"
|
||||||
<button type="button" class="btn btn-dark" id="start-seckey-button"
|
id="start-seckey-button">Use Security Key</button>
|
||||||
>Use Security Key</button>
|
|
||||||
</form>
|
</form>
|
||||||
(% endif %)
|
(% endif %)
|
||||||
</div>
|
</div>
|
||||||
|
|
Loading…
Reference in a new issue