diff --git a/app/static/css/app.css b/app/static/css/app.css index 4212fa6..d55d215 100644 --- a/app/static/css/app.css +++ b/app/static/css/app.css @@ -2350,3 +2350,16 @@ html.sidebar-open { .btn-favorite:active { transform: scale(0.88); } + +/* ── Passkey form info callout ──────────────────────────────────────────────── */ + +.passkey-info-callout { + background: #eff6ff; + border: 1px solid #bfdbfe; + border-radius: var(--radius); + color: #1d4ed8; + font-size: 12px; + line-height: 1.5; + padding: 10px 12px; + margin-bottom: 14px; +} diff --git a/app/static/js/vault.js b/app/static/js/vault.js index b3b4057..c3e51a0 100644 --- a/app/static/js/vault.js +++ b/app/static/js/vault.js @@ -81,6 +81,11 @@ const Vault = (() => { phone: "Phone", email: "Email", ssn_number: "Social Security Number", + // passkey + rp_id: "RP ID (Domain)", + credential_id: "Credential ID", + user_handle: "User Handle", + device_hint: "Device / Authenticator", }; const SENSITIVE_FIELDS = new Set([ "password", @@ -89,6 +94,8 @@ const Vault = (() => { "account_number", "routing_number", "ssn_number", + "credential_id", + "user_handle", ]); // ── API helpers ─────────────────────────────────────────────────────────── @@ -499,6 +506,14 @@ const Vault = (() => { case "ssn": subText = "•••-••-••••"; break; + case "passkey": + subText = [ + item.plain.username, + item.plain.rp_id ? `@ ${item.plain.rp_id}` : "", + ] + .filter(Boolean) + .join(" "); + break; } } @@ -2852,7 +2867,8 @@ const Vault = (() => { item.name.toLowerCase().includes(q) || (item.plain?.username || "").toLowerCase().includes(q) || (item.plain?.url || "").toLowerCase().includes(q) || - (item.plain?.note_body || "").toLowerCase().includes(q), + (item.plain?.note_body || "").toLowerCase().includes(q) || + (item.plain?.rp_id || "").toLowerCase().includes(q), ), ); } @@ -2871,6 +2887,7 @@ const Vault = (() => { bank: "🏦 Bank Account", address: "🏠 Address", ssn: "🪪 Identity (SSN)", + passkey: "🔐 Passkey", }; function switchModalType(type) { @@ -2977,6 +2994,15 @@ const Vault = (() => { setVal("field-ssn-number", p.ssn_number); setVal("field-notes", p.notes); break; + case "passkey": + setVal("field-pk-rp-id", p.rp_id); + setVal("field-pk-username", p.username); + setVal("field-pk-credential-id", p.credential_id); + setVal("field-pk-user-handle", p.user_handle); + setVal("field-pk-device-hint", p.device_hint); + setVal("field-pk-notes", p.notes); + setVal("field-tags", (p.tags || []).join(", ")); + break; } } } @@ -3057,6 +3083,16 @@ const Vault = (() => { ssn_number: getVal("field-ssn-number"), notes: getVal("field-notes").trim(), }; + case "passkey": + return { + rp_id: getVal("field-pk-rp-id").trim(), + username: getVal("field-pk-username").trim(), + credential_id: getVal("field-pk-credential-id").trim(), + user_handle: getVal("field-pk-user-handle").trim(), + device_hint: getVal("field-pk-device-hint").trim(), + notes: getVal("field-pk-notes").trim(), + tags: _parseTags(getVal("field-tags")), + }; default: return {}; } @@ -3337,6 +3373,7 @@ const Vault = (() => { bank: "🏦", address: "🏠", ssn: "🪪", + passkey: "🔐", }[type] || "🔑" ); } @@ -3557,6 +3594,7 @@ const Vault = (() => { bank: "Bank Accounts", address: "Addresses", ssn: "Identities", + passkey: "Passkeys", }; _activeFilter = { type: "itemType", value: type }; switchView("vault"); diff --git a/app/templates/vault/index.html b/app/templates/vault/index.html index 486b9e5..3e8f073 100644 --- a/app/templates/vault/index.html +++ b/app/templates/vault/index.html @@ -102,6 +102,14 @@ 🪪 Identities +