assay_auth/store/types.rs
1//! Plain-old-data records persisted by the auth stores.
2//!
3//! Field shapes are deliberately database-agnostic: timestamps are
4//! `f64` seconds since UNIX epoch (matches the engine's existing
5//! convention), opaque ids/credential bytes are owned `String`/`Vec<u8>`.
6
7use serde::{Deserialize, Serialize};
8
9/// Authoritative user record. The `id` is opaque — typically a
10/// `usr_<base64url>` string minted at signup time.
11#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
12pub struct User {
13 pub id: String,
14 pub email: Option<String>,
15 pub email_verified: bool,
16 pub display_name: Option<String>,
17 pub created_at: f64,
18}
19
20/// One stored WebAuthn credential. `transports` is a comma-separated
21/// list (CSV) per the `auth.passkeys.transports` column shape — the
22/// PG/SQLite stores serialise this on write.
23#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
24pub struct PasskeyCred {
25 pub credential_id: Vec<u8>,
26 pub public_key: Vec<u8>,
27 pub sign_count: u32,
28 pub transports: Vec<String>,
29 pub created_at: f64,
30}
31
32/// Opaque server-side session. `id` is the cookie value the client
33/// presents on every request; `csrf_token` is sent in a parallel
34/// non-HttpOnly cookie and must match a header/form field on
35/// state-changing requests (double-submit pattern).
36#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
37pub struct Session {
38 pub id: String,
39 pub user_id: String,
40 pub csrf_token: String,
41 pub created_at: f64,
42 pub expires_at: f64,
43 pub ip_hash: Option<String>,
44 pub user_agent_hash: Option<String>,
45}