diff --git a/frontend/views/SetupView.tsx b/frontend/views/SetupView.tsx
index 765c775..d764340 100644
--- a/frontend/views/SetupView.tsx
+++ b/frontend/views/SetupView.tsx
@@ -5,8 +5,9 @@ import WizardStep from "Frontend/components/wizard/WizardStep";
import Input from "Frontend/components/Input";
import {GearFine, HandWaving, Palette, User} from "@phosphor-icons/react";
import {Card} from "@nextui-org/react";
-import {UserEndpoint} from "Frontend/generated/endpoints";
+import {SetupEndpoint} from "Frontend/generated/endpoints";
import {ThemeSelector} from "Frontend/components/theming/ThemeSelector";
+import {useNavigate} from "react-router-dom";
function WelcomeStep() {
return (
@@ -82,48 +83,60 @@ function SettingsStep() {
);
}
-const SetupView = () => (
-
-
- UserEndpoint.registerInitialSuperAdmin({
- username: values.username,
- password: values.password,
- email: values.email
+function SetupView() {
+ const navigate = useNavigate();
+
+ return (
+
+
+ {
+ try {
+ await SetupEndpoint.registerSuperAdmin({
+ username: values.username,
+ password: values.password,
+ email: values.email
+ });
+ navigate('/login');
+ } catch (e) {
+ alert("An error occurred while completing the setup. Please try again.")
+ }
+ }
}
- ).then(() => alert("Successfully registered!"))}
- >
- }>
-
-
- }>
-
-
- }
>
-
-
- }>
-
-
-
-
-
-);
+ }>
+
+
+ }>
+
+
+ }
+ >
+
+
+ }>
+
+
+
+
+
+ );
+}
export default SetupView;
\ No newline at end of file
diff --git a/src/main/kotlin/de/grimsi/gameyfin/setup/SetupDataLoader.kt b/src/main/kotlin/de/grimsi/gameyfin/setup/SetupDataLoader.kt
index 831b744..cfe6e6c 100644
--- a/src/main/kotlin/de/grimsi/gameyfin/setup/SetupDataLoader.kt
+++ b/src/main/kotlin/de/grimsi/gameyfin/setup/SetupDataLoader.kt
@@ -34,19 +34,17 @@ class SetupDataLoader(
fun setupUsers() {
val superadmin = User(
username = "admin",
- password = "admin",
- roles = listOf(roleRepository.findByRolename(Roles.SUPERADMIN.roleName)!!)
+ password = "admin"
)
- userService.registerUser(superadmin)
+ userService.registerUser(superadmin, Roles.SUPERADMIN)
val user = User(
username = "user",
- password = "user",
- roles = listOf(roleRepository.findByRolename(Roles.USER.roleName)!!)
+ password = "user"
)
- userService.registerUser(user)
+ userService.registerUser(user, Roles.USER)
}
fun setupRoles() {
diff --git a/src/main/kotlin/de/grimsi/gameyfin/setup/SetupEndpoint.kt b/src/main/kotlin/de/grimsi/gameyfin/setup/SetupEndpoint.kt
new file mode 100644
index 0000000..b9ad8b7
--- /dev/null
+++ b/src/main/kotlin/de/grimsi/gameyfin/setup/SetupEndpoint.kt
@@ -0,0 +1,38 @@
+package de.grimsi.gameyfin.setup
+
+import com.vaadin.flow.server.auth.AnonymousAllowed
+import de.grimsi.gameyfin.config.Roles
+import de.grimsi.gameyfin.users.RoleService
+import de.grimsi.gameyfin.users.UserService
+import de.grimsi.gameyfin.users.dto.UserInfo
+import de.grimsi.gameyfin.users.dto.UserRegistration
+import de.grimsi.gameyfin.users.entities.User
+import dev.hilla.Endpoint
+import dev.hilla.exception.EndpointException
+
+@Endpoint
+class SetupEndpoint(
+ private val setupService: SetupService,
+ private val roleService: RoleService,
+ private val userService: UserService
+) {
+ @AnonymousAllowed
+ fun isSetupCompleted(): Boolean {
+ return setupService.isSetupCompleted()
+ }
+
+ @AnonymousAllowed
+ fun registerSuperAdmin(superAdminRegistration: UserRegistration): UserInfo {
+ if (setupService.isSetupCompleted()) throw EndpointException("Setup already completed")
+
+ val user = User(
+ username = superAdminRegistration.username,
+ password = superAdminRegistration.password,
+ email = superAdminRegistration.email,
+ roles = listOf(roleService.toRole(Roles.SUPERADMIN))
+ )
+
+ val superAdmin = setupService.createInitialAdminUser(user)
+ return userService.toUserInfo(superAdmin)
+ }
+}
\ No newline at end of file
diff --git a/src/main/kotlin/de/grimsi/gameyfin/setup/SetupService.kt b/src/main/kotlin/de/grimsi/gameyfin/setup/SetupService.kt
index 9b6d675..74a6139 100644
--- a/src/main/kotlin/de/grimsi/gameyfin/setup/SetupService.kt
+++ b/src/main/kotlin/de/grimsi/gameyfin/setup/SetupService.kt
@@ -2,10 +2,13 @@ package de.grimsi.gameyfin.setup
import de.grimsi.gameyfin.config.Roles
import de.grimsi.gameyfin.users.RoleService
+import de.grimsi.gameyfin.users.UserService
+import de.grimsi.gameyfin.users.entities.User
import org.springframework.stereotype.Service
@Service
class SetupService(
+ private val userService: UserService,
private val roleService: RoleService
) {
@@ -17,4 +20,11 @@ class SetupService(
fun isSetupCompleted(): Boolean {
return roleService.getUserCountForRole(Roles.SUPERADMIN) > 0
}
+
+ /**
+ * Creates the initial user with Super-Admin permissions
+ */
+ fun createInitialAdminUser(superAdmin: User): User {
+ return userService.registerUser(superAdmin, Roles.SUPERADMIN)
+ }
}
\ No newline at end of file
diff --git a/src/main/kotlin/de/grimsi/gameyfin/users/RoleService.kt b/src/main/kotlin/de/grimsi/gameyfin/users/RoleService.kt
index 0e78c5e..374de42 100644
--- a/src/main/kotlin/de/grimsi/gameyfin/users/RoleService.kt
+++ b/src/main/kotlin/de/grimsi/gameyfin/users/RoleService.kt
@@ -20,11 +20,12 @@ class RoleService(
return r.users.size
}
- fun toRoles(roles: Collection): List {
- return roles.mapNotNull { r -> roleRepository.findByRolename(r) }
+ fun toRoles(roles: Collection): List {
+ return roles.mapNotNull { r -> roleRepository.findByRolename(r.roleName) }
}
- fun toRole(role: String): Role {
- return roleRepository.findByRolename(role) ?: throw RuntimeException("Role $role does not exist")
+ fun toRole(role: Roles): Role {
+ return roleRepository.findByRolename(role.roleName)
+ ?: throw RuntimeException("Role ${role.roleName} does not exist")
}
}
\ No newline at end of file
diff --git a/src/main/kotlin/de/grimsi/gameyfin/users/UserEndpoint.kt b/src/main/kotlin/de/grimsi/gameyfin/users/UserEndpoint.kt
index 659760e..ee38448 100644
--- a/src/main/kotlin/de/grimsi/gameyfin/users/UserEndpoint.kt
+++ b/src/main/kotlin/de/grimsi/gameyfin/users/UserEndpoint.kt
@@ -6,11 +6,9 @@ import de.grimsi.gameyfin.users.dto.UserRegistration
import de.grimsi.gameyfin.users.entities.User
import dev.hilla.Endpoint
import jakarta.annotation.security.PermitAll
-import org.springframework.http.HttpStatus
import org.springframework.security.core.Authentication
import org.springframework.security.core.GrantedAuthority
import org.springframework.security.core.context.SecurityContextHolder
-import org.springframework.web.server.ResponseStatusException
@Endpoint
class UserEndpoint(
@@ -31,21 +29,13 @@ class UserEndpoint(
return userService.toUserInfo(user)
}
- @PermitAll
- fun registerInitialSuperAdmin(registration: UserRegistration): UserInfo {
- if (roleService.getUserCountForRole(Roles.SUPERADMIN) > 0) throw ResponseStatusException(HttpStatus.UNAUTHORIZED)
- val superAdmin: User = registerUser(registration, listOf(Roles.SUPERADMIN))
- return userService.toUserInfo(superAdmin)
- }
-
private fun registerUser(registration: UserRegistration, roles: List): User {
val user = User(
username = registration.username,
password = registration.password,
- email = registration.email,
- roles = roles.map { r -> roleService.toRole(r.roleName) }
+ email = registration.email
)
- return userService.registerUser(user)
+ return userService.registerUser(user, roles)
}
}
\ No newline at end of file
diff --git a/src/main/kotlin/de/grimsi/gameyfin/users/UserService.kt b/src/main/kotlin/de/grimsi/gameyfin/users/UserService.kt
index 6f43716..2141325 100644
--- a/src/main/kotlin/de/grimsi/gameyfin/users/UserService.kt
+++ b/src/main/kotlin/de/grimsi/gameyfin/users/UserService.kt
@@ -1,5 +1,6 @@
package de.grimsi.gameyfin.users
+import de.grimsi.gameyfin.config.Roles
import de.grimsi.gameyfin.users.dto.UserInfo
import de.grimsi.gameyfin.users.entities.Role
import de.grimsi.gameyfin.users.entities.User
@@ -18,7 +19,8 @@ import org.springframework.stereotype.Service
@Transactional
class UserService(
private val userRepository: UserRepository,
- private val passwordEncoder: PasswordEncoder
+ private val passwordEncoder: PasswordEncoder,
+ private val roleService: RoleService
) : UserDetailsService {
override fun loadUserByUsername(username: String): UserDetails {
@@ -36,8 +38,13 @@ class UserService(
)
}
- fun registerUser(user: User): User {
+ fun registerUser(user: User, role: Roles): User {
+ return registerUser(user, listOf(role))
+ }
+
+ fun registerUser(user: User, roles: List): User {
user.password = passwordEncoder.encode(user.password)
+ user.roles = roleService.toRoles(roles)
return userRepository.save(user)
}
diff --git a/src/main/kotlin/de/grimsi/gameyfin/users/entities/User.kt b/src/main/kotlin/de/grimsi/gameyfin/users/entities/User.kt
index a6dbb93..e3b901c 100644
--- a/src/main/kotlin/de/grimsi/gameyfin/users/entities/User.kt
+++ b/src/main/kotlin/de/grimsi/gameyfin/users/entities/User.kt
@@ -33,5 +33,5 @@ class User(
joinColumns = [JoinColumn(name = "user_id", referencedColumnName = "id")],
inverseJoinColumns = [JoinColumn(name = "role_id", referencedColumnName = "id")]
)
- var roles: Collection
+ var roles: Collection = emptyList()
)
\ No newline at end of file