4c33f3380f77
expose + add 2FA button on login entries with no TOTP secret (v1.8.3)
- time
- 2026-04-24 22:32 UTC · 6 months ago
- machine
- koh2
- parent
- 653b9700c5c0
↓ peach-browser-4c33f338.tar.gzatlas at this save
files changed4 files
manifest.firefox.json+1 −1manifest.json+1 −1package.json+1 −1src/popup/views/Entry.tsx+49 −35manifest.firefox.json+1 −1
@@ -1,7 +1,7 @@11 {22 "manifest_version": 3,33 "name": "Peach",4- "version": "1.8.2",4+ "version": "1.8.3",55 "description": "Zero-knowledge password manager",66 "browser_specific_settings": {77 "gecko": {manifest.json+1 −1
@@ -1,7 +1,7 @@11 {22 "manifest_version": 3,33 "name": "Peach",4- "version": "1.8.2",4+ "version": "1.8.3",55 "description": "Zero-knowledge password manager",66 "action": {77 "default_popup": "src/popup/index.html",package.json+1 −1
@@ -1,6 +1,6 @@11 {22 "name": "peach",3- "version": "1.8.2",3+ "version": "1.8.3",44 "description": "Zero-knowledge password manager",55 "type": "module",66 "scripts": {src/popup/views/Entry.tsx+49 −35
@@ -806,45 +806,59 @@806806 </Show>807807 808808 {/* ── TOTP ─────────────────────────────────────────── */}809- <Show when={totpState()}>810- {(state) => (809+ <Show when={entry().type === "login"}>810+ <Show811+ when={totpState() || editingField() === "totp"}812+ fallback={813+ <button814+ class="peach-btn peach-btn--ghost peach-btn--sm peach-add-notes-btn"815+ onClick={() => startEdit("totp", "")}816+ >817+ + add 2FA818+ </button>819+ }820+ >811821 <section class="peach-totp-band">812822 <Show813823 when={editingField() === "totp"}814824 fallback={815- <>816- <div817- class="peach-totp-main peach-inline-clickable"818- onClick={() => startEdit("totp", entry().totp ?? "")}819- >820- <span class="peach-label">2-factor</span>821- <div class="peach-totp-code-row">822- <p class={`peach-totp-code${totpHot() ? " is-hot" : ""}`}>823- <span class="peach-totp-code-text">824- {state().code.slice(0, 3)} {state().code.slice(3)}825- </span>826- </p>827- <button828- class={`peach-btn peach-btn--ghost peach-btn--sm peach-icon-btn peach-copy-btn peach-totp-copy-btn ${copied() === "totp" ? "is-copied" : ""}`}829- onClick={(e) => void copyField(state().code.replace(" ", ""), "totp", e.currentTarget as HTMLButtonElement)}830- aria-label="Copy TOTP code"825+ <Show when={totpState()}>826+ {(state) => (827+ <>828+ <div829+ class="peach-totp-main peach-inline-clickable"830+ onClick={() => startEdit("totp", entry().totp ?? "")}831831 >832- <CopyGlyph /><span class="peach-copy-sheen" />833- </button>834- </div>835- </div>836- <div class="peach-totp-meta">837- <span class="peach-label">expires</span>838- <div class="peach-totp-countdown">{state().remaining}s</div>839- <svg class="peach-totp-ring" width="44" height="44" viewBox="0 0 44 44">840- <circle cx="22" cy="22" r="17" class="peach-totp-ring-track" />841- <circle cx="22" cy="22" r="17" class="peach-totp-ring-progress"842- stroke-dasharray="106.8"843- stroke-dashoffset={(1 - state().remaining / 30) * 106.8}844- />845- </svg>846- </div>847- </>832+ <span class="peach-label">2-factor</span>833+ <div class="peach-totp-code-row">834+ <p class={`peach-totp-code${totpHot() ? " is-hot" : ""}`}>835+ <span class="peach-totp-code-text">836+ {state().code.slice(0, 3)} {state().code.slice(3)}837+ </span>838+ </p>839+ <button840+ class={`peach-btn peach-btn--ghost peach-btn--sm peach-icon-btn peach-copy-btn peach-totp-copy-btn ${copied() === "totp" ? "is-copied" : ""}`}841+ onClick={(e) => void copyField(state().code.replace(" ", ""), "totp", e.currentTarget as HTMLButtonElement)}842+ aria-label="Copy TOTP code"843+ >844+ <CopyGlyph /><span class="peach-copy-sheen" />845+ </button>846+ </div>847+ </div>848+ <div class="peach-totp-meta">849+ <span class="peach-label">expires</span>850+ <div class="peach-totp-countdown">{state().remaining}s</div>851+ <svg class="peach-totp-ring" width="44" height="44" viewBox="0 0 44 44">852+ <circle cx="22" cy="22" r="17" class="peach-totp-ring-track" />853+ <circle cx="22" cy="22" r="17" class="peach-totp-ring-progress"854+ stroke-dasharray="106.8"855+ stroke-dashoffset={(1 - state().remaining / 30) * 106.8}856+ />857+ </svg>858+ </div>859+ </>860+ )}861+ </Show>848862 }849863 >850864 <div@@ -866,7 +880,7 @@866880 </div>867881 </Show>868882 </section>869- )}883+ </Show>870884 </Show>871885 872886 {/* ── Bottom spacer ─────────────────────────────────── */}