05/09 Update: add passkey
This commit is contained in:
@@ -2350,3 +2350,16 @@ html.sidebar-open {
|
|||||||
.btn-favorite:active {
|
.btn-favorite:active {
|
||||||
transform: scale(0.88);
|
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;
|
||||||
|
}
|
||||||
|
|||||||
+39
-1
@@ -81,6 +81,11 @@ const Vault = (() => {
|
|||||||
phone: "Phone",
|
phone: "Phone",
|
||||||
email: "Email",
|
email: "Email",
|
||||||
ssn_number: "Social Security Number",
|
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([
|
const SENSITIVE_FIELDS = new Set([
|
||||||
"password",
|
"password",
|
||||||
@@ -89,6 +94,8 @@ const Vault = (() => {
|
|||||||
"account_number",
|
"account_number",
|
||||||
"routing_number",
|
"routing_number",
|
||||||
"ssn_number",
|
"ssn_number",
|
||||||
|
"credential_id",
|
||||||
|
"user_handle",
|
||||||
]);
|
]);
|
||||||
|
|
||||||
// ── API helpers ───────────────────────────────────────────────────────────
|
// ── API helpers ───────────────────────────────────────────────────────────
|
||||||
@@ -499,6 +506,14 @@ const Vault = (() => {
|
|||||||
case "ssn":
|
case "ssn":
|
||||||
subText = "•••-••-••••";
|
subText = "•••-••-••••";
|
||||||
break;
|
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.name.toLowerCase().includes(q) ||
|
||||||
(item.plain?.username || "").toLowerCase().includes(q) ||
|
(item.plain?.username || "").toLowerCase().includes(q) ||
|
||||||
(item.plain?.url || "").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",
|
bank: "🏦 Bank Account",
|
||||||
address: "🏠 Address",
|
address: "🏠 Address",
|
||||||
ssn: "🪪 Identity (SSN)",
|
ssn: "🪪 Identity (SSN)",
|
||||||
|
passkey: "🔐 Passkey",
|
||||||
};
|
};
|
||||||
|
|
||||||
function switchModalType(type) {
|
function switchModalType(type) {
|
||||||
@@ -2977,6 +2994,15 @@ const Vault = (() => {
|
|||||||
setVal("field-ssn-number", p.ssn_number);
|
setVal("field-ssn-number", p.ssn_number);
|
||||||
setVal("field-notes", p.notes);
|
setVal("field-notes", p.notes);
|
||||||
break;
|
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"),
|
ssn_number: getVal("field-ssn-number"),
|
||||||
notes: getVal("field-notes").trim(),
|
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:
|
default:
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
@@ -3337,6 +3373,7 @@ const Vault = (() => {
|
|||||||
bank: "🏦",
|
bank: "🏦",
|
||||||
address: "🏠",
|
address: "🏠",
|
||||||
ssn: "🪪",
|
ssn: "🪪",
|
||||||
|
passkey: "🔐",
|
||||||
}[type] || "🔑"
|
}[type] || "🔑"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -3557,6 +3594,7 @@ const Vault = (() => {
|
|||||||
bank: "Bank Accounts",
|
bank: "Bank Accounts",
|
||||||
address: "Addresses",
|
address: "Addresses",
|
||||||
ssn: "Identities",
|
ssn: "Identities",
|
||||||
|
passkey: "Passkeys",
|
||||||
};
|
};
|
||||||
_activeFilter = { type: "itemType", value: type };
|
_activeFilter = { type: "itemType", value: type };
|
||||||
switchView("vault");
|
switchView("vault");
|
||||||
|
|||||||
@@ -102,6 +102,14 @@
|
|||||||
<span class="sidebar-icon">🪪</span>
|
<span class="sidebar-icon">🪪</span>
|
||||||
<span class="sidebar-label">Identities</span>
|
<span class="sidebar-label">Identities</span>
|
||||||
</li>
|
</li>
|
||||||
|
<li
|
||||||
|
class="sidebar-item"
|
||||||
|
data-type-filter="passkey"
|
||||||
|
data-tooltip="Passkeys"
|
||||||
|
>
|
||||||
|
<span class="sidebar-icon">🔐</span>
|
||||||
|
<span class="sidebar-label">Passkeys</span>
|
||||||
|
</li>
|
||||||
<li class="sidebar-section-header">Tools</li>
|
<li class="sidebar-section-header">Tools</li>
|
||||||
<li
|
<li
|
||||||
class="sidebar-item"
|
class="sidebar-item"
|
||||||
@@ -446,6 +454,7 @@
|
|||||||
<option value="bank">🏦 Bank Account</option>
|
<option value="bank">🏦 Bank Account</option>
|
||||||
<option value="address">🏠 Address</option>
|
<option value="address">🏠 Address</option>
|
||||||
<option value="ssn">🪪 Identity (SSN)</option>
|
<option value="ssn">🪪 Identity (SSN)</option>
|
||||||
|
<option value="passkey">🔐 Passkey</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
@@ -758,6 +767,78 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="type-fields hidden" data-for-types="passkey">
|
||||||
|
<div class="passkey-info-callout">
|
||||||
|
🔐 Store the details of a passkey registered on a website. The actual
|
||||||
|
private key stays on your device/authenticator.
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="field-pk-rp-id"
|
||||||
|
>RP ID (Domain) <span class="required">*</span></label
|
||||||
|
>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
id="field-pk-rp-id"
|
||||||
|
placeholder="e.g. github.com"
|
||||||
|
autocomplete="off"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="field-pk-username">Username / Display Name</label>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
id="field-pk-username"
|
||||||
|
placeholder="e.g. alice@example.com"
|
||||||
|
autocomplete="off"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="field-pk-credential-id"
|
||||||
|
>Credential ID
|
||||||
|
<span class="field-label-optional">optional</span></label
|
||||||
|
>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
id="field-pk-credential-id"
|
||||||
|
class="input-monospace"
|
||||||
|
placeholder="Base64url credential ID"
|
||||||
|
autocomplete="off"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="field-pk-user-handle"
|
||||||
|
>User Handle
|
||||||
|
<span class="field-label-optional">optional</span></label
|
||||||
|
>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
id="field-pk-user-handle"
|
||||||
|
class="input-monospace"
|
||||||
|
placeholder="Base64url user handle"
|
||||||
|
autocomplete="off"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="field-pk-device-hint"
|
||||||
|
>Device / Authenticator
|
||||||
|
<span class="field-label-optional">optional</span></label
|
||||||
|
>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
id="field-pk-device-hint"
|
||||||
|
placeholder="e.g. Touch ID on MacBook Pro"
|
||||||
|
autocomplete="off"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="field-pk-notes">Notes</label>
|
||||||
|
<textarea
|
||||||
|
id="field-pk-notes"
|
||||||
|
rows="3"
|
||||||
|
placeholder="Optional notes…"
|
||||||
|
></textarea>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="field-folder">Folder</label>
|
<label for="field-folder">Folder</label>
|
||||||
<select id="field-folder">
|
<select id="field-folder">
|
||||||
@@ -766,7 +847,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="type-fields"
|
class="type-fields"
|
||||||
data-for-types="password note card bank address ssn"
|
data-for-types="password note card bank address ssn passkey"
|
||||||
>
|
>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="field-tags">Tags</label>
|
<label for="field-tags">Tags</label>
|
||||||
|
|||||||
Reference in New Issue
Block a user