4cefcb6b900a

tighten PeachScript subview to match export password card pattern (peach-settings-input, password-stack, master-password labelled section, mismatch hint); surface real backend error code instead of swallowing as RESTORE_FAILED; bump 2.7.3

time
2026-04-28 04:15 UTC · 6 months ago
machine
koh2
parent
24d24af0eefd
4 files manifest.firefox.json+1 −1manifest.json+1 −1package.json+1 −1src/popup/views/Import.tsx+31 −13
manifest.firefox.json+1 −1
@@ -1,7 +1,7 @@11 {22   "manifest_version": 3,33   "name": "Peach",4-  "version": "2.7.2",4+  "version": "2.7.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": "2.7.2",4+  "version": "2.7.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": "2.7.2",3+  "version": "2.7.3",44   "description": "Zero-knowledge password manager",55   "type": "module",66   "scripts": {

view file

src/popup/views/Import.tsx+31 −13
@@ -191,7 +191,10 @@191191           settings: payload.settings,192192         },193193       });194-      if (!(restoreRes as { ok: boolean }).ok) throw new Error("RESTORE_FAILED");194+      const restoreEnvelope = restoreRes as { ok: boolean; error?: string };195+      if (!restoreEnvelope.ok) {196+        throw new Error(restoreEnvelope.error ?? "RESTORE_FAILED");197+      }195198 196199       if (payload.license?.key) {197200         await sendMessage({@@ -222,7 +225,7 @@222225             </div>223226           </div>224227         </Show>225-        <div class="peach-settings-group peach-export-card peach-export-card--primary">228+        <div class="peach-settings-group peach-export-card peach-export-card--primary peach-export-pass-group">226229           <p class="peach-settings-label">paste peachscript</p>227230           <p class="peach-export-card-copy">228231             {isOnboarding@@ -235,29 +238,40 @@235238             value={scriptInput()}236239             onInput={(e) => setScriptInput((e.target as HTMLTextAreaElement).value)}237240           />238-          <input239-            class="peach-restore-input"240-            type="password"241-            placeholder="PeachScript password"242-            value={scriptPass()}243-            onInput={(e) => setScriptPass((e.target as HTMLInputElement).value)}244-          />241+          <div class="peach-settings-stack peach-export-password-stack">242+            <input243+              class="peach-settings-input"244+              type="password"245+              placeholder="PeachScript password"246+              value={scriptPass()}247+              onInput={(e) => setScriptPass((e.target as HTMLInputElement).value)}248+            />249+          </div>245250           <Show when={isOnboarding}>246-            <div class="peach-auth-grid">251+            <p class="peach-settings-label" style="margin-top:4px">new master password</p>252+            <p class="peach-export-card-copy">253+              This password unlocks Peach on this device after the restore.254+            </p>255+            <div class="peach-settings-stack peach-export-password-stack">247256               <input248-                class="peach-restore-input"257+                class="peach-settings-input"249258                 type="password"250-                placeholder="new master password"259+                placeholder={`master password (min 8 chars)`}251260                 value={masterPassword()}252261                 onInput={(e) => setMasterPassword((e.target as HTMLInputElement).value)}253262               />254263               <input255-                class="peach-restore-input"264+                class="peach-settings-input"256265                 type="password"257266                 placeholder="confirm master password"258267                 value={masterConfirm()}259268                 onInput={(e) => setMasterConfirm((e.target as HTMLInputElement).value)}260269               />270+              <Show when={masterConfirm().length > 0 && masterPassword() !== masterConfirm()}>271+                <p class="peach-export-note" style="color:var(--peach-t2)">272+                  Passwords don't match273+                </p>274+              </Show>261275             </div>262276           </Show>263277           <button@@ -783,6 +797,10 @@783797       return "Choose a master password for your new vault first.";784798     case "RESTORE_FAILED":785799       return "Restore failed. Your existing vault is unchanged.";800+    case "vault locked":801+      return "Peach is locked. Open Peach with your master password and try again.";802+    case "refuse to replace with empty entry set":803+      return "This PeachScript decoded to zero entries — refusing to wipe the vault.";786804     case "NO_ENTRIES_IMPORTED":787805       return "No importable password entries were found in that file.";788806     default:

view file