configurable url

This commit is contained in:
Stefan Hardegger
2025-07-24 08:03:56 +02:00
parent 4bbc14d165
commit 77ad643eac
15 changed files with 257 additions and 26 deletions

View File

@@ -23,7 +23,7 @@ import java.util.List;
@EnableWebSecurity
public class SecurityConfig {
@Value("${storycove.cors.allowed-origins:${STORYCOVE_CORS_ALLOWED_ORIGINS:http://localhost:3000}}")
@Value("${storycove.cors.allowed-origins}")
private String allowedOrigins;
private final JwtAuthenticationFilter jwtAuthenticationFilter;

View File

@@ -23,10 +23,8 @@ import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import java.util.stream.Collectors;
@@ -39,7 +37,6 @@ public class StoryController {
private final StoryService storyService;
private final AuthorService authorService;
private final SeriesService seriesService;
private final TagService tagService;
private final HtmlSanitizationService sanitizationService;
private final ImageService imageService;
private final TypesenseService typesenseService;
@@ -47,14 +44,12 @@ public class StoryController {
public StoryController(StoryService storyService,
AuthorService authorService,
SeriesService seriesService,
TagService tagService,
HtmlSanitizationService sanitizationService,
ImageService imageService,
@Autowired(required = false) TypesenseService typesenseService) {
this.storyService = storyService;
this.authorService = authorService;
this.seriesService = seriesService;
this.tagService = tagService;
this.sanitizationService = sanitizationService;
this.imageService = imageService;
this.typesenseService = typesenseService;
@@ -88,7 +83,7 @@ public class StoryController {
Story story = new Story();
updateStoryFromRequest(story, request);
Story savedStory = storyService.create(story);
Story savedStory = storyService.createWithTagNames(story, request.getTagNames());
return ResponseEntity.status(HttpStatus.CREATED).body(convertToDto(savedStory));
}
@@ -325,20 +320,7 @@ public class StoryController {
story.setSeries(series);
}
// Handle tags
if (createReq.getTagNames() != null && !createReq.getTagNames().isEmpty()) {
for (String tagName : createReq.getTagNames()) {
if (tagName != null && !tagName.trim().isEmpty()) {
Tag tag = tagService.findByNameOptional(tagName.trim().toLowerCase())
.orElseGet(() -> {
Tag newTag = new Tag();
newTag.setName(tagName.trim().toLowerCase());
return tagService.create(newTag);
});
story.addTag(tag);
}
}
}
// Tags are handled in the service layer
} else if (request instanceof UpdateStoryRequest updateReq) {
if (updateReq.getTitle() != null) {
story.setTitle(updateReq.getTitle());

View File

@@ -338,7 +338,7 @@ public class AuthorService {
if (updates.getAuthorRating() != null) {
existing.setAuthorRating(updates.getAuthorRating());
}
if (updates.getUrls() != null && !updates.getUrls().isEmpty()) {
if (updates.getUrls() != null) {
existing.getUrls().clear();
existing.getUrls().addAll(updates.getUrls());
}

View File

@@ -316,6 +316,36 @@ public class StoryService {
return savedStory;
}
public Story createWithTagNames(@Valid Story story, java.util.List<String> tagNames) {
validateStoryForCreate(story);
// Set up relationships
if (story.getAuthor() != null && story.getAuthor().getId() != null) {
Author author = authorService.findById(story.getAuthor().getId());
story.setAuthor(author);
}
if (story.getSeries() != null && story.getSeries().getId() != null) {
Series series = seriesService.findById(story.getSeries().getId());
story.setSeries(series);
validateSeriesVolume(series, story.getVolume());
}
Story savedStory = storyRepository.save(story);
// Handle tags by names
if (tagNames != null && !tagNames.isEmpty()) {
updateStoryTagsByNames(savedStory, tagNames);
}
// Index in Typesense (if available)
if (typesenseService != null) {
typesenseService.indexStory(savedStory);
}
return savedStory;
}
public Story update(UUID id, @Valid Story storyUpdates) {
Story existingStory = findById(id);

View File

@@ -23,6 +23,10 @@ server:
port: 8080
storycove:
app:
public-url: ${STORYCOVE_PUBLIC_URL:http://localhost:6925}
cors:
allowed-origins: ${STORYCOVE_CORS_ALLOWED_ORIGINS:http://localhost:3000,http://localhost:6925}
jwt:
secret: ${JWT_SECRET:default-secret-key}
expiration: 86400000 # 24 hours