Share owned host API state between HTTP hooks and native pages

This commit is contained in:
2026-11-07 00:23:57 +00:00
parent 45d099c3e4
commit c91ecbf7a4
14 changed files with 261 additions and 133 deletions
+11 -7
View File
@@ -155,17 +155,18 @@ struct Pending<T> {
deadline: Instant,
value: T,
}
pub struct Passkeys<'a> {
db: &'a Connection,
/// Own the connection for a shared API, or borrow it for a local caller.
pub struct Passkeys<D: std::borrow::Borrow<Connection>> {
db: D,
webauthn: Webauthn,
registrations: HashMap<String, Pending<(String, bool, PasskeyRegistration)>>,
assertions: HashMap<String, Pending<(Binding, PasskeyAuthentication)>>,
}
impl<'a> Passkeys<'a> {
pub fn new(db: &'a Connection, rp_id: &str, origin: &str) -> Result<Self> {
impl<D: std::borrow::Borrow<Connection>> Passkeys<D> {
pub fn new(db: D, rp_id: &str, origin: &str) -> Result<Self> {
let origin = Url::parse(origin)?;
let webauthn = WebauthnBuilder::new(rp_id, &origin)?.build()?;
db.execute_batch("CREATE TABLE IF NOT EXISTS passkey_credentials(id TEXT PRIMARY KEY,label TEXT NOT NULL,credential TEXT NOT NULL)")?;
db.borrow().execute_batch("CREATE TABLE IF NOT EXISTS passkey_credentials(id TEXT PRIMARY KEY,label TEXT NOT NULL,credential TEXT NOT NULL)")?;
Ok(Self {
db,
webauthn,
@@ -176,6 +177,7 @@ impl<'a> Passkeys<'a> {
/// Database errors leave the manager locked.
pub fn is_unlocked(&self) -> bool {
self.db
.borrow()
.query_row(
"SELECT NOT EXISTS(SELECT 1 FROM passkey_credentials)",
[],
@@ -187,6 +189,7 @@ impl<'a> Passkeys<'a> {
pub fn list(&self) -> Result<Vec<serde_json::Value>> {
let mut statement = self
.db
.borrow()
.prepare("SELECT id,label FROM passkey_credentials ORDER BY rowid")?;
let rows = statement.query_map([], |row| {
Ok((row.get::<_, String>(0)?, row.get::<_, String>(1)?))
@@ -201,6 +204,7 @@ impl<'a> Passkeys<'a> {
fn credentials(&self) -> Result<Vec<Passkey>> {
let mut q = self
.db
.borrow()
.prepare("SELECT credential FROM passkey_credentials")?;
q.query_map([], |r| r.get::<_, String>(0))?
.map(|r| Ok(serde_json::from_str(&r?)?))
@@ -261,7 +265,7 @@ impl<'a> Passkeys<'a> {
let credential = self
.webauthn
.finish_passkey_registration(&response, state)?;
self.db.execute(
self.db.borrow().execute(
"INSERT INTO passkey_credentials(id,label,credential) VALUES(?1,?2,?3)",
params![
serde_json::to_string(credential.cred_id())?,
@@ -313,7 +317,7 @@ impl<'a> Passkeys<'a> {
bail!("passkey counter did not increase");
}
credential.update_credential(&result);
self.db.execute(
self.db.borrow().execute(
"UPDATE passkey_credentials SET credential=?1 WHERE id=?2",
params![
serde_json::to_string(credential)?,