Fixed various smaller issues

This commit is contained in:
grimsi
2025-09-03 20:26:44 +02:00
parent 153001fdfe
commit 4ae78b01a8
8 changed files with 68 additions and 16 deletions
@@ -35,9 +35,11 @@ export default function GameRequestView() {
const gameRequests = useSnapshot(gameRequestState).gameRequests;
const [areGameRequestsEnabled, setAreGameRequestsEnabled] = useState(false);
const [areGuestsAllowedToRequestGames, setAreGuestsAllowedToRequestGames] = useState(false);
useEffect(() => {
ConfigEndpoint.areGameRequestsEnabled().then(setAreGameRequestsEnabled);
ConfigEndpoint.areGuestsAllowedToRequestGames().then(setAreGuestsAllowedToRequestGames);
}, []);
const [searchTerm, setSearchTerm] = useState("");
@@ -168,7 +170,7 @@ export default function GameRequestView() {
color="primary"
startContent={<PlusCircle weight="fill"/>}
onPress={requestGameModal.onOpen}
isDisabled={!areGameRequestsEnabled}>
isDisabled={!areGameRequestsEnabled || (!auth.state.user && !areGuestsAllowedToRequestGames)}>
Request a Game
</Button>
</div>
+10 -12
View File
@@ -94,18 +94,16 @@ export default function MainLayout() {
</Tooltip>
</NavbarContent>}
<NavbarContent justify="end" className="items-center">
{auth.state.user &&
<NavbarItem>
<Tooltip content="Request a game" placement="bottom">
<Button color="primary"
isDisabled={window.location.pathname.startsWith("/requests")}
onPress={() => navigate("/requests")}
startContent={<Disc weight="fill"/>}>
Requests
</Button>
</Tooltip>
</NavbarItem>
}
<NavbarItem>
<Tooltip content="Request a game" placement="bottom">
<Button color="primary"
isDisabled={window.location.pathname.startsWith("/requests")}
onPress={() => navigate("/requests")}
startContent={<Disc weight="fill"/>}>
Requests
</Button>
</Tooltip>
</NavbarItem>
{isAdmin(auth) &&
<NavbarItem>
<Tooltip content="View library scan results" placement="bottom">
@@ -59,4 +59,9 @@ class ConfigEndpoint(
@DynamicPublicAccess
@AnonymousAllowed
fun areGameRequestsEnabled(): Boolean = configService.get(ConfigProperties.Requests.Games.Enabled) == true
@DynamicPublicAccess
@AnonymousAllowed
fun areGuestsAllowedToRequestGames(): Boolean =
configService.get(ConfigProperties.Requests.Games.AllowGuestsToRequestGames) == true
}
@@ -91,7 +91,7 @@ class GameRequestService(
// Check if guests are allowed to create requests
if (config.get(ConfigProperties.Requests.Games.AllowGuestsToRequestGames) != true && currentUser == null) {
throw EndpointException("Only registered users can create game requests")
throw EndpointException("Only registered users can submit game requests")
}
// Check if user has too many open requests (0 means no limit per user)
@@ -99,7 +99,9 @@ class UserService(
if (principal is OidcUser) {
val oidcUser = org.gameyfin.app.users.entities.User(principal)
val userInfoDto = oidcUser.toExtendedUserInfoDto()
val user = userRepository.findByOidcProviderId(oidcUser.oidcProviderId!!)
?: throw UsernameNotFoundException("Unknown OIDC user with provider ID '${oidcUser.oidcProviderId}'")
val userInfoDto = user.toExtendedUserInfoDto()
userInfoDto.roles = roleService.extractGrantedAuthorities(principal.authorities)
.mapNotNull { Role.safeValueOf(it.authority) }
return userInfoDto
@@ -1,14 +1,15 @@
package org.gameyfin.app.users.entities
import org.gameyfin.app.games.entities.Image
import jakarta.persistence.*
import org.gameyfin.app.core.Role
import org.gameyfin.app.core.security.EncryptionConverter
import org.gameyfin.app.games.entities.Image
import org.springframework.security.oauth2.core.oidc.user.OidcUser
@Entity
@Table(name = "users")
@EntityListeners(UserEntityListener::class)
class User(
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@@ -0,0 +1,25 @@
package org.gameyfin.app.users.entities
import jakarta.persistence.EntityManager
import jakarta.persistence.PreRemove
import org.gameyfin.app.requests.entities.GameRequest
import org.gameyfin.app.util.EntityManagerHolder
class UserEntityListener {
@PreRemove
fun preRemove(user: User) {
val entityManager: EntityManager = EntityManagerHolder.getEntityManager()
// Remove user from all GameRequest voters and requester fields
val gameRequests = entityManager.createQuery(
"SELECT gr FROM GameRequest gr WHERE :user MEMBER OF gr.voters OR gr.requester = :user",
GameRequest::class.java
).setParameter("user", user).resultList
for (gr in gameRequests) {
gr.voters.remove(user)
if (gr.requester == user) gr.requester = null
entityManager.merge(gr)
}
}
}
@@ -0,0 +1,19 @@
package org.gameyfin.app.util
import jakarta.persistence.EntityManager
import org.springframework.context.ApplicationContext
import org.springframework.context.ApplicationContextAware
import org.springframework.stereotype.Component
@Component
object EntityManagerHolder : ApplicationContextAware {
private var entityManager: EntityManager? = null
override fun setApplicationContext(context: ApplicationContext) {
entityManager = context.getBean(EntityManager::class.java)
}
fun getEntityManager(): EntityManager {
return entityManager ?: throw IllegalStateException("EntityManager not set")
}
}