add passkey support
This commit is contained in:
+50
-2
@@ -3,7 +3,7 @@ use pulldown_cmark::{Options, Parser, html as cmark_html};
|
||||
|
||||
use crate::{
|
||||
domain::PresenceUser,
|
||||
domain::{Category, GroceryList, Item, Meal, MealIngredient, User},
|
||||
domain::{Category, GroceryList, Item, Meal, MealIngredient, Passkey, User},
|
||||
};
|
||||
|
||||
pub fn login_page(error: Option<&str>, invite: Option<&str>) -> Markup {
|
||||
@@ -28,8 +28,11 @@ pub fn login_page(error: Option<&str>, invite: Option<&str>) -> Markup {
|
||||
input id="password" name="password" type="password" autocomplete="current-password" required;
|
||||
button class="button button-primary" type="submit" { "Sign in" }
|
||||
}
|
||||
div class="auth-divider" { span { "or" } }
|
||||
button id="passkey-login" class="button button-secondary" type="button" { "Sign in with a passkey" }
|
||||
p class="auth-switch" { "Need an account? " a href="/register" { "Create one" } }
|
||||
}
|
||||
script src="/static/passkey-login.js" {}
|
||||
},
|
||||
)
|
||||
}
|
||||
@@ -79,6 +82,51 @@ pub fn registration_closed_page() -> Markup {
|
||||
)
|
||||
}
|
||||
|
||||
pub fn account_page(user: &User, passkeys: &[Passkey], csrf_token: &str) -> Markup {
|
||||
page(
|
||||
"Account",
|
||||
Some(user),
|
||||
html! {
|
||||
div class="page-heading" {
|
||||
div {
|
||||
p class="eyebrow" { "ACCOUNT" }
|
||||
h1 { "Account" }
|
||||
p class="lede" { "Manage your sign-in methods." }
|
||||
}
|
||||
}
|
||||
div class="dashboard-grid" {
|
||||
section class="panel" {
|
||||
div class="panel-heading" {
|
||||
h2 { "Passkeys" }
|
||||
span class="count-badge" { (passkeys.len()) }
|
||||
}
|
||||
p { "Passkeys let you sign in without a password using your device." }
|
||||
@if passkeys.is_empty() {
|
||||
p class="muted" { "You have no passkeys yet." }
|
||||
} @else {
|
||||
div class="passkey-list" {
|
||||
@for passkey in passkeys {
|
||||
div class="passkey-row" {
|
||||
div class="item-copy" {
|
||||
strong { "Passkey" }
|
||||
small { (passkey.credential_id) }
|
||||
}
|
||||
form method="post" action=(format!("/account/passkeys/{}/delete", passkey.id)) {
|
||||
input type="hidden" name="csrf" value=(csrf_token);
|
||||
button class="danger-link" type="submit" { "Remove" }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
button id="add-passkey" class="button button-primary" type="button" data-csrf=(csrf_token) { "Add a passkey" }
|
||||
}
|
||||
}
|
||||
script src="/static/passkey-register.js" {}
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
pub fn lists_page(user: &User, lists: &[GroceryList], csrf_token: &str) -> Markup {
|
||||
page(
|
||||
"Your lists",
|
||||
@@ -907,7 +955,7 @@ fn page(title: &str, user: Option<&User>, content: Markup) -> Markup {
|
||||
a href="/meals" { "Meals" }
|
||||
}
|
||||
div class="account-nav" {
|
||||
span class="user-name" { (user.display_name) }
|
||||
a class="user-name" href="/account" { (user.display_name) }
|
||||
form method="post" action="/logout" {
|
||||
button class="text-button" type="submit" { "Sign out" }
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user