mirror of
https://github.com/imgfloat/server.git
synced 2026-02-05 11:49:25 +00:00
Improve settings
This commit is contained in:
@@ -29,13 +29,13 @@ public class SchemaMigration implements ApplicationRunner {
|
||||
}
|
||||
|
||||
private void cleanupSpringSessionTables() {
|
||||
try {
|
||||
jdbcTemplate.execute("DELETE FROM SPRING_SESSION_ATTRIBUTES");
|
||||
jdbcTemplate.execute("DELETE FROM SPRING_SESSION");
|
||||
logger.info("Cleared persisted Spring Session tables on startup to avoid stale session conflicts");
|
||||
} catch (DataAccessException ex) {
|
||||
logger.debug("Spring Session tables not available for cleanup", ex);
|
||||
}
|
||||
// try {
|
||||
// jdbcTemplate.execute("DELETE FROM SPRING_SESSION_ATTRIBUTES");
|
||||
// jdbcTemplate.execute("DELETE FROM SPRING_SESSION");
|
||||
// logger.info("Cleared persisted Spring Session tables on startup to avoid stale session conflicts");
|
||||
// } catch (DataAccessException ex) {
|
||||
// logger.debug("Spring Session tables not available for cleanup", ex);
|
||||
// }
|
||||
}
|
||||
|
||||
private void ensureChannelCanvasColumns() {
|
||||
|
||||
@@ -20,32 +20,31 @@ public class SecurityConfig {
|
||||
@Bean
|
||||
SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
|
||||
http
|
||||
.authorizeHttpRequests(auth -> auth
|
||||
.requestMatchers(
|
||||
"/",
|
||||
"/css/**",
|
||||
"/js/**",
|
||||
"/webjars/**",
|
||||
"/actuator/health",
|
||||
"/v3/api-docs/**",
|
||||
"/swagger-ui.html",
|
||||
"/swagger-ui/**",
|
||||
"/channels"
|
||||
).permitAll()
|
||||
.requestMatchers(HttpMethod.GET, "/view/*/broadcast").permitAll()
|
||||
.requestMatchers(HttpMethod.GET, "/api/channels").permitAll()
|
||||
.requestMatchers(HttpMethod.GET, "/api/channels/*/assets/visible").permitAll()
|
||||
.requestMatchers(HttpMethod.GET, "/api/channels/*/canvas").permitAll()
|
||||
.requestMatchers(HttpMethod.GET, "/api/channels/*/assets/*/content").permitAll()
|
||||
.requestMatchers("/ws/**").permitAll()
|
||||
.anyRequest().authenticated()
|
||||
)
|
||||
.oauth2Login(oauth -> oauth
|
||||
.tokenEndpoint(token -> token.accessTokenResponseClient(twitchAccessTokenResponseClient()))
|
||||
.userInfoEndpoint(user -> user.userService(twitchOAuth2UserService()))
|
||||
)
|
||||
.logout(logout -> logout.logoutSuccessUrl("/").permitAll())
|
||||
.csrf(csrf -> csrf.ignoringRequestMatchers("/ws/**", "/api/**"));
|
||||
.authorizeHttpRequests(auth -> auth
|
||||
.requestMatchers(
|
||||
"/",
|
||||
"/css/**",
|
||||
"/js/**",
|
||||
"/webjars/**",
|
||||
"/actuator/health",
|
||||
"/v3/api-docs/**",
|
||||
"/swagger-ui.html",
|
||||
"/swagger-ui/**",
|
||||
"/channels"
|
||||
).permitAll()
|
||||
.requestMatchers(HttpMethod.GET, "/view/*/broadcast").permitAll()
|
||||
.requestMatchers(HttpMethod.GET, "/api/channels").permitAll()
|
||||
.requestMatchers(HttpMethod.GET, "/api/channels/*/assets/visible").permitAll()
|
||||
.requestMatchers(HttpMethod.GET, "/api/channels/*/canvas").permitAll()
|
||||
.requestMatchers(HttpMethod.GET, "/api/channels/*/assets/*/content").permitAll()
|
||||
.requestMatchers("/ws/**").permitAll()
|
||||
.anyRequest().authenticated()
|
||||
)
|
||||
.oauth2Login(oauth -> oauth
|
||||
.tokenEndpoint(token -> token.accessTokenResponseClient(twitchAccessTokenResponseClient()))
|
||||
.userInfoEndpoint(user -> user.userService(twitchOAuth2UserService())))
|
||||
.logout(logout -> logout.logoutSuccessUrl("/").permitAll())
|
||||
.csrf(csrf -> csrf.ignoringRequestMatchers("/ws/**", "/api/**"));
|
||||
return http.build();
|
||||
}
|
||||
|
||||
|
||||
@@ -55,14 +55,11 @@ public class SystemEnvironmentValidator {
|
||||
);
|
||||
}
|
||||
|
||||
log.info("Environment validation successful.");
|
||||
log.info("Configuration:");
|
||||
log.info("Environment validation successful:");
|
||||
log.info(" - TWITCH_CLIENT_ID: {}", redact(twitchClientId));
|
||||
log.info(" - TWITCH_CLIENT_SECRET: {}", redact(twitchClientSecret));
|
||||
log.info(" - SPRING_SERVLET_MULTIPART_MAX_FILE_SIZE: {} ({} bytes)",
|
||||
springMaxFileSize, maxUploadBytes);
|
||||
log.info(" - SPRING_SERVLET_MULTIPART_MAX_REQUEST_SIZE: {} ({} bytes)",
|
||||
springMaxRequestSize, maxRequestBytes);
|
||||
log.info(" - SPRING_SERVLET_MULTIPART_MAX_FILE_SIZE: {} ({} bytes)", springMaxFileSize, maxUploadBytes);
|
||||
log.info(" - SPRING_SERVLET_MULTIPART_MAX_REQUEST_SIZE: {} ({} bytes)", springMaxRequestSize, maxRequestBytes);
|
||||
log.info(" - IMGFLOAT_DB_PATH: {}", dbPath);
|
||||
log.info(" - IMGFLOAT_INITIAL_TWITCH_USERNAME_SYSADMIN: {}", initialSysadmin);
|
||||
log.info(" - IMGFLOAT_ASSETS_PATH: {}", assetsPath);
|
||||
@@ -70,20 +67,23 @@ public class SystemEnvironmentValidator {
|
||||
}
|
||||
|
||||
private void checkString(String value, String name, StringBuilder missing) {
|
||||
if (!StringUtils.hasText(value) || "changeme".equalsIgnoreCase(value.trim())) {
|
||||
missing.append(" - ").append(name).append("\n");
|
||||
if (value != null && StringUtils.hasText(value)) {
|
||||
return
|
||||
}
|
||||
missing.append(" - ").append(name).append("\n");
|
||||
}
|
||||
|
||||
private <T extends Number> void checkUnsignedNumeric(T value, String name, StringBuilder missing) {
|
||||
if (value == null || value.doubleValue() <= 0) {
|
||||
missing.append(" - ").append(name).append('\n');
|
||||
if (value !== null && value.doubleValue() >= 0) {
|
||||
return;
|
||||
}
|
||||
missing.append(" - ").append(name).append('\n');
|
||||
}
|
||||
|
||||
private String redact(String value) {
|
||||
if (!StringUtils.hasText(value)) return "(missing)";
|
||||
if (value.length() <= 6) return "******";
|
||||
return value.substring(0, 2) + "****" + value.substring(value.length() - 2);
|
||||
if (value != null && StringUtils.hasText(value)) {
|
||||
return "**************";
|
||||
};
|
||||
return "<not set>";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,10 +41,11 @@ final class TwitchAuthorizationCodeGrantRequestEntityConverter implements
|
||||
}
|
||||
|
||||
return new RequestEntity<>(
|
||||
body,
|
||||
entity.getHeaders(),
|
||||
entity.getMethod() == null ? HttpMethod.POST : entity.getMethod(),
|
||||
entity.getUrl() == null ? URI.create(registration.getProviderDetails().getTokenUri()) : entity.getUrl());
|
||||
body,
|
||||
entity.getHeaders(),
|
||||
entity.getMethod() == null ? HttpMethod.POST : entity.getMethod(),
|
||||
entity.getUrl() == null ? URI.create(registration.getProviderDetails().getTokenUri()) : entity.getUrl()
|
||||
);
|
||||
}
|
||||
|
||||
private MultiValueMap<String, String> cloneBody(MultiValueMap<?, ?> existingBody) {
|
||||
|
||||
@@ -68,6 +68,21 @@ public class ViewController {
|
||||
return "channels";
|
||||
}
|
||||
|
||||
@org.springframework.web.bind.annotation.GetMapping("/settings")
|
||||
public String settingsView(OAuth2AuthenticationToken oauthToken, Model model) {
|
||||
String sessionUsername = OauthSessionUser.from(oauthToken).login();
|
||||
authorizationService.userIsSystemAdministratorOrThrowHttpError(sessionUsername);
|
||||
LOG.info("Rendering settings for {}", sessionUsername);
|
||||
Settings settings = settingsService.get();
|
||||
try {
|
||||
model.addAttribute("settingsJson", objectMapper.writeValueAsString(settings));
|
||||
} catch (JsonProcessingException e) {
|
||||
LOG.error("Failed to serialize settings for settings view", e);
|
||||
throw new ResponseStatusException(INTERNAL_SERVER_ERROR, "Failed to serialize settings");
|
||||
}
|
||||
return "settings";
|
||||
}
|
||||
|
||||
@org.springframework.web.bind.annotation.GetMapping("/view/{broadcaster}/admin")
|
||||
public String adminView(@org.springframework.web.bind.annotation.PathVariable("broadcaster") String broadcaster,
|
||||
OAuth2AuthenticationToken oauthToken,
|
||||
|
||||
@@ -16,15 +16,16 @@ import java.util.UUID;
|
||||
public class Asset {
|
||||
@Id
|
||||
private String id;
|
||||
|
||||
@Column(nullable = false)
|
||||
private String broadcaster;
|
||||
|
||||
@Column(nullable = false)
|
||||
private String name;
|
||||
|
||||
@Column(columnDefinition = "TEXT")
|
||||
@Column(columnDefinition = "TEXT", nullable = false)
|
||||
private String url;
|
||||
@Column(columnDefinition = "TEXT", nullable = false)
|
||||
private String preview;
|
||||
@Column(nullable = false)
|
||||
private Instant createdAt;
|
||||
private double x;
|
||||
private double y;
|
||||
private double width;
|
||||
@@ -34,8 +35,6 @@ public class Asset {
|
||||
private Boolean muted;
|
||||
private String mediaType;
|
||||
private String originalMediaType;
|
||||
@Column(columnDefinition = "TEXT")
|
||||
private String preview;
|
||||
private Integer zIndex;
|
||||
private Boolean audioLoop;
|
||||
private Integer audioDelayMillis;
|
||||
@@ -43,7 +42,6 @@ public class Asset {
|
||||
private Double audioPitch;
|
||||
private Double audioVolume;
|
||||
private boolean hidden;
|
||||
private Instant createdAt;
|
||||
|
||||
public Asset() {
|
||||
}
|
||||
@@ -61,7 +59,7 @@ public class Asset {
|
||||
this.speed = 1.0;
|
||||
this.muted = false;
|
||||
this.zIndex = 1;
|
||||
this.hidden = false;
|
||||
this.hidden = true;
|
||||
this.createdAt = Instant.now();
|
||||
}
|
||||
|
||||
|
||||
@@ -44,12 +44,13 @@ public class AssetEvent {
|
||||
return event;
|
||||
}
|
||||
|
||||
public static AssetEvent visibility(String channel, AssetPatch patch) {
|
||||
public static AssetEvent visibility(String channel, AssetPatch patch, AssetView asset) {
|
||||
AssetEvent event = new AssetEvent();
|
||||
event.type = Type.VISIBILITY;
|
||||
event.channel = channel;
|
||||
event.patch = patch;
|
||||
event.assetId = patch.id();
|
||||
event.payload = asset;
|
||||
return event;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user