feat(plugins): update flow — detection, one-click update, permission re-consent (#52)#61
Merged
Conversation
…re-consent (#52) The plugin manager had no update mechanism (uninstall+reinstall only) and no re-consent when a plugin's permissions or code change. installPlugin already overwrites + hash-verifies + reloads, so this adds the missing detection, affordance, and consent around it. - updates.ts: pure detection (compareSemver, availableUpdate by version OR versionless hash-diff, addedPermissions) + unit tests. - Update affordance in BOTH tabs: Installed shows v{old} → {new} + Update button; Browse swaps the badge for Update; Installed tab header shows a '• N updates' count. Catalog is fetched once on section mount. - Consent: first installs show a permission disclosure (gated by a new default-on 'Review permissions before installing plugins' setting); updates apply silently unless they request NEW permissions, which always prompts (non-skippable). Shared PluginPermissionModal for both. - marketplaceStore.fetchManifest for the pre-consent permission preview. - i18n en/fr/ru parity.
…pdates (#52) - Security: pass the reviewed manifest text into installPlugin so the executed permission set is exactly the consented one, closing the fetch→consent→load TOCTOU (manifest.json isn't hash-pinned; index.js still is). Covers install disclosure, silent updates, and permission-grow updates. - availableUpdate now requires an exact sourceId match — a local/url plugin is never 'updated' from an id-colliding catalog entry (which would overwrite the local bundle). +2 regression tests. - Installed-tab update perm baseline reads getLoadedPlugins() at click, matching the Browse tab. - Backfill 3 ru keys missing since #44 (install.failed/integrityFailed, installed.unverified).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #52. The plugin manager had no update mechanism (uninstall + reinstall only), no update-available detection, and no re-consent when a plugin's permissions or code change.
installPluginalready overwrites → hash-verifies (#44) → reloads, so this adds the missing detection, affordance, and consent around it. No Rust changes.What's here
src/plugins/updates.ts(pure, unit-tested):compareSemver,availableUpdate(newer version OR versionless hash-diff — catches in-repo re-stamps like navy-green on mutablemain),addedPermissions.v{old} → {new}+ an Update button; Browse swaps the Installed badge for an Update button; the Installed tab header shows a• N updatescount. Catalog is fetched once on section mount.PluginPermissionModalfor both (install = all perms; update = added perms emphasized).marketplaceStore.fetchManifestfor the pre-consent permission preview.Verification
updates.tsunit tests (15) + full suite 868 passing,tscclean, i18n parity green.themesbadge) → confirm installs (6→7); update detection (• 1 updatecount,v0.9.0 → 1.0.0arrow, Update button); silent update when no new perms (badge clears); permission-grow modal ("New permissions" +themes) as the security gate; opt-out OFF → one-click install with no disclosure.Notes / out of scope
manifest.jsonisn't hash-pinned (pre-existing); the perm preview re-fetches it, but the executedindex.jsstays hash-verified. Negligible pre-existing TOCTOU window.