diff --git a/server/src/main/java/org/eclipse/openvsx/LocalRegistryService.java b/server/src/main/java/org/eclipse/openvsx/LocalRegistryService.java
index 3a2b5ee5b..670da1571 100644
--- a/server/src/main/java/org/eclipse/openvsx/LocalRegistryService.java
+++ b/server/src/main/java/org/eclipse/openvsx/LocalRegistryService.java
@@ -38,6 +38,7 @@
import org.eclipse.openvsx.eclipse.EclipseService;
import org.eclipse.openvsx.entities.*;
import org.eclipse.openvsx.json.*;
+import org.eclipse.openvsx.migration.MigrationsProperties;
import org.eclipse.openvsx.publish.ExtensionVersionIntegrityService;
import org.eclipse.openvsx.publish.PublishingConfig;
import org.eclipse.openvsx.repositories.RepositoryService;
@@ -62,6 +63,7 @@
import org.eclipse.openvsx.util.VersionService;
import org.eclipse.openvsx.util.auth.AuthenticatedUser;
import org.eclipse.openvsx.util.auth.LoggedInAuthentication;
+import org.eclipse.openvsx.web.WebUiProperties;
import static org.eclipse.openvsx.cache.CacheService.*;
import static org.eclipse.openvsx.entities.FileResource.*;
@@ -89,6 +91,8 @@ public class LocalRegistryService implements IExtensionRegistry {
private final SimilarityCheckService similarityCheckService;
private final PublishingConfig publishingConfig;
private final TrustedPublishingConfig trustedPublishingConfig;
+ private final MigrationsProperties migrationsProperties;
+ private final WebUiProperties webUi;
/**
* How far behind the present the changes feed stops, see {@link #visibleUntil}.
@@ -111,6 +115,8 @@ public LocalRegistryService(
@Nullable SimilarityCheckService similarityCheckService,
PublishingConfig publishingConfig,
TrustedPublishingConfig trustedPublishingConfig,
+ MigrationsProperties migrationsProperties,
+ WebUiProperties webUi,
@Value("${ovsx.changes-feed.lag:PT30S}") Duration changesFeedLag
) {
this.entityManager = entityManager;
@@ -128,15 +134,11 @@ public LocalRegistryService(
this.similarityCheckService = similarityCheckService;
this.publishingConfig = publishingConfig;
this.trustedPublishingConfig = trustedPublishingConfig;
+ this.migrationsProperties = migrationsProperties;
+ this.webUi = webUi;
this.changesFeedLag = changesFeedLag;
}
- @Value("${ovsx.webui.url:}")
- String webuiUrl;
-
- @Value("${ovsx.registry.version:}")
- String registryVersion;
-
@Override
public NamespaceJson getNamespace(String namespaceName) {
return getNamespace(namespaceName, false);
@@ -1330,7 +1332,7 @@ private ExtensionReplacementJson toReplacementJson(
return null;
}
- var baseUrl = webui ? webuiUrl : UrlUtil.getBaseUrl();
+ var baseUrl = webui ? webUi.getUrl() : UrlUtil.getBaseUrl();
var segments = new String[] {
webui ? "extension" : "api",
replacement.getExtension().getNamespace().getName(),
@@ -1377,6 +1379,7 @@ public String getPublicKey(String publicId) {
@Override
public RegistryVersionJson getRegistryVersion() {
+ var registryVersion = migrationsProperties.getRegistryVersion();
if (StringUtils.isEmpty(registryVersion)) {
throw new NotFoundException();
}
diff --git a/server/src/main/java/org/eclipse/openvsx/RestTemplateConfig.java b/server/src/main/java/org/eclipse/openvsx/RestTemplateConfig.java
index 577e186b2..d15afc689 100644
--- a/server/src/main/java/org/eclipse/openvsx/RestTemplateConfig.java
+++ b/server/src/main/java/org/eclipse/openvsx/RestTemplateConfig.java
@@ -26,6 +26,8 @@
import org.springframework.web.client.RestTemplate;
import org.springframework.web.util.DefaultUriBuilderFactory;
+import org.eclipse.openvsx.mirror.MirrorConfig;
+
@Configuration
public class RestTemplateConfig {
@@ -154,11 +156,11 @@ public RestTemplate backgroundNonRedirectingRestTemplate(
@Bean
public RestTemplate vsCodeIdRestTemplate(
- @Value("${ovsx.data.mirror.enabled:false}") boolean mirrorModeEnabled,
+ MirrorConfig mirrorConfig,
RestTemplate restTemplate,
RestTemplate backgroundRestTemplate
) {
- return mirrorModeEnabled ? backgroundRestTemplate : restTemplate;
+ return mirrorConfig.isEnabled() ? backgroundRestTemplate : restTemplate;
}
private HttpClientBuilder createHttpClientBuilder(HttpConnPoolConfig httpConnPoolConfig) {
diff --git a/server/src/main/java/org/eclipse/openvsx/accesstoken/AccessTokenConfig.java b/server/src/main/java/org/eclipse/openvsx/accesstoken/AccessTokenConfig.java
index 6a18940a1..6a61d6774 100644
--- a/server/src/main/java/org/eclipse/openvsx/accesstoken/AccessTokenConfig.java
+++ b/server/src/main/java/org/eclipse/openvsx/accesstoken/AccessTokenConfig.java
@@ -22,8 +22,17 @@
import org.springframework.context.annotation.Configuration;
import org.springframework.util.StringUtils;
+import org.eclipse.openvsx.mirror.MirrorConfig;
+
@Configuration
public class AccessTokenConfig {
+
+ private final MirrorConfig mirrorConfig;
+
+ public AccessTokenConfig(MirrorConfig mirrorConfig) {
+ this.mirrorConfig = mirrorConfig;
+ }
+
/**
* The token prefix to use when generating a new access token.
*
@@ -116,9 +125,6 @@ public class AccessTokenConfig {
@Value("${ovsx.access-token.token-hash-salt:}")
private String tokenHashSalt;
- @Value("${ovsx.data.mirror.enabled:false}")
- private boolean mirrorEnabled;
-
public @NonNull String getPrefix() {
return this.prefix;
}
@@ -173,7 +179,7 @@ public boolean hasNotificationSchedule() {
@PostConstruct
public void validate() {
- if (isTokenExpiryEnabled() && mirrorEnabled) {
+ if (isTokenExpiryEnabled() && mirrorConfig.isEnabled()) {
throw new IllegalArgumentException(
"ovsx.access-token.expiration can not be enabled when mirror mode is active, got: " + expiration);
}
diff --git a/server/src/main/java/org/eclipse/openvsx/adapter/LocalVSCodeService.java b/server/src/main/java/org/eclipse/openvsx/adapter/LocalVSCodeService.java
index 487010a52..7da37a8a4 100644
--- a/server/src/main/java/org/eclipse/openvsx/adapter/LocalVSCodeService.java
+++ b/server/src/main/java/org/eclipse/openvsx/adapter/LocalVSCodeService.java
@@ -48,6 +48,7 @@
import org.eclipse.openvsx.util.TimeUtil;
import org.eclipse.openvsx.util.UrlUtil;
import org.eclipse.openvsx.util.VersionService;
+import org.eclipse.openvsx.web.WebUiProperties;
import static org.eclipse.openvsx.adapter.ExtensionQueryParam.*;
import static org.eclipse.openvsx.adapter.ExtensionQueryParam.Criterion.*;
@@ -68,6 +69,7 @@ public class LocalVSCodeService implements IVSCodeService {
private final ExtensionVersionIntegrityService integrityService;
private final WebResourceService webResources;
private final CacheService cache;
+ private final WebUiProperties webUi;
private final Map assets = Map.of(
FILE_VSIX,
@@ -87,9 +89,6 @@ public class LocalVSCodeService implements IVSCodeService {
FILE_SIGNATURE,
DOWNLOAD_SIG);
- @Value("${ovsx.webui.url:}")
- String webuiUrl;
-
// See RepositoryService.findActiveExtensionVersions / ExtensionVersionJooqRepository -
// caps how many of an extension's active pre-release versions the version listing below
// fetches per extensionQuery request; regular releases are never capped. A negative value
@@ -105,7 +104,8 @@ public LocalVSCodeService(
StorageUtilService storageUtil,
ExtensionVersionIntegrityService integrityService,
WebResourceService webResources,
- CacheService cache
+ CacheService cache,
+ WebUiProperties webUi
) {
this.repositories = repositories;
this.versions = versions;
@@ -114,6 +114,7 @@ public LocalVSCodeService(
this.integrityService = integrityService;
this.webResources = webResources;
this.cache = cache;
+ this.webUi = webUi;
}
@Override
@@ -466,7 +467,11 @@ public String getItemUrl(String namespaceName, String extensionName) {
throw new NotFoundException();
}
- return UrlUtil.createApiUrl(webuiUrl, "extension", extension.getNamespace().getName(), extension.getName());
+ return UrlUtil.createApiUrl(
+ webUi.getUrl(),
+ "extension",
+ extension.getNamespace().getName(),
+ extension.getName());
}
@Override
diff --git a/server/src/main/java/org/eclipse/openvsx/adapter/VSCodeIdService.java b/server/src/main/java/org/eclipse/openvsx/adapter/VSCodeIdService.java
index 7268a3a55..c6449c90d 100644
--- a/server/src/main/java/org/eclipse/openvsx/adapter/VSCodeIdService.java
+++ b/server/src/main/java/org/eclipse/openvsx/adapter/VSCodeIdService.java
@@ -27,6 +27,8 @@
import org.eclipse.openvsx.UrlConfigService;
import org.eclipse.openvsx.entities.Extension;
import org.eclipse.openvsx.migration.HandlerJobRequest;
+import org.eclipse.openvsx.migration.MigrationsProperties;
+import org.eclipse.openvsx.mirror.MirrorConfig;
import org.eclipse.openvsx.util.NamingUtil;
import org.eclipse.openvsx.util.TimeUtil;
import org.eclipse.openvsx.util.UUIDService;
@@ -39,36 +41,36 @@ public class VSCodeIdService {
private final UrlConfigService urlConfigService;
private final JobRequestScheduler scheduler;
private final UUIDService uuidService;
-
- @Value("${ovsx.data.mirror.enabled:false}")
- boolean mirrorEnabled;
+ private final MirrorConfig mirrorConfig;
+ private final MigrationsProperties migrationsProperties;
@Value("${ovsx.vscode.upstream.update-on-start:false}")
boolean updateOnStart;
- @Value("${ovsx.migrations.delay.seconds:0}")
- long delay;
-
public VSCodeIdService(
RestTemplate vsCodeIdRestTemplate,
UrlConfigService urlConfigService,
JobRequestScheduler scheduler,
- UUIDService uuidService
+ UUIDService uuidService,
+ MirrorConfig mirrorConfig,
+ MigrationsProperties migrationsProperties
) {
this.vsCodeIdRestTemplate = vsCodeIdRestTemplate;
this.urlConfigService = urlConfigService;
this.scheduler = scheduler;
this.uuidService = uuidService;
+ this.mirrorConfig = mirrorConfig;
+ this.migrationsProperties = migrationsProperties;
}
@EventListener
public void applicationStarted(ApplicationStartedEvent event) {
- if (mirrorEnabled) {
+ if (mirrorConfig.isEnabled()) {
return;
}
if (updateOnStart) {
scheduler.schedule(
- TimeUtil.getCurrentUTC().plusSeconds(delay),
+ TimeUtil.getCurrentUTC().plusSeconds(migrationsProperties.getDelaySeconds()),
new HandlerJobRequest<>(VSCodeIdDailyUpdateJobRequestHandler.class));
}
diff --git a/server/src/main/java/org/eclipse/openvsx/extension_control/ExtensionControlService.java b/server/src/main/java/org/eclipse/openvsx/extension_control/ExtensionControlService.java
index 8e8449203..ea2d911f4 100644
--- a/server/src/main/java/org/eclipse/openvsx/extension_control/ExtensionControlService.java
+++ b/server/src/main/java/org/eclipse/openvsx/extension_control/ExtensionControlService.java
@@ -34,6 +34,8 @@
import org.eclipse.openvsx.cache.CacheService;
import org.eclipse.openvsx.entities.UserData;
import org.eclipse.openvsx.migration.HandlerJobRequest;
+import org.eclipse.openvsx.migration.MigrationsProperties;
+import org.eclipse.openvsx.mirror.MirrorConfig;
import org.eclipse.openvsx.repositories.RepositoryService;
import org.eclipse.openvsx.search.SearchUtilService;
import org.eclipse.openvsx.util.ExtensionId;
@@ -52,9 +54,8 @@ public class ExtensionControlService {
private final EntityManager entityManager;
private final SearchUtilService search;
private final CacheService cache;
-
- @Value("${ovsx.data.mirror.enabled:false}")
- boolean mirrorEnabled;
+ private final MirrorConfig mirrorConfig;
+ private final MigrationsProperties migrationsProperties;
@Value("${ovsx.extension-control.enabled:true}")
boolean enabled;
@@ -65,31 +66,32 @@ public class ExtensionControlService {
@Value("${ovsx.extension-control.update-on-start:false}")
boolean updateOnStart;
- @Value("${ovsx.migrations.delay.seconds:0}")
- long delay;
-
public ExtensionControlService(
JobRequestScheduler scheduler,
RepositoryService repositories,
EntityManager entityManager,
SearchUtilService search,
- CacheService cache
+ CacheService cache,
+ MirrorConfig mirrorConfig,
+ MigrationsProperties migrationsProperties
) {
this.scheduler = scheduler;
this.repositories = repositories;
this.entityManager = entityManager;
this.search = search;
this.cache = cache;
+ this.mirrorConfig = mirrorConfig;
+ this.migrationsProperties = migrationsProperties;
}
@EventListener
public void applicationStarted(ApplicationStartedEvent event) {
- if (!enabled || mirrorEnabled) {
+ if (!enabled || mirrorConfig.isEnabled()) {
scheduler.deleteRecurringJob("UpdateExtensionControl");
} else {
if (updateOnStart) {
scheduler.schedule(
- TimeUtil.getCurrentUTC().plusSeconds(delay),
+ TimeUtil.getCurrentUTC().plusSeconds(migrationsProperties.getDelaySeconds()),
new HandlerJobRequest<>(ExtensionControlJobRequestHandler.class));
}
diff --git a/server/src/main/java/org/eclipse/openvsx/migration/GenerateKeyPairJobRequestHandler.java b/server/src/main/java/org/eclipse/openvsx/migration/GenerateKeyPairJobRequestHandler.java
index df6b00226..5a0d41592 100644
--- a/server/src/main/java/org/eclipse/openvsx/migration/GenerateKeyPairJobRequestHandler.java
+++ b/server/src/main/java/org/eclipse/openvsx/migration/GenerateKeyPairJobRequestHandler.java
@@ -17,7 +17,6 @@
import org.jobrunr.scheduling.JobRequestScheduler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.dao.DataAccessException;
import org.springframework.stereotype.Component;
@@ -25,6 +24,7 @@
import org.eclipse.openvsx.admin.RemoveFileJobRequest;
import org.eclipse.openvsx.entities.ExtensionVersion;
import org.eclipse.openvsx.entities.FileResource;
+import org.eclipse.openvsx.publish.ExtensionVersionIntegrityService;
import org.eclipse.openvsx.repositories.RepositoryService;
import static org.eclipse.openvsx.entities.FileResource.DOWNLOAD_SIG;
@@ -39,23 +39,24 @@ public class GenerateKeyPairJobRequestHandler implements JobRequestHandler jobRequest) throws Exception {
+ var keyPairMode = integrityService.getKeyPairMode();
logger.info("Starting signature key-pair generation in mode {}", keyPairMode);
switch (keyPairMode) {
diff --git a/server/src/main/java/org/eclipse/openvsx/migration/MigrationScheduler.java b/server/src/main/java/org/eclipse/openvsx/migration/MigrationScheduler.java
index 7e249b094..a86cc792a 100644
--- a/server/src/main/java/org/eclipse/openvsx/migration/MigrationScheduler.java
+++ b/server/src/main/java/org/eclipse/openvsx/migration/MigrationScheduler.java
@@ -17,6 +17,8 @@
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
+import org.eclipse.openvsx.mirror.MirrorConfig;
+
@Component
public class MigrationScheduler implements JobRequestHandler> {
@@ -26,9 +28,7 @@ public class MigrationScheduler implements JobRequestHandler jobRequest) throws Exception {
orphanNamespaceMigration.fixOrphanNamespaces();
- if (!mirrorEnabled) {
+ if (!mirrorConfig.isEnabled()) {
scheduler.enqueue(new HandlerJobRequest<>(GenerateKeyPairJobRequestHandler.class));
}
diff --git a/server/src/main/java/org/eclipse/openvsx/migration/MigrationsProperties.java b/server/src/main/java/org/eclipse/openvsx/migration/MigrationsProperties.java
new file mode 100644
index 000000000..8acb2b6a2
--- /dev/null
+++ b/server/src/main/java/org/eclipse/openvsx/migration/MigrationsProperties.java
@@ -0,0 +1,39 @@
+/********************************************************************************
+ * Copyright (c) 2026 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * https://www.eclipse.org/legal/epl-2.0
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ********************************************************************************/
+package org.eclipse.openvsx.migration;
+
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Component;
+
+/**
+ * {@code ovsx.migrations.delay.seconds} and {@code ovsx.registry.version}, previously declared
+ * independently in every startup job that delays itself behind the registry's own start-up
+ * (migrations, VS Code id daily update, extension control update).
+ */
+@Component
+public class MigrationsProperties {
+
+ @Value("${ovsx.migrations.delay.seconds:0}")
+ private long delaySeconds;
+
+ @Value("${ovsx.registry.version:}")
+ private String registryVersion;
+
+ public long getDelaySeconds() {
+ return delaySeconds;
+ }
+
+ public String getRegistryVersion() {
+ return registryVersion;
+ }
+}
diff --git a/server/src/main/java/org/eclipse/openvsx/migration/ScheduleMigrationsListener.java b/server/src/main/java/org/eclipse/openvsx/migration/ScheduleMigrationsListener.java
index 26147267d..a71254c85 100644
--- a/server/src/main/java/org/eclipse/openvsx/migration/ScheduleMigrationsListener.java
+++ b/server/src/main/java/org/eclipse/openvsx/migration/ScheduleMigrationsListener.java
@@ -26,32 +26,32 @@
public class ScheduleMigrationsListener {
protected final Logger logger = LoggerFactory.getLogger(ScheduleMigrationsListener.class);
- @Value("${ovsx.migrations.delay.seconds:0}")
- long delay;
-
@Value("${ovsx.migrations.once-per-version:false}")
boolean runMigrationsOncePerVersion;
- @Value("${ovsx.registry.version:}")
- String registryVersion;
-
private final JobRequestScheduler scheduler;
private final UUIDService uuidService;
+ private final MigrationsProperties migrationsProperties;
- public ScheduleMigrationsListener(JobRequestScheduler scheduler, UUIDService uuidService) {
+ public ScheduleMigrationsListener(
+ JobRequestScheduler scheduler,
+ UUIDService uuidService,
+ MigrationsProperties migrationsProperties
+ ) {
this.scheduler = scheduler;
this.uuidService = uuidService;
+ this.migrationsProperties = migrationsProperties;
}
@EventListener
public void applicationStarted(ApplicationStartedEvent event) {
UUID jobId = null;
if (runMigrationsOncePerVersion) {
- var jobIdText = "MigrationScheduler::" + registryVersion;
+ var jobIdText = "MigrationScheduler::" + migrationsProperties.getRegistryVersion();
jobId = uuidService.generateFromName(jobIdText);
}
- var instant = Instant.now().plusSeconds(delay);
+ var instant = Instant.now().plusSeconds(migrationsProperties.getDelaySeconds());
scheduler.schedule(jobId, instant, new HandlerJobRequest<>(MigrationScheduler.class));
}
}
diff --git a/server/src/main/java/org/eclipse/openvsx/mirror/MirrorConfig.java b/server/src/main/java/org/eclipse/openvsx/mirror/MirrorConfig.java
index 22b77161d..fdfbb7da6 100644
--- a/server/src/main/java/org/eclipse/openvsx/mirror/MirrorConfig.java
+++ b/server/src/main/java/org/eclipse/openvsx/mirror/MirrorConfig.java
@@ -12,6 +12,7 @@
import java.util.HashSet;
import java.util.Set;
+import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@@ -19,6 +20,13 @@
@Configuration
public class MirrorConfig {
+ @Value("${ovsx.data.mirror.enabled:false}")
+ private boolean enabled;
+
+ public boolean isEnabled() {
+ return enabled;
+ }
+
@Bean
@ConfigurationProperties(prefix = "ovsx.data.mirror.exclude-extensions")
public Set excludeExtensions() {
diff --git a/server/src/main/java/org/eclipse/openvsx/publish/ExtensionVersionIntegrityService.java b/server/src/main/java/org/eclipse/openvsx/publish/ExtensionVersionIntegrityService.java
index 3d0c3fea8..5d91b77e5 100644
--- a/server/src/main/java/org/eclipse/openvsx/publish/ExtensionVersionIntegrityService.java
+++ b/server/src/main/java/org/eclipse/openvsx/publish/ExtensionVersionIntegrityService.java
@@ -65,6 +65,10 @@ public boolean isEnabled() {
return keyPairMode.equals(KEYPAIR_MODE_CREATE) || keyPairMode.equals(KEYPAIR_MODE_RENEW);
}
+ public String getKeyPairMode() {
+ return keyPairMode;
+ }
+
public boolean verifyExtensionVersion(TempFile extensionFile, TempFile signatureFile, TempFile publicKeyFile) {
AsymmetricKeyParameter publicKeyParameters;
try (var inReader = new InputStreamReader(Files.newInputStream(publicKeyFile.getPath()))) {
diff --git a/server/src/main/java/org/eclipse/openvsx/security/SecurityConfig.java b/server/src/main/java/org/eclipse/openvsx/security/SecurityConfig.java
index 34aab3b11..cded40a82 100644
--- a/server/src/main/java/org/eclipse/openvsx/security/SecurityConfig.java
+++ b/server/src/main/java/org/eclipse/openvsx/security/SecurityConfig.java
@@ -20,21 +20,21 @@
import org.springframework.security.web.servlet.util.matcher.PathPatternRequestMatcher;
import org.springframework.security.web.util.matcher.RequestMatcher;
+import org.eclipse.openvsx.web.WebUiProperties;
+
@Configuration
@EnableWebSecurity
public class SecurityConfig {
- @Value("${ovsx.webui.url:}")
- String webuiUrl;
-
- @Value(
- "${ovsx.webui.frontendRoutes:/extension/**,/namespace/**,/search,/user-settings/**,/publish,/admin-dashboard/**}"
- )
- String[] frontendRoutes;
+ private final WebUiProperties webUi;
@Value("${ovsx.webui.additional-routes:}")
String[] additionalRoutes;
+ public SecurityConfig(WebUiProperties webUi) {
+ this.webUi = webUi;
+ }
+
@Bean
public SecurityFilterChain filterChain(HttpSecurity http, OAuth2UserServices userServices) throws Exception {
var filterChain = http.authorizeHttpRequests(
@@ -74,7 +74,7 @@ public SecurityFilterChain filterChain(HttpSecurity http, OAuth2UserServices use
.permitAll()
.requestMatchers(pathMatchers("/admin/**"))
.hasAuthority("ROLE_ADMIN")
- .requestMatchers(pathMatchers(frontendRoutes))
+ .requestMatchers(pathMatchers(webUi.getFrontendRoutes()))
.permitAll()
.requestMatchers(pathMatchers(additionalRoutes))
.permitAll()
@@ -95,6 +95,7 @@ public SecurityFilterChain filterChain(HttpSecurity http, OAuth2UserServices use
.exceptionHandling(configurer -> configurer.authenticationEntryPoint(new Http403ForbiddenEntryPoint()));
if (userServices.canLogin()) {
+ var webuiUrl = webUi.getUrl();
var redirectUrl = StringUtils.isEmpty(webuiUrl) ? "/" : webuiUrl;
filterChain.oauth2Login(configurer -> {
configurer.defaultSuccessUrl(redirectUrl);
diff --git a/server/src/main/java/org/eclipse/openvsx/storage/AzureBlobStorageService.java b/server/src/main/java/org/eclipse/openvsx/storage/AzureBlobStorageService.java
index 3479ccd95..a7e370427 100644
--- a/server/src/main/java/org/eclipse/openvsx/storage/AzureBlobStorageService.java
+++ b/server/src/main/java/org/eclipse/openvsx/storage/AzureBlobStorageService.java
@@ -70,6 +70,14 @@ public boolean isEnabled() {
return !StringUtils.isEmpty(serviceEndpoint);
}
+ public String getServiceEndpoint() {
+ return serviceEndpoint;
+ }
+
+ public String getBlobContainer() {
+ return blobContainer;
+ }
+
protected BlobContainerClient getContainerClient() {
if (containerClient == null) {
containerClient = new BlobContainerClientBuilder()
diff --git a/server/src/main/java/org/eclipse/openvsx/storage/log/AzureDownloadCountHandler.java b/server/src/main/java/org/eclipse/openvsx/storage/log/AzureDownloadCountHandler.java
index bc6e989d6..66760ef6f 100644
--- a/server/src/main/java/org/eclipse/openvsx/storage/log/AzureDownloadCountHandler.java
+++ b/server/src/main/java/org/eclipse/openvsx/storage/log/AzureDownloadCountHandler.java
@@ -45,6 +45,7 @@
import org.eclipse.openvsx.entities.FileResource;
import org.eclipse.openvsx.migration.HandlerJobRequest;
import org.eclipse.openvsx.settings.SettingsService;
+import org.eclipse.openvsx.storage.AzureBlobStorageService;
import org.eclipse.openvsx.util.TempFile;
import static org.eclipse.openvsx.storage.AzureBlobStorageService.AZURE_USER_AGENT;
@@ -61,6 +62,7 @@ public class AzureDownloadCountHandler implements JobRequestHandler processBlobItem(String blobName) throws IOException
if (isGetBlobOperation(node) && isStatusOk(node) && isExtensionPackageUri(node)
&& isNotOpenVSXUserAgent(node)) {
var uri = node.get("uri").asString();
- pathParams = uri.substring(storageServiceEndpoint.length()).split("/");
+ pathParams = uri.substring(storageService.getServiceEndpoint().length()).split("/");
}
- if (pathParams != null && storageBlobContainer.equals(pathParams[1])) {
+ if (pathParams != null && storageService.getBlobContainer().equals(pathParams[1])) {
var fileName = UriUtils.decode(pathParams[pathParams.length - 1], StandardCharsets.UTF_8)
.toUpperCase();
fileCounts.merge(fileName, 1, Integer::sum);
@@ -305,7 +306,7 @@ private boolean isCorrectName(String name) {
private Pattern getBlobItemNamePattern() {
if (blobItemNamePattern == null) {
- var host = URI.create(storageServiceEndpoint).getHost();
+ var host = URI.create(storageService.getServiceEndpoint()).getHost();
var storageAccount = host.substring(0, host.indexOf('.'));
var regex = "^resourceId=/subscriptions/.*/resourceGroups/.*/providers/Microsoft\\.Storage/storageAccounts/"
diff --git a/server/src/main/java/org/eclipse/openvsx/web/ServerErrorController.java b/server/src/main/java/org/eclipse/openvsx/web/ServerErrorController.java
index b11550292..301575e26 100644
--- a/server/src/main/java/org/eclipse/openvsx/web/ServerErrorController.java
+++ b/server/src/main/java/org/eclipse/openvsx/web/ServerErrorController.java
@@ -11,7 +11,6 @@
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
-import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.web.WebProperties;
import org.springframework.boot.webmvc.autoconfigure.error.BasicErrorController;
@@ -28,11 +27,11 @@
@ConditionalOnProperty(value = "spring.web.error.path", havingValue = "/server-error")
public class ServerErrorController extends BasicErrorController {
- @Value("${ovsx.webui.url:}")
- String webuiUrl;
+ private final WebUiProperties webUi;
- public ServerErrorController(ErrorAttributes errorAttributes, WebProperties webProperties) {
+ public ServerErrorController(ErrorAttributes errorAttributes, WebProperties webProperties, WebUiProperties webUi) {
super(errorAttributes, webProperties.getError());
+ this.webUi = webUi;
}
// Override errorHtml() itself rather than adding a new method with its own explicit
@@ -43,6 +42,6 @@ public ServerErrorController(ErrorAttributes errorAttributes, WebProperties webP
// the correct, property-driven path with no combination/doubling.
@Override
public ModelAndView errorHtml(HttpServletRequest request, HttpServletResponse response) {
- return new ModelAndView("redirect:" + UrlUtil.createApiUrl(webuiUrl, "error"));
+ return new ModelAndView("redirect:" + UrlUtil.createApiUrl(webUi.getUrl(), "error"));
}
}
diff --git a/server/src/main/java/org/eclipse/openvsx/web/SitemapService.java b/server/src/main/java/org/eclipse/openvsx/web/SitemapService.java
index 65fcc54a1..2a9f8787b 100644
--- a/server/src/main/java/org/eclipse/openvsx/web/SitemapService.java
+++ b/server/src/main/java/org/eclipse/openvsx/web/SitemapService.java
@@ -22,7 +22,6 @@
import javax.xml.transform.stream.StreamResult;
import org.apache.commons.lang3.StringUtils;
-import org.springframework.beans.factory.annotation.Value;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Component;
@@ -35,12 +34,11 @@
public class SitemapService {
private final RepositoryService repositories;
+ private final WebUiProperties webUi;
- @Value("${ovsx.webui.url:}")
- String webuiUrl;
-
- public SitemapService(RepositoryService repositories) {
+ public SitemapService(RepositoryService repositories, WebUiProperties webUi) {
this.repositories = repositories;
+ this.webUi = webUi;
}
@Cacheable(CACHE_SITEMAP)
@@ -78,6 +76,7 @@ public String generateSitemap() throws ParserConfigurationException, IOException
}
private String getBaseUrl() {
+ var webuiUrl = webUi.getUrl();
String url;
if (StringUtils.isEmpty(webuiUrl)) {
url = UrlUtil.getBaseUrl();
diff --git a/server/src/main/java/org/eclipse/openvsx/web/WebConfig.java b/server/src/main/java/org/eclipse/openvsx/web/WebConfig.java
index e405bb39b..2523fc578 100644
--- a/server/src/main/java/org/eclipse/openvsx/web/WebConfig.java
+++ b/server/src/main/java/org/eclipse/openvsx/web/WebConfig.java
@@ -13,7 +13,6 @@
import java.util.Optional;
import org.apache.commons.lang3.StringUtils;
-import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
@@ -25,22 +24,21 @@
@Configuration
public class WebConfig implements WebMvcConfigurer {
- private MirrorExtensionHandlerInterceptor mirrorInterceptor;
-
- @Value("${ovsx.webui.url:}")
- String webuiUrl;
+ private final WebUiProperties webUi;
- @Value(
- "${ovsx.webui.frontendRoutes:/extension/**,/namespace/**,/search,/user-settings/**,/publish,/admin-dashboard/**}"
- )
- String[] frontendRoutes;
+ private MirrorExtensionHandlerInterceptor mirrorInterceptor;
- public WebConfig(Optional mirrorExtensionHandlerInterceptor) {
+ public WebConfig(
+ WebUiProperties webUi,
+ Optional mirrorExtensionHandlerInterceptor
+ ) {
+ this.webUi = webUi;
mirrorExtensionHandlerInterceptor.ifPresent(service -> this.mirrorInterceptor = service);
}
@Override
public void addCorsMappings(CorsRegistry registry) {
+ var webuiUrl = webUi.getUrl();
if (!StringUtils.isEmpty(webuiUrl) && URI.create(webuiUrl).isAbsolute()) {
// The Web UI is given with an absolute URL, so we need to enable CORS with credentials.
var authorizedEndpoints = new String[] {
@@ -71,7 +69,7 @@ public void addCorsMappings(CorsRegistry registry) {
@Override
public void addViewControllers(ViewControllerRegistry registry) {
- for (var route : frontendRoutes) {
+ for (var route : webUi.getFrontendRoutes()) {
registry.addViewController(route).setViewName("forward:/index.html");
}
}
diff --git a/server/src/main/java/org/eclipse/openvsx/web/WebUiProperties.java b/server/src/main/java/org/eclipse/openvsx/web/WebUiProperties.java
new file mode 100644
index 000000000..bac19d0ec
--- /dev/null
+++ b/server/src/main/java/org/eclipse/openvsx/web/WebUiProperties.java
@@ -0,0 +1,40 @@
+/********************************************************************************
+ * Copyright (c) 2026 Contributors to the Eclipse Foundation
+ *
+ * See the NOTICE file(s) distributed with this work for additional
+ * information regarding copyright ownership.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License 2.0 which is available at
+ * https://www.eclipse.org/legal/epl-2.0
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ ********************************************************************************/
+package org.eclipse.openvsx.web;
+
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Component;
+
+/**
+ * The web UI's own URL and the frontend routes it serves, previously declared independently
+ * (and identically) in both {@link WebConfig} and {@code SecurityConfig}.
+ */
+@Component
+public class WebUiProperties {
+
+ @Value("${ovsx.webui.url:}")
+ private String url;
+
+ @Value(
+ "${ovsx.webui.frontendRoutes:/extension/**,/namespace/**,/search,/user-settings/**,/publish,/admin-dashboard/**}"
+ )
+ private String[] frontendRoutes;
+
+ public String getUrl() {
+ return url;
+ }
+
+ public String[] getFrontendRoutes() {
+ return frontendRoutes;
+ }
+}
diff --git a/server/src/test/java/org/eclipse/openvsx/LocalRegistryServiceTest.java b/server/src/test/java/org/eclipse/openvsx/LocalRegistryServiceTest.java
index 6044c5835..76b06555f 100644
--- a/server/src/test/java/org/eclipse/openvsx/LocalRegistryServiceTest.java
+++ b/server/src/test/java/org/eclipse/openvsx/LocalRegistryServiceTest.java
@@ -44,6 +44,7 @@
import org.eclipse.openvsx.entities.PersonalAccessTokenType;
import org.eclipse.openvsx.entities.UserData;
import org.eclipse.openvsx.json.NamespaceJson;
+import org.eclipse.openvsx.migration.MigrationsProperties;
import org.eclipse.openvsx.publish.ExtensionVersionIntegrityService;
import org.eclipse.openvsx.publish.PublishingConfig;
import org.eclipse.openvsx.repositories.RepositoryService;
@@ -55,6 +56,7 @@
import org.eclipse.openvsx.util.TempFile;
import org.eclipse.openvsx.util.VersionService;
import org.eclipse.openvsx.util.auth.AccessTokenAuthentication;
+import org.eclipse.openvsx.web.WebUiProperties;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
@@ -129,6 +131,8 @@ void setUp() {
similarityCheckService,
new PublishingConfig(),
new TrustedPublishingConfig(),
+ new MigrationsProperties(),
+ new WebUiProperties(),
Duration.ofSeconds(30));
// A permissive default for a void method rather than a per-test expectation: the tests of
diff --git a/server/src/test/java/org/eclipse/openvsx/RegistryAPITest.java b/server/src/test/java/org/eclipse/openvsx/RegistryAPITest.java
index e4f68bea6..4e42ff913 100644
--- a/server/src/test/java/org/eclipse/openvsx/RegistryAPITest.java
+++ b/server/src/test/java/org/eclipse/openvsx/RegistryAPITest.java
@@ -66,6 +66,8 @@
import org.eclipse.openvsx.json.*;
import org.eclipse.openvsx.mail.MailService;
import org.eclipse.openvsx.metrics.ExtensionDownloadMetrics;
+import org.eclipse.openvsx.migration.MigrationsProperties;
+import org.eclipse.openvsx.mirror.MirrorConfig;
import org.eclipse.openvsx.publish.ExtensionVersionIntegrityService;
import org.eclipse.openvsx.publish.PublishExtensionVersionHandler;
import org.eclipse.openvsx.publish.PublishExtensionVersionService;
@@ -90,6 +92,7 @@
import org.eclipse.openvsx.util.UUIDService;
import org.eclipse.openvsx.util.VersionAlias;
import org.eclipse.openvsx.util.VersionService;
+import org.eclipse.openvsx.web.WebUiProperties;
import static org.assertj.core.api.Assertions.assertThat;
import static org.eclipse.openvsx.entities.FileResource.*;
@@ -3639,7 +3642,7 @@ private byte[] createExtensionPackageWithCollidingReadme(String name, String ver
}
@TestConfiguration
- @Import({ SecurityConfig.class, MockMvcAsyncConfig.class })
+ @Import({ SecurityConfig.class, MockMvcAsyncConfig.class, WebUiProperties.class })
static class TestConfig {
@Bean
TransactionTemplate transactionTemplate() {
@@ -3673,7 +3676,7 @@ UUIDService uuidService() {
@Bean
AccessTokenConfig tokenConfig() {
- return new AccessTokenConfig();
+ return new AccessTokenConfig(new MirrorConfig());
}
@Bean
@@ -3741,6 +3744,8 @@ LocalRegistryService localRegistryService(
similarityCheckService,
publishingConfig,
trustedPublishingConfig,
+ new MigrationsProperties(),
+ new WebUiProperties(),
CHANGES_FEED_LAG);
}
diff --git a/server/src/test/java/org/eclipse/openvsx/UserAPITest.java b/server/src/test/java/org/eclipse/openvsx/UserAPITest.java
index 185700a26..735285b3e 100644
--- a/server/src/test/java/org/eclipse/openvsx/UserAPITest.java
+++ b/server/src/test/java/org/eclipse/openvsx/UserAPITest.java
@@ -49,6 +49,8 @@
import org.eclipse.openvsx.entities.*;
import org.eclipse.openvsx.json.*;
import org.eclipse.openvsx.mail.MailService;
+import org.eclipse.openvsx.migration.MigrationsProperties;
+import org.eclipse.openvsx.mirror.MirrorConfig;
import org.eclipse.openvsx.publish.ExtensionVersionIntegrityService;
import org.eclipse.openvsx.publish.PublishExtensionVersionHandler;
import org.eclipse.openvsx.publish.PublishingConfig;
@@ -70,6 +72,7 @@
import org.eclipse.openvsx.util.TargetPlatformVersion;
import org.eclipse.openvsx.util.UUIDService;
import org.eclipse.openvsx.util.VersionService;
+import org.eclipse.openvsx.web.WebUiProperties;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
@@ -1154,7 +1157,7 @@ public Boolean answer(InvocationOnMock invocation) {
}
@TestConfiguration
- @Import(SecurityConfig.class)
+ @Import({ SecurityConfig.class, WebUiProperties.class })
static class TestConfig {
@Bean
TransactionTemplate transactionTemplate() {
@@ -1188,7 +1191,7 @@ UUIDService uuidService() {
@Bean
AccessTokenConfig tokenConfig() {
- return new AccessTokenConfig();
+ return new AccessTokenConfig(new MirrorConfig());
}
@Bean
@@ -1259,6 +1262,8 @@ LocalRegistryService localRegistryService(
similarityCheckService,
new PublishingConfig(),
new TrustedPublishingConfig(),
+ new MigrationsProperties(),
+ new WebUiProperties(),
Duration.ofSeconds(30));
}
diff --git a/server/src/test/java/org/eclipse/openvsx/adapter/LocalVSCodeServiceTest.java b/server/src/test/java/org/eclipse/openvsx/adapter/LocalVSCodeServiceTest.java
index 8ffe03717..83ad940d5 100644
--- a/server/src/test/java/org/eclipse/openvsx/adapter/LocalVSCodeServiceTest.java
+++ b/server/src/test/java/org/eclipse/openvsx/adapter/LocalVSCodeServiceTest.java
@@ -20,6 +20,7 @@
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.TestConfiguration;
import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Import;
import org.springframework.test.context.bean.override.mockito.MockitoBean;
import org.springframework.test.context.junit.jupiter.SpringExtension;
@@ -33,6 +34,7 @@
import org.eclipse.openvsx.search.SearchUtilService;
import org.eclipse.openvsx.storage.*;
import org.eclipse.openvsx.util.VersionService;
+import org.eclipse.openvsx.web.WebUiProperties;
import static org.assertj.core.api.Assertions.assertThat;
import static org.eclipse.openvsx.adapter.ExtensionQueryParam.*;
@@ -126,6 +128,7 @@ private ExtensionVersion mockExtensionVersion(Extension extension, long id, Stri
}
@TestConfiguration
+ @Import(WebUiProperties.class)
static class TestConfig {
@Bean
LocalVSCodeService vsCodeService(
@@ -135,7 +138,8 @@ LocalVSCodeService vsCodeService(
StorageUtilService storageUtil,
ExtensionVersionIntegrityService integrityService,
WebResourceService webResources,
- CacheService cache
+ CacheService cache,
+ WebUiProperties webUi
) {
return new LocalVSCodeService(
repositories,
@@ -144,7 +148,8 @@ LocalVSCodeService vsCodeService(
storageUtil,
integrityService,
webResources,
- cache);
+ cache,
+ webUi);
}
}
diff --git a/server/src/test/java/org/eclipse/openvsx/adapter/VSCodeAPITest.java b/server/src/test/java/org/eclipse/openvsx/adapter/VSCodeAPITest.java
index 448644a7a..1afdd20b2 100644
--- a/server/src/test/java/org/eclipse/openvsx/adapter/VSCodeAPITest.java
+++ b/server/src/test/java/org/eclipse/openvsx/adapter/VSCodeAPITest.java
@@ -63,6 +63,7 @@
import org.eclipse.openvsx.util.TargetPlatform;
import org.eclipse.openvsx.util.VersionService;
import org.eclipse.openvsx.web.JacksonConfig;
+import org.eclipse.openvsx.web.WebUiProperties;
import static org.assertj.core.api.Assertions.assertThat;
import static org.eclipse.openvsx.entities.FileResource.*;
@@ -1436,7 +1437,7 @@ private Path mockExtensionBrowse(
}
@TestConfiguration
- @Import({ SecurityConfig.class, MockMvcAsyncConfig.class, JacksonConfig.class })
+ @Import({ SecurityConfig.class, MockMvcAsyncConfig.class, JacksonConfig.class, WebUiProperties.class })
static class TestConfig {
@Bean
IExtensionQueryRequestHandler extensionQueryRequestHandler(
@@ -1489,7 +1490,8 @@ LocalVSCodeService localVSCodeService(
StorageUtilService storageUtil,
ExtensionVersionIntegrityService integrityService,
WebResourceService webResourceService,
- CacheService cache
+ CacheService cache,
+ WebUiProperties webUi
) {
return new LocalVSCodeService(
repositories,
@@ -1498,7 +1500,8 @@ LocalVSCodeService localVSCodeService(
storageUtil,
integrityService,
webResourceService,
- cache);
+ cache,
+ webUi);
}
@Bean
diff --git a/server/src/test/java/org/eclipse/openvsx/admin/AdminAPITest.java b/server/src/test/java/org/eclipse/openvsx/admin/AdminAPITest.java
index 6fe026925..495afceb5 100644
--- a/server/src/test/java/org/eclipse/openvsx/admin/AdminAPITest.java
+++ b/server/src/test/java/org/eclipse/openvsx/admin/AdminAPITest.java
@@ -80,6 +80,8 @@
import org.eclipse.openvsx.json.UserPublishInfoJson;
import org.eclipse.openvsx.mail.MailService;
import org.eclipse.openvsx.metrics.ExtensionDownloadMetrics;
+import org.eclipse.openvsx.migration.MigrationsProperties;
+import org.eclipse.openvsx.mirror.MirrorConfig;
import org.eclipse.openvsx.publish.ExtensionVersionIntegrityService;
import org.eclipse.openvsx.publish.PublishExtensionVersionHandler;
import org.eclipse.openvsx.publish.PublishingConfig;
@@ -110,6 +112,7 @@
import org.eclipse.openvsx.util.TargetPlatformVersion;
import org.eclipse.openvsx.util.UUIDService;
import org.eclipse.openvsx.util.VersionService;
+import org.eclipse.openvsx.web.WebUiProperties;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.ArgumentMatchers.any;
@@ -2612,7 +2615,7 @@ private String errorJson(String message) throws JacksonException {
}
@TestConfiguration
- @Import(SecurityConfig.class)
+ @Import({ SecurityConfig.class, WebUiProperties.class })
static class TestConfig {
@Bean
TransactionTemplate transactionTemplate() {
@@ -2646,7 +2649,7 @@ UUIDService uuidService() {
@Bean
AccessTokenConfig tokenConfig() {
- return new AccessTokenConfig();
+ return new AccessTokenConfig(new MirrorConfig());
}
@Bean
@@ -2744,6 +2747,8 @@ LocalRegistryService localRegistryService(
similarityCheckService,
new PublishingConfig(),
new TrustedPublishingConfig(),
+ new MigrationsProperties(),
+ new WebUiProperties(),
Duration.ofSeconds(30));
}
diff --git a/server/src/test/java/org/eclipse/openvsx/admin/ConsistencyAPITest.java b/server/src/test/java/org/eclipse/openvsx/admin/ConsistencyAPITest.java
index 4e249e62c..3ff9cdec7 100644
--- a/server/src/test/java/org/eclipse/openvsx/admin/ConsistencyAPITest.java
+++ b/server/src/test/java/org/eclipse/openvsx/admin/ConsistencyAPITest.java
@@ -20,6 +20,7 @@
import org.springframework.boot.security.oauth2.client.autoconfigure.servlet.OAuth2ClientWebSecurityAutoConfiguration;
import org.springframework.boot.webmvc.test.autoconfigure.AutoConfigureMockMvc;
import org.springframework.boot.webmvc.test.autoconfigure.WebMvcTest;
+import org.springframework.context.annotation.Import;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.test.context.bean.override.mockito.MockitoBean;
@@ -31,6 +32,7 @@
import org.eclipse.openvsx.entities.UserData;
import org.eclipse.openvsx.util.ErrorResultException;
import org.eclipse.openvsx.util.NotFoundException;
+import org.eclipse.openvsx.web.WebUiProperties;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.*;
@@ -43,6 +45,7 @@
excludeAutoConfiguration = { OAuth2ClientWebSecurityAutoConfiguration.class }
)
@AutoConfigureMockMvc(addFilters = false)
+@Import(WebUiProperties.class)
class ConsistencyAPITest {
@Autowired
diff --git a/server/src/test/java/org/eclipse/openvsx/admin/FileDecisionAPITest.java b/server/src/test/java/org/eclipse/openvsx/admin/FileDecisionAPITest.java
index 029215fe7..2dd051182 100644
--- a/server/src/test/java/org/eclipse/openvsx/admin/FileDecisionAPITest.java
+++ b/server/src/test/java/org/eclipse/openvsx/admin/FileDecisionAPITest.java
@@ -18,11 +18,13 @@
import org.springframework.boot.security.oauth2.client.autoconfigure.servlet.OAuth2ClientWebSecurityAutoConfiguration;
import org.springframework.boot.webmvc.test.autoconfigure.AutoConfigureMockMvc;
import org.springframework.boot.webmvc.test.autoconfigure.WebMvcTest;
+import org.springframework.context.annotation.Import;
import org.springframework.http.MediaType;
import org.springframework.test.context.bean.override.mockito.MockitoBean;
import org.springframework.test.web.servlet.MockMvc;
import org.eclipse.openvsx.repositories.RepositoryService;
+import org.eclipse.openvsx.web.WebUiProperties;
import static org.mockito.Mockito.*;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
@@ -33,6 +35,7 @@
excludeAutoConfiguration = { OAuth2ClientWebSecurityAutoConfiguration.class }
)
@AutoConfigureMockMvc(addFilters = false)
+@Import(WebUiProperties.class)
class FileDecisionAPITest {
@Autowired
diff --git a/server/src/test/java/org/eclipse/openvsx/admin/ScanAPITest.java b/server/src/test/java/org/eclipse/openvsx/admin/ScanAPITest.java
index 650374781..375d81699 100644
--- a/server/src/test/java/org/eclipse/openvsx/admin/ScanAPITest.java
+++ b/server/src/test/java/org/eclipse/openvsx/admin/ScanAPITest.java
@@ -22,6 +22,7 @@
import org.springframework.boot.security.oauth2.client.autoconfigure.servlet.OAuth2ClientWebSecurityAutoConfiguration;
import org.springframework.boot.webmvc.test.autoconfigure.AutoConfigureMockMvc;
import org.springframework.boot.webmvc.test.autoconfigure.WebMvcTest;
+import org.springframework.context.annotation.Import;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.util.Streamable;
@@ -39,6 +40,7 @@
import org.eclipse.openvsx.storage.StorageUtilService;
import org.eclipse.openvsx.util.ErrorResultException;
import org.eclipse.openvsx.util.LogService;
+import org.eclipse.openvsx.web.WebUiProperties;
import static org.mockito.Mockito.*;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
@@ -49,6 +51,7 @@
@WebMvcTest(value = ScanAPI.class, excludeAutoConfiguration = { OAuth2ClientWebSecurityAutoConfiguration.class })
@AutoConfigureMockMvc(addFilters = false)
+@Import(WebUiProperties.class)
class ScanAPITest {
@Autowired
diff --git a/server/src/test/java/org/eclipse/openvsx/migration/MigrationSchedulerTest.java b/server/src/test/java/org/eclipse/openvsx/migration/MigrationSchedulerTest.java
index 7b625e3a8..c6cfa4b2f 100644
--- a/server/src/test/java/org/eclipse/openvsx/migration/MigrationSchedulerTest.java
+++ b/server/src/test/java/org/eclipse/openvsx/migration/MigrationSchedulerTest.java
@@ -7,6 +7,8 @@
import org.mockito.junit.jupiter.MockitoExtension;
import org.springframework.test.util.ReflectionTestUtils;
+import org.eclipse.openvsx.mirror.MirrorConfig;
+
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.verify;
@@ -21,9 +23,10 @@ class MigrationSchedulerTest {
@Test
void run_schedulesMigrationItemProcessingUsingTheConfiguredCron() throws Exception {
- var migrationScheduler = new MigrationScheduler(orphanNamespaceMigration, scheduler);
+ var mirrorConfig = new MirrorConfig();
+ ReflectionTestUtils.setField(mirrorConfig, "enabled", true);
+ var migrationScheduler = new MigrationScheduler(orphanNamespaceMigration, scheduler, mirrorConfig);
ReflectionTestUtils.setField(migrationScheduler, "migrationItemsCron", "0 * * * *");
- ReflectionTestUtils.setField(migrationScheduler, "mirrorEnabled", true);
migrationScheduler.run(new HandlerJobRequest<>(MigrationScheduler.class));
diff --git a/server/src/test/java/org/eclipse/openvsx/trustedpublishing/TrustedPublishingAPITest.java b/server/src/test/java/org/eclipse/openvsx/trustedpublishing/TrustedPublishingAPITest.java
index b326fcb23..8bc72e910 100644
--- a/server/src/test/java/org/eclipse/openvsx/trustedpublishing/TrustedPublishingAPITest.java
+++ b/server/src/test/java/org/eclipse/openvsx/trustedpublishing/TrustedPublishingAPITest.java
@@ -23,6 +23,7 @@
import org.springframework.boot.security.oauth2.client.autoconfigure.servlet.OAuth2ClientWebSecurityAutoConfiguration;
import org.springframework.boot.webmvc.test.autoconfigure.AutoConfigureMockMvc;
import org.springframework.boot.webmvc.test.autoconfigure.WebMvcTest;
+import org.springframework.context.annotation.Import;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.test.context.bean.override.mockito.MockitoBean;
@@ -42,6 +43,7 @@
import org.eclipse.openvsx.trustedpublishing.TrustedPublishingService.TrustedPublishers;
import org.eclipse.openvsx.util.ErrorResultException;
import org.eclipse.openvsx.util.NotFoundException;
+import org.eclipse.openvsx.web.WebUiProperties;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyString;
@@ -61,6 +63,7 @@
excludeAutoConfiguration = { OAuth2ClientWebSecurityAutoConfiguration.class }
)
@AutoConfigureMockMvc(addFilters = false)
+@Import(WebUiProperties.class)
class TrustedPublishingAPITest {
private static final String NAMESPACE = "foo";
diff --git a/server/src/test/java/org/eclipse/openvsx/web/ServerErrorControllerTest.java b/server/src/test/java/org/eclipse/openvsx/web/ServerErrorControllerTest.java
index dc60f052d..c05c4281d 100644
--- a/server/src/test/java/org/eclipse/openvsx/web/ServerErrorControllerTest.java
+++ b/server/src/test/java/org/eclipse/openvsx/web/ServerErrorControllerTest.java
@@ -18,6 +18,7 @@
import org.mockito.Mockito;
import org.springframework.boot.autoconfigure.web.WebProperties;
import org.springframework.boot.webmvc.error.ErrorAttributes;
+import org.springframework.test.util.ReflectionTestUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import static org.assertj.core.api.Assertions.assertThat;
@@ -45,10 +46,12 @@ void errorHtmlOverrideHasNoOwnRequestMappingPath() throws Exception {
@Test
void errorHtmlRedirectsToTheWebuiErrorPage() throws Exception {
+ var webUi = new WebUiProperties();
+ ReflectionTestUtils.setField(webUi, "url", "https://open-vsx.org");
var controller = new ServerErrorController(
Mockito.mock(ErrorAttributes.class),
- new WebProperties());
- controller.webuiUrl = "https://open-vsx.org";
+ new WebProperties(),
+ webUi);
var modelAndView = controller.errorHtml(
Mockito.mock(HttpServletRequest.class),
diff --git a/server/src/test/java/org/eclipse/openvsx/web/SitemapControllerTest.java b/server/src/test/java/org/eclipse/openvsx/web/SitemapControllerTest.java
index 93407b6d1..9cb09b0dd 100644
--- a/server/src/test/java/org/eclipse/openvsx/web/SitemapControllerTest.java
+++ b/server/src/test/java/org/eclipse/openvsx/web/SitemapControllerTest.java
@@ -73,7 +73,7 @@ void testSitemap() throws Exception {
}
@TestConfiguration
- @Import(SecurityConfig.class)
+ @Import({ SecurityConfig.class, WebUiProperties.class })
static class TestConfig {
@Bean
OAuth2UserServices oauth2UserServices(
@@ -87,8 +87,8 @@ OAuth2UserServices oauth2UserServices(
}
@Bean
- SitemapService sitemapService(RepositoryService repositories) {
- return new SitemapService(repositories);
+ SitemapService sitemapService(RepositoryService repositories, WebUiProperties webUi) {
+ return new SitemapService(repositories, webUi);
}
}
}