diff --git a/.changeset/registry-lifecycle.md b/.changeset/registry-lifecycle.md new file mode 100644 index 000000000..082af0fa4 --- /dev/null +++ b/.changeset/registry-lifecycle.md @@ -0,0 +1,10 @@ +--- +"@emdash-cms/admin": minor +"emdash": minor +--- + +Plugins installed from the experimental registry can now be uninstalled and updated from the admin, the same way marketplace plugins always could. The "uninstall is not yet available for registry plugins" placeholder is gone — registry plugin rows now show the same Uninstall and Update buttons. + +The Plugins page's "updates available" indicator now covers registry plugins too. If the registry aggregator is unreachable, marketplace updates still load (and vice versa). + +Updates that need newly-declared permissions, or that newly expose a public (unauthenticated) route, prompt for re-consent before installing the new version — matching the gate that marketplace updates already have. diff --git a/packages/admin/src/components/CapabilityConsentDialog.tsx b/packages/admin/src/components/CapabilityConsentDialog.tsx index c97de8bff..58056de1e 100644 --- a/packages/admin/src/components/CapabilityConsentDialog.tsx +++ b/packages/admin/src/components/CapabilityConsentDialog.tsx @@ -26,6 +26,8 @@ export interface CapabilityConsentDialogProps { allowedHosts?: string[]; /** New capabilities added in an update (highlighted differently) */ newCapabilities?: string[]; + /** Routes that change from private to public in an update. */ + newlyPublicRoutes?: string[]; /** Audit verdict badge */ auditVerdict?: "pass" | "warn" | "fail"; /** Whether the action is in progress */ @@ -44,6 +46,7 @@ export function CapabilityConsentDialog({ capabilities, allowedHosts, newCapabilities = [], + newlyPublicRoutes = [], auditVerdict, isPending = false, error, @@ -52,7 +55,7 @@ export function CapabilityConsentDialog({ }: CapabilityConsentDialogProps) { const { t } = useLingui(); const newSet = new Set(newCapabilities); - const isUpdate = mode === "update" || newCapabilities.length > 0; + const isUpdate = mode === "update" || newCapabilities.length > 0 || newlyPublicRoutes.length > 0; return (
+ {t`This update exposes the following routes without authentication:`} +
+