diff --git a/shared/components/rstack-identity.ts b/shared/components/rstack-identity.ts
index 4862a1d..600b245 100644
--- a/shared/components/rstack-identity.ts
+++ b/shared/components/rstack-identity.ts
@@ -420,62 +420,116 @@ export class RStackIdentity extends HTMLElement {
const status = await res.json();
if (status.multiDevice) return; // already has 2+ devices
- // Show a toast nudge
+ // Show a toast nudge with QR code
const toast = document.createElement("div");
toast.className = "eid-device-nudge";
- toast.innerHTML = `
-
-
-
- Sign in from your phone or tablet too — it also acts as a backup if you ever lose access to this device.
-
-
-
-
-
- `;
- toast.querySelector('[data-action="setup"]')?.addEventListener("click", () => {
- toast.remove();
- this.showAccountModal({ openSection: "device" });
- });
- toast.querySelector('[data-action="later"]')?.addEventListener("click", () => {
- localStorage.setItem(NUDGE_KEY, String(Date.now()));
- toast.style.animation = "eid-nudge-in 0.3s ease-in reverse forwards";
- setTimeout(() => toast.remove(), 300);
- });
+ let linkUrl = "";
+ let linkError = "";
+
+ const renderNudge = () => {
+ const qrHTML = linkUrl
+ ? `
+
}&format=png&margin=6)
+
+
+
+
+
+ Expires in 10 minutes
`
+ : linkError
+ ? `${linkError}
`
+ : ` Generating link…
`;
+
+ toast.innerHTML = `
+
+
+
+ Scan this QR code on your phone or tablet to add a passkey backup.
+
+ ${qrHTML}
+
+
+
+ `;
+
+ toast.querySelector('[data-action="later"]')?.addEventListener("click", () => {
+ localStorage.setItem(NUDGE_KEY, String(Date.now()));
+ toast.style.animation = "eid-nudge-in 0.3s ease-in reverse forwards";
+ setTimeout(() => toast.remove(), 300);
+ });
+ toast.querySelector('[data-action="copy"]')?.addEventListener("click", () => {
+ navigator.clipboard.writeText(linkUrl).catch(() => {});
+ const btn = toast.querySelector('[data-action="copy"]') as HTMLButtonElement;
+ if (btn) { btn.textContent = "Copied!"; setTimeout(() => { btn.textContent = "Copy"; }, 2000); }
+ });
+ };
document.body.appendChild(toast);
+ renderNudge(); // show loading state
+
+ // Generate device link
+ try {
+ const linkRes = await fetch(`${ENCRYPTID_URL}/api/device-link/start`, {
+ method: "POST",
+ headers: { Authorization: `Bearer ${getAccessToken()}` },
+ });
+ const linkData = await linkRes.json();
+ if (!linkRes.ok || linkData.error) throw new Error(linkData.error || "Failed");
+ linkUrl = linkData.linkUrl;
+ } catch {
+ linkError = "Could not generate link. Try My Account → Devices.";
+ }
+ renderNudge(); // show QR or error
} catch { /* offline */ }
}