e4155d95f68e
fix: Show changelog only for intentional notices (v5.2.5)
- time
- 2026-09-06 19:35 UTC · 1 month ago
- machine
- koh2
- parent
- 46fd698ce73c
↓ peach-browser-e4155d95.tar.gzatlas at this save
files changed5 files
manifest.firefox.json+1 −1manifest.json+1 −1package.json+1 −1src/shared/release-notes.test.ts+15 −9src/shared/release-notes.ts+16 −10manifest.firefox.json+1 −1
@@ -1,7 +1,7 @@11 {22 "manifest_version": 3,33 "name": "Peach Password Manager",4- "version": "5.2.4",4+ "version": "5.2.5",55 "description": "Zero-knowledge password manager",66 "browser_specific_settings": {77 "gecko": {manifest.json+1 −1
@@ -2,7 +2,7 @@22 "manifest_version": 3,33 "minimum_chrome_version": "116",44 "name": "Peach Password Manager",5- "version": "5.2.4",5+ "version": "5.2.5",66 "description": "Zero-knowledge password manager",77 "action": {88 "default_popup": "src/popup/index.html",package.json+1 −1
@@ -1,6 +1,6 @@11 {22 "name": "peach",3- "version": "5.2.4",3+ "version": "5.2.5",44 "description": "Zero-knowledge password manager",55 "license": "GPL-3.0-only",66 "type": "module",src/shared/release-notes.test.ts+15 −9
@@ -17,6 +17,7 @@1717 // Import after globals are stubbed so the module captures the mock.1818 const {1919 PEACH_VERSION,20+ CURRENT_NOTICE_ID,2021 CURRENT_NOTES,2122 hasReleaseNotes,2223 shouldShowWhatsNew,@@ -45,34 +46,39 @@4546 expect(hasReleaseNotes()).toBe(true);4647 });4748 48- it("shouldShowWhatsNew returns true when stored version differs", async () => {49- store["peach_whats_new_seen"] = "0.0.1";49+ it("shouldShowWhatsNew returns true when the important notice changes", async () => {50+ store["peach_whats_new_seen"] = "previous-critical-notice";5051 expect(await shouldShowWhatsNew()).toBe(true);5152 });5253 53- it("shouldShowWhatsNew returns false when stored version matches", async () => {54- store["peach_whats_new_seen"] = PEACH_VERSION;54+ it("shouldShowWhatsNew returns false when the important notice matches", async () => {55+ store["peach_whats_new_seen"] = CURRENT_NOTICE_ID;5556 expect(await shouldShowWhatsNew()).toBe(false);5657 });5758 59+ it("does not reshow unchanged notes after a patch-version dismissal", async () => {60+ store["peach_whats_new_seen"] = "5.2.3";61+ expect(await shouldShowWhatsNew()).toBe(false);62+ expect(store["peach_whats_new_seen"]).toBe(CURRENT_NOTICE_ID);63+ });64+5865 it("shouldShowWhatsNew returns false on a fresh install (nothing seen yet)", async () => {5966 expect(await shouldShowWhatsNew()).toBe(false);6067 });6168 6269 it("markWhatsNewSeen stores the current version and suppresses reshowing", async () => {6370 // Simulate an upgrade from a previously-seen older version.64- store["peach_whats_new_seen"] = "0.0.1";71+ store["peach_whats_new_seen"] = "previous-critical-notice";6572 expect(await shouldShowWhatsNew()).toBe(true);6673 await markWhatsNewSeen();6774 expect(await shouldShowWhatsNew()).toBe(false);68- expect(store["peach_whats_new_seen"]).toBe(PEACH_VERSION);75+ expect(store["peach_whats_new_seen"]).toBe(CURRENT_NOTICE_ID);6976 });7077 71- it("a version bump re-triggers the screen", async () => {78+ it("a new important notice re-triggers the screen", async () => {7279 await markWhatsNewSeen();7380 expect(await shouldShowWhatsNew()).toBe(false);74- // Simulate an older stored version (as if the user upgraded)75- store["peach_whats_new_seen"] = "5.0.0";81+ store["peach_whats_new_seen"] = "future-breaking-notice";7682 expect(await shouldShowWhatsNew()).toBe(true);7783 });7884 });src/shared/release-notes.ts+16 −10
@@ -1,15 +1,13 @@11 /**22 * Build-time release notes for the "what's new" screen.33 *4- * The screen appears once after unlock when the build version differs from the5- * last version the user acknowledged. `__PEACH_VERSION__` is injected by Vite6- * from package.json at build time. When `CURRENT_NOTES` is empty the screen is7- * skipped entirely — no content, no interruption.4+ * The screen appears once after unlock when CURRENT_NOTICE_ID differs from the5+ * last notice the user acknowledged. The app version is display-only: routine6+ * patch releases must not replay unchanged notes.87 *9- * To ship a new changelog: bump the version in package.json (which Vite injects10- * as `__PEACH_VERSION__`), then add entries to `CURRENT_NOTES` below. The11- * version mismatch triggers the screen on next unlock; "Continue" stores the12- * version and suppresses it until the next bump.8+ * To ship an important/breaking changelog: update CURRENT_NOTES and deliberately9+ * change CURRENT_NOTICE_ID. "Continue" stores that ID and suppresses the screen10+ * until the next intentional notice revision.1311 */1412 1513 declare const __PEACH_VERSION__: string;@@ -24,6 +22,8 @@2422 ? __PEACH_VERSION__2523 : "0.0.0";2624 25+export const CURRENT_NOTICE_ID = "vault-v4-android-minimum-2026-09-05";26+2727 export const CURRENT_NOTES: ReleaseNote[] = [2828 {2929 heading: "Passphrases & long passwords",@@ -51,7 +51,13 @@5151 // on, so the screen never appears. It only fires on an upgrade from a5252 // previously-seen version. Mirrors Android's WhatsNewScreen gate.5353 if (last === undefined) return false;54- return last !== PEACH_VERSION;54+ if (typeof last === "string" && /^\d+\.\d+\.\d+$/.test(last)) {55+ // Versions through v5.2.4 stored the app version. Any such value proves56+ // this same static V4 notice was already acknowledged; migrate silently.57+ await chrome.storage.local.set({ [WHATS_NEW_SEEN_KEY]: CURRENT_NOTICE_ID });58+ return false;59+ }60+ return last !== CURRENT_NOTICE_ID;5561 } catch {5662 return false;5763 }@@ -59,7 +65,7 @@5965 6066 export async function markWhatsNewSeen(): Promise<void> {6167 try {62- await chrome.storage.local.set({ [WHATS_NEW_SEEN_KEY]: PEACH_VERSION });68+ await chrome.storage.local.set({ [WHATS_NEW_SEEN_KEY]: CURRENT_NOTICE_ID });6369 } catch {6470 // best-effort — the screen just won't reshow, which is the lesser evil6571 }