github eclipse-openvsx/openvsx v1.4.0

one hour ago

Server

[1.4.0] - 2026-11-09

Added

  • Publisher agreements without an external service: set ovsx.publisher-agreement.version (such as 1, 1.0 or 1.0.0) and ovsx.publisher-agreement.text to make users sign before publishing; a new major version makes signatures outdated, unless ovsx.publisher-agreement.allowed-versions names the versions whose signatures stay valid (#2325)
  • An outdated agreement stops publishing until it is signed again, while a revoked or missing one also takes extensions offline on the startup compliance check (#2325)
  • Admins can reinstate a revoked agreement with POST /admin/publisher/{provider}/{loginName}/reinstate-agreement and list a user's signings, revocations and reinstatements with GET /admin/publisher/{provider}/{loginName}/agreement-history; migration V1_82 adds the publisher_agreement_event table (#2325)
  • ovsx.publisher-agreement.check-compliance-on-start runs the publisher compliance check on startup for any agreement provider (#2325)
  • GET /admin/api/permissions lists the permissions a deployment registers
  • GET /admin/user/search takes a permission parameter, a permission name or any, to list users granted it individually; admins are not matched (#2399)
  • Trusted publishing registers a repository the provider cannot look up, such as a private one, as pending until its first publish presents the single-use registration code (registrationCode, valid for 7 days); migration V1_85 (#2350)

Changed

  • The Eclipse publisher agreement and OAuth login moved behind the PublisherAgreementProvider and ExternalLoginProvider extension points, and UserJson.publisherAgreement gains loginProvider and loginProviderName (#2325)
  • A login of any provider returns to the page that started it, when that page is passed as redirect, instead of the eclipse login always going to the profile page (#2325)
  • Signing an agreement that is already signed answers 200 instead of 400, and additionalLogins[].loginName of a user is no longer set (#2325)
  • Upgrade: the ovsx.eclipse.* properties, their deployment descriptor entries and the Eclipse handling of generate-properties.sh (ECLIPSE_CLIENT_*, and the ovsx.publishing.require-license=true it set) are removed without a fallback, so ovsx.eclipse.check-compliance-on-start becomes ovsx.publisher-agreement.check-compliance-on-start; a deployment that needs Eclipse supplies a @Primary PublisherAgreementProvider, otherwise everyone may publish unless ovsx.publisher-agreement.version is set (#2325)
  • ovsx.data.mirror.requests-per-second now spaces upstream requests evenly instead of allowing a burst of up to one second of requests after an idle period (#2324)
  • A failed namespace change is retried once, instead of ten times as JobRunr does by default (#2353)
  • Permission is an open type that deployments extend through PermissionProvider; only registered permissions can be granted, open /admin, or reserve a user's revocation to admins, and an unknown name is a 400
  • A request that needs a logged-in user answers 401 instead of 403 when nobody is logged in, so clients can tell an expired session from a missing permission (#2416)

Removed

  • CodedAuthException.ECLIPSE_MISSING_GITHUB_ID and ECLIPSE_MISMATCH_GITHUB_ID are removed; a login provider that needs such codes defines them itself (#2369)
  • The columns user_data.eclipse_token and user_data.eclipse_person_id are dropped, with UserData.eclipseToken/eclipsePersonId, AuthToken and AuthTokenConverter (#2369)
  • Upgrade: migration V1_83 fails, and so does the startup, while either column still holds data; a deployment that uses them copies the rows to its own table and sets both columns to NULL first, in a migration that sorts before V1_83 (#2369)
  • AdminService.forgetUser publishes a UserForgottenEvent(userId) in the erasure's transaction, whether the row is deleted or anonymized, for a deployment that keeps personal data of a user elsewhere to clear it (#2369)
  • Tier-based rate limiting, its admin and /user/customers endpoints, and the ovsx.rate-limit.* and ovsx.caching.{customer,tier,rate-limit-token,usage}.* settings are removed
  • Upgrade: migration V1_84 drops the six rate limit tables and refuses to run while they hold rows, so move the data out and stop writing to them first; supply a RedisClusterClient bean (or enable bucket4j's redis-cluster-jedis cache) if rate limiting provided it; stored manage_rate_limits grants stop counting, and are dropped on the next access save, unless a PermissionProvider registers that name; delete the JobRunr recurring jobs collect-usage-stats and calculate-daily-usage-stats unless your deployment reschedules them under those ids; keep an every-admin-handler-authorizes check like AdminEndpointPermissionCheckTest in your own admin controllers

Fixed

  • Moving extensions into an existing namespace no longer reverts edits made to that namespace while its files were being copied (#2353)
  • Signing the publisher agreement and the bulk revocation of publishers are refused while the registry is in read-only mode, like the other endpoints that write to the database
  • Fix the startup failure with bucket4j.enabled=true by bumping bucket4j-spring-boot-starter to 0.14.0 (Spring Boot 4) and bucket4j to 8.15.0 (#2405)
  • The publisher and admin extension details show the version the registry serves as latest instead of a higher removed one (#2409)

Dependencies

  • Remove the direct guava dependency (#2324)
  • Bump Spring Boot to 4.0.9, with Jetty 12.1.14, Netty 4.2.19.Final and PostgreSQL driver 42.7.14
  • Force the transitive guava (from google-cloud-storage) from 33.5.0 to 33.7.2, fixing uncontrolled memory allocation when deserializing Guava's compact hash collections (#2431)
  • Bump OpenTelemetry from 1.63.0 to 1.67.0, fixing quadratic CPU use when parsing crafted W3C tracestate headers; the discontinued Zipkin exporter stays at 1.64.0 (#2430)

Web UI

[1.4.0] - 2026-11-09

Added

  • PageSettings.elements.errorHelp adds a deployment's help below the message of the error dialog, given the error code and message, such as a link for the code of a login provider it adds (#2369)
  • useReportedQuery requires an action that titles the error dialog with what failed, e.g. "Couldn’t load the namespace members", and an ignore predicate for the errors a page renders itself, e.g. isNotFound for a 404 shown as a not-found state; MainContext.handleError takes the dialog title directly
  • Curated home rows are regions labelled with their title and set aria-busy while they load, so assistive technology can tell a loading row from a loaded one
  • PageSettings.elements.userSettingsTabs lets a deployment contribute user-settings tabs
  • The index exports handleError, NO_CACHE, DelayedLoadIndicator, Timestamp, AddUserDialog, GenerateTokenDialog, SearchListContainer, createMultiSelectFilterOperators, createArrayContainsFilterOperators, SettingsHeader and EmptyPlaceholder, for pages contributed through adminPages and userSettingsTabs
  • Filter users on the Access Control page by granted permission and show each user's permissions as chips in the results; useAdminUserSearch takes an optional permission (#2399)
  • Registering a trusted publisher for a private repository shows its single-use registration code once and marks the registration as pending in the list until the first publish completes it (#2350)

Changed

  • The error dialog no longer has help for the eclipse-missing-github-id and eclipse-mismatch-github-id login errors, and a failed publisher agreement points to pageSettings.publisherAgreement.email, or to the registry's administrators without one, instead of webmaster@eclipse.org; the error message itself is still shown (#2369)
  • The publisher agreement panel and the admin revoke dialog take the login they require from the new publisherAgreement.loginProvider and loginProviderName (display label) fields of UserData instead of assuming Eclipse; without it no extra login is asked for; their login links return to the page they were on
  • The publisher agreement panel shows a revoked status without a sign action, a different message for an outdated one, and admins can reinstate a revoked agreement
  • MainContext keeps its value, handleError and updateUser stable across renders, so consumers can depend on them in effects and skip needless re-renders
  • The default publisher agreement text URL is now the server's /api/publisher-agreement, instead of /documents/publisher-agreement.md
  • sendRequest rejects a 200 carrying an error result and no longer retries; retries belong to the query client, which waits out a 429 for queries and never retries a mutation.
  • ExtensionRegistryService query methods take an AbortSignal instead of an AbortController and write methods take neither; no method resolves an ErrorResult any more but rejects with it, as getUser does when nobody is logged in.
  • The error dialog is titled with what failed, e.g. "Couldn’t load the namespace members", instead of a bare "Error"
  • A curated row on the home page that fails to load shows "We couldn’t load extensions at this time." with a Retry button instead of disappearing; CuratedRow carries the row's error and a refetch for custom home pages
  • AdminPermission is a string, ADMIN_PERMISSIONS names the built-in ones, and the Access Control page lists permissions from the server, so a deployment can register its own
  • Breaking: AppProviders no longer mounts the QueryClientProvider or takes a queryClient; Main mounts it above everything else, so a page that mounts AppProviders without Main wraps it in its own QueryClientProvider

Fixed

  • A query reported through useReportedQuery (or a page's own error effect) no longer reopens the error dialog in a loop that cannot be closed while the query stays failed (#2348)
  • A failed review post or removal, token revocation or user search no longer leaves its spinner running
  • An expired session no longer leaves the UI logged in and failing every request until the page is reloaded: a 401 the registry confirms is the end of the session logs the user out and asks them to log in again, back to the page they were on, which needs a registry that answers 401 when nobody is logged in; any other 401 is reported as an error
  • The extension details show no latest version, instead of a removed one, for an extension the registry no longer serves (#2409)

Removed

  • sendNonRetriableRequest, controllerFromSignal and the abortController field of ServerAPIRequest: use sendRequest with signal, and pass a queryFn's signal straight to the service
  • The Rate Limiting admin pages (tiers, customers, usage stats), the user-settings Rate Limiting tab, the manage_rate_limits permission and the tier, customer, usage and rate limit token methods and types of ExtensionRegistryService: a deployment adds such pages through PageSettings.elements.adminPages and userSettingsTabs

Dependencies

  • Bump vite from 8.3.2 to 8.3.5 (#2357)
  • Bump markdown-it from 14.3.2 to 14.3.3 (#2358)
  • Bump undici from 8.11.2 to 8.12.3 (#2362)
  • Remove fetch-retry; the query client owns retries
  • Bump dompurify from 3.4.16 to 3.4.17 (#2379)
  • Upgrade yarn from 4.9.1 to 4.18.1 and set npmMinimalAgeGate to 7 days, so versions published in the last 7 days are not picked for new resolutions (#2393)
  • Bump qs from 6.16.0 to 6.17.1 (#2429)

Don't miss a new openvsx release

NewReleases is sending notifications on new releases.