Add WebAuthn support for admin login and kiosk mode
This commit is contained in:
@@ -105,6 +105,28 @@ function ensureSchema() {
|
||||
created_at TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP
|
||||
) STRICT;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS webauthn_credentials (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
user_id INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
||||
credential_id TEXT NOT NULL UNIQUE,
|
||||
public_key TEXT NOT NULL,
|
||||
counter INTEGER NOT NULL DEFAULT 0 CHECK (counter >= 0),
|
||||
transports TEXT,
|
||||
label TEXT,
|
||||
created_at TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
last_used_at TEXT
|
||||
) STRICT;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS webauthn_challenges (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
user_id INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
||||
challenge TEXT NOT NULL,
|
||||
purpose TEXT NOT NULL CHECK (purpose IN ('registration', 'authentication')),
|
||||
expires_at TEXT NOT NULL,
|
||||
used_at TEXT,
|
||||
created_at TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP
|
||||
) STRICT;
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_maintenance_motorcycle
|
||||
ON maintenance_events(motorcycle_id, event_date DESC, id DESC);
|
||||
CREATE INDEX IF NOT EXISTS idx_maintenance_due
|
||||
@@ -113,6 +135,10 @@ function ensureSchema() {
|
||||
ON trips(motorcycle_id, trip_date DESC, id DESC);
|
||||
CREATE INDEX IF NOT EXISTS idx_motorcycle_shares_user
|
||||
ON motorcycle_shares(user_id, motorcycle_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_webauthn_credentials_user
|
||||
ON webauthn_credentials(user_id);
|
||||
CREATE INDEX IF NOT EXISTS idx_webauthn_challenges_lookup
|
||||
ON webauthn_challenges(user_id, purpose, expires_at, used_at);
|
||||
`);
|
||||
|
||||
const userColumns = db.prepare("PRAGMA table_info(users)").all() as { name: string }[];
|
||||
@@ -196,6 +222,8 @@ function ensureSchema() {
|
||||
}
|
||||
|
||||
db.exec("CREATE INDEX IF NOT EXISTS idx_users_active ON users(active, name COLLATE NOCASE)");
|
||||
db.prepare("DELETE FROM webauthn_challenges WHERE used_at IS NOT NULL OR expires_at < ?")
|
||||
.run(new Date().toISOString());
|
||||
}
|
||||
|
||||
function ensureInitialAdmin() {
|
||||
|
||||
Reference in New Issue
Block a user