diff --git a/src/main/java/dev/kruhlmann/imgfloat/controller/SystemAdministratorApiController.java b/src/main/java/dev/kruhlmann/imgfloat/controller/SystemAdministratorApiController.java index 368efcd..2e37981 100644 --- a/src/main/java/dev/kruhlmann/imgfloat/controller/SystemAdministratorApiController.java +++ b/src/main/java/dev/kruhlmann/imgfloat/controller/SystemAdministratorApiController.java @@ -57,7 +57,11 @@ public class SystemAdministratorApiController { throw new ResponseStatusException(BAD_REQUEST, "Username is required"); } String username = request.twitchUsername().trim(); - systemAdministratorService.addSysadmin(username); + try { + systemAdministratorService.addSysadmin(username); + } catch (IllegalStateException e) { + throw new ResponseStatusException(BAD_REQUEST, e.getMessage(), e); + } LOG.info("System administrator added: {} (requested by {})", username, sessionUsername); return ResponseEntity.ok().body(systemAdministratorService.listSysadmins()); } diff --git a/src/main/java/dev/kruhlmann/imgfloat/service/SystemAdministratorService.java b/src/main/java/dev/kruhlmann/imgfloat/service/SystemAdministratorService.java index 4e90382..c19de6f 100644 --- a/src/main/java/dev/kruhlmann/imgfloat/service/SystemAdministratorService.java +++ b/src/main/java/dev/kruhlmann/imgfloat/service/SystemAdministratorService.java @@ -71,7 +71,7 @@ public class SystemAdministratorService { String initialSysadmin = getInitialSysadmin(); if (initialSysadmin != null && initialSysadmin.equals(normalized)) { - return; + throw new IllegalStateException("Cannot add the initial system administrator"); } if (repo.existsByTwitchUsername(normalized)) { @@ -81,6 +81,7 @@ public class SystemAdministratorService { repo.save(new SystemAdministrator(normalized)); } + @Transactional public void removeSysadmin(String twitchUsername) { String normalized = normalize(twitchUsername); String initialSysadmin = getInitialSysadmin(); @@ -118,11 +119,21 @@ public class SystemAdministratorService { } public List listSysadmins() { - return repo + String initialSysadmin = getInitialSysadmin(); + List persistedAdmins = repo .findAllByOrderByTwitchUsernameAsc() .stream() .map(SystemAdministrator::getTwitchUsername) .collect(Collectors.toList()); + if (initialSysadmin == null) { + return persistedAdmins; + } + return java.util.stream.Stream + .concat(persistedAdmins.stream(), java.util.stream.Stream.of(initialSysadmin)) + .map(this::normalize) + .distinct() + .sorted() + .collect(Collectors.toList()); } private String normalize(String username) { diff --git a/src/main/resources/static/js/settings.js b/src/main/resources/static/js/settings.js index 77e91a9..3bcaacc 100644 --- a/src/main/resources/static/js/settings.js +++ b/src/main/resources/static/js/settings.js @@ -187,14 +187,16 @@ function renderSystemAdministrators(admins) { const button = document.createElement("button"); button.classList.add("button", "secondary"); button.type = "button"; - button.textContent = "Remove"; - button.addEventListener("click", () => removeSystemAdministrator(admin)); button.setAttribute("data-sysadmin-remove", "true"); button.setAttribute("data-sysadmin-username", admin); if (isInitialSysadmin) { button.disabled = true; - button.title = "The initial system administrator cannot be removed."; + button.textContent = "System default"; + button.title = "The system default administrator cannot be removed."; + } else { + button.textContent = "Remove"; + button.addEventListener("click", () => removeSystemAdministrator(admin)); } listItem.appendChild(text); @@ -226,6 +228,10 @@ function addSystemAdministrator() { showToast("Enter a Twitch username", "warning"); return; } + if (initialSysadmin && username.toLowerCase() === initialSysadmin) { + showToast("That user is already the system default administrator.", "warning"); + return; + } fetch("/api/system-administrators", { method: "POST", headers: { "Content-Type": "application/json" },