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
4 files manifest.firefox.json+1 −1manifest.json+1 −1package.json+1 −1src/popup/views/Entry.tsx+49 −35
manifest.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": {

view file

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",

view file

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": {

view file

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 ─────────────────────────────────── */}

view file