remove hardcoded passwords

This commit is contained in:
Stefan Hardegger
2026-07-08 15:38:41 +02:00
parent fc26819a8f
commit 12d26611a1
3 changed files with 30 additions and 25 deletions

View File

@@ -2,10 +2,11 @@ package com.storycove;
import org.springframework.boot.SpringApplication; import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.security.servlet.UserDetailsServiceAutoConfiguration;
import org.springframework.scheduling.annotation.EnableAsync; import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.annotation.EnableScheduling; import org.springframework.scheduling.annotation.EnableScheduling;
@SpringBootApplication @SpringBootApplication(exclude = {UserDetailsServiceAutoConfiguration.class})
@EnableScheduling @EnableScheduling
@EnableAsync @EnableAsync
public class StoryCoveApplication { public class StoryCoveApplication {

View File

@@ -1,5 +1,6 @@
package com.storycove.config; package com.storycove.config;
import com.storycove.service.LibraryService;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
@@ -11,7 +12,6 @@ import org.springframework.stereotype.Component;
import javax.sql.DataSource; import javax.sql.DataSource;
import java.sql.Connection; import java.sql.Connection;
import java.sql.Statement; import java.sql.Statement;
import java.util.Arrays;
import java.util.List; import java.util.List;
/** /**
@@ -28,20 +28,15 @@ public class DatabaseMigrationRunner implements CommandLineRunner {
@Autowired @Autowired
private DataSource dataSource; private DataSource dataSource;
@Autowired
private LibraryService libraryService;
@Value("${spring.datasource.username}") @Value("${spring.datasource.username}")
private String dbUsername; private String dbUsername;
@Value("${spring.datasource.password}") @Value("${spring.datasource.password}")
private String dbPassword; private String dbPassword;
// List of all library databases that need migrations
private static final List<String> LIBRARY_DATABASES = Arrays.asList(
"storycove", // default database
"storycove_afterdark",
"storycove_clas",
"storycove_secret"
);
// SQL for last_completed_at column migration (idempotent) // SQL for last_completed_at column migration (idempotent)
private static final String LAST_COMPLETED_AT_MIGRATION = private static final String LAST_COMPLETED_AT_MIGRATION =
"ALTER TABLE stories ADD COLUMN IF NOT EXISTS last_completed_at TIMESTAMP;"; "ALTER TABLE stories ADD COLUMN IF NOT EXISTS last_completed_at TIMESTAMP;";
@@ -78,7 +73,12 @@ public class DatabaseMigrationRunner implements CommandLineRunner {
public void run(String... args) throws Exception { public void run(String... args) throws Exception {
logger.info("🗄️ Starting database migrations..."); logger.info("🗄️ Starting database migrations...");
for (String database : LIBRARY_DATABASES) { List<String> databases = libraryService.getAllLibraries().stream()
.map(lib -> libraryService.getDbNameForLibrary(lib.getId()))
.filter(db -> db != null && !db.isBlank())
.collect(java.util.stream.Collectors.toList());
for (String database : databases) {
try { try {
applyMigrations(database); applyMigrations(database);
logger.info("✅ Successfully applied migrations to database: {}", database); logger.info("✅ Successfully applied migrations to database: {}", database);

View File

@@ -33,12 +33,15 @@ public class LibraryService implements ApplicationContextAware {
@Value("${spring.datasource.url}") @Value("${spring.datasource.url}")
private String baseDbUrl; private String baseDbUrl;
@Value("${spring.datasource.username}") @Value("${spring.datasource.username}")
private String dbUsername; private String dbUsername;
@Value("${spring.datasource.password}") @Value("${spring.datasource.password}")
private String dbPassword; private String dbPassword;
@Value("${storycove.auth.password}")
private String appPassword;
private final ObjectMapper objectMapper = new ObjectMapper(); private final ObjectMapper objectMapper = new ObjectMapper();
@@ -252,6 +255,11 @@ public class LibraryService implements ApplicationContextAware {
return current != null ? current.getImagePath() : "/images/default"; return current != null ? current.getImagePath() : "/images/default";
} }
public String getDbNameForLibrary(String libraryId) {
Library library = libraries.get(libraryId);
return library != null ? library.getDbName() : null;
}
public String getImagePathForLibrary(String libraryId) { public String getImagePathForLibrary(String libraryId) {
if (libraryId == null) { if (libraryId == null) {
return "/images/default"; return "/images/default";
@@ -358,21 +366,17 @@ public class LibraryService implements ApplicationContextAware {
Library defaultLibrary = new Library( Library defaultLibrary = new Library(
"main", "main",
"Main Library", "Main Library",
"Your existing story collection (migrated)", "Your story collection",
passwordEncoder.encode("temp-password-change-me"), // Temporary password passwordEncoder.encode(appPassword),
existingDbName // Use existing database name existingDbName
); );
defaultLibrary.setInitialized(true); // Mark as initialized since it has existing data defaultLibrary.setInitialized(true);
libraries.put("main", defaultLibrary); libraries.put("main", defaultLibrary);
saveLibrariesToFile(); saveLibrariesToFile();
logger.warn("=".repeat(80)); logger.info("Created default library 'Main Library' using APP_PASSWORD");
logger.warn("MIGRATION: Created 'Main Library' for your existing data");
logger.warn("Temporary password: 'temp-password-change-me'");
logger.warn("IMPORTANT: Please set a proper password in Settings > Library Settings");
logger.warn("=".repeat(80));
} }
private String extractDatabaseName(String jdbcUrl) { private String extractDatabaseName(String jdbcUrl) {