05/18 Enhanced codes and functionalities 11
This commit is contained in:
+19
-1
@@ -2549,4 +2549,22 @@ html.sidebar-open {
|
||||
|
||||
.health-banner-dismiss:hover {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Passkey attachment type selector */
|
||||
.passkey-attachment-select {
|
||||
padding: 7px 10px;
|
||||
border: 1px solid var(--border);
|
||||
border-radius: var(--radius);
|
||||
font-size: 13px;
|
||||
color: var(--text);
|
||||
background: var(--surface);
|
||||
cursor: pointer;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.passkey-attachment-select:focus {
|
||||
outline: none;
|
||||
border-color: var(--primary);
|
||||
box-shadow: 0 0 0 3px rgba(192, 57, 43, 0.15);
|
||||
}
|
||||
|
||||
@@ -523,9 +523,10 @@ const PasskeyAuth = (() => {
|
||||
/**
|
||||
* Register a new passkey for the currently logged-in user.
|
||||
* Requires an active access_token in sessionStorage (set by vault.js on login).
|
||||
* @param {string} name User-friendly name for the passkey (e.g. "iPhone 15").
|
||||
* @param {string} name User-friendly name (e.g. "iPhone 15").
|
||||
* @param {string} attachment "platform" (default) | "cross-platform"
|
||||
*/
|
||||
async function registerPasskey(name) {
|
||||
async function registerPasskey(name, attachment = "platform") {
|
||||
if (!window.PublicKeyCredential) {
|
||||
return { error: 'Passkeys are not supported in this browser.' };
|
||||
}
|
||||
@@ -540,6 +541,7 @@ const PasskeyAuth = (() => {
|
||||
'Content-Type': 'application/json',
|
||||
Authorization: `Bearer ${token}`,
|
||||
},
|
||||
body: JSON.stringify({ attachment }),
|
||||
});
|
||||
if (!beginRes.ok) {
|
||||
const d = await beginRes.json().catch(() => ({}));
|
||||
|
||||
+11
-3
@@ -2442,10 +2442,16 @@ const Vault = (() => {
|
||||
const lastUsed = c.last_used_at
|
||||
? `Last used ${new Date(c.last_used_at).toLocaleDateString()}`
|
||||
: "Never used";
|
||||
const transports = c.transports || [];
|
||||
const typeLabel = transports.includes("internal")
|
||||
? "📱 Device"
|
||||
: transports.some((t) => ["usb", "nfc", "ble", "smart-card"].includes(t))
|
||||
? "🔑 Security key"
|
||||
: "🔑 Passkey";
|
||||
return `<div class="passkey-item" data-cred-id="${c.id}">
|
||||
<div class="passkey-info">
|
||||
<span class="passkey-name">${escHtml(c.name)}</span>
|
||||
<span class="passkey-meta">${lastUsed} · Added ${escHtml(created)}</span>
|
||||
<span class="passkey-meta">${typeLabel} · ${lastUsed} · Added ${escHtml(created)}</span>
|
||||
</div>
|
||||
<div class="passkey-actions">
|
||||
<button class="btn-text btn-sm btn-rename-passkey" data-id="${c.id}" data-name="${escHtml(c.name)}">Rename</button>
|
||||
@@ -2498,13 +2504,15 @@ const Vault = (() => {
|
||||
registerBtn.dataset.bound = "1";
|
||||
registerBtn.addEventListener("click", async () => {
|
||||
const nameInput = document.getElementById("passkey-name-input");
|
||||
const attachSel = document.getElementById("passkey-attachment-select");
|
||||
const name = (nameInput?.value || "").trim() || "Passkey";
|
||||
const attachment = attachSel?.value || "platform";
|
||||
const errEl = document.getElementById("passkeys-error");
|
||||
errEl?.classList.add("hidden");
|
||||
registerBtn.disabled = true;
|
||||
registerBtn.textContent = "Waiting…";
|
||||
|
||||
const result = await PasskeyAuth.registerPasskey(name);
|
||||
const result = await PasskeyAuth.registerPasskey(name, attachment);
|
||||
|
||||
registerBtn.disabled = false;
|
||||
registerBtn.textContent = "+ Add passkey";
|
||||
@@ -4339,4 +4347,4 @@ const Vault = (() => {
|
||||
}
|
||||
})();
|
||||
|
||||
document.addEventListener("DOMContentLoaded", Vault.init);
|
||||
document.addEventListener("DOMContentLoaded", Vault.init);
|
||||
|
||||
Reference in New Issue
Block a user