diff --git a/app/package.json b/app/package.json index 80158c5..fde9357 100644 --- a/app/package.json +++ b/app/package.json @@ -1,6 +1,6 @@ { "name": "gameyfin", - "version": "2.1.0", + "version": "2.1.1-preview", "type": "module", "dependencies": { "@heroui/react": "2.7.9", @@ -265,4 +265,4 @@ "disableUsageStatistics": true, "hash": "dba97848bdace60924f9cee496353baae70cfa4fccc7bacaf827807c51908866" } -} +} \ No newline at end of file diff --git a/app/src/main/frontend/components/temp/DockerHubDeprecationPopover.tsx b/app/src/main/frontend/components/temp/DockerHubDeprecationPopover.tsx new file mode 100644 index 0000000..85cdc54 --- /dev/null +++ b/app/src/main/frontend/components/temp/DockerHubDeprecationPopover.tsx @@ -0,0 +1,44 @@ +import {Button, Link, Popover, PopoverContent, PopoverTrigger} from "@heroui/react"; +import {Warning} from "@phosphor-icons/react"; + +// TODO: Remove this component before the release of version 2.2.0 +export default function DockerHubDeprecationPopover() { + return ( + + + + + +
+

Image deprecation notice

+

+ Starting with version + 2.2.0 + the image{' '} + + grimsi/gameyfin + + {' '}will no longer be published to Docker Hub. +

+

+ Please switch to{' '} + + ghcr.io/gameyfin/gameyfin + + {' '}if you are currently using the Docker Hub image. +

+
+
+
+ ); +} \ No newline at end of file diff --git a/app/src/main/frontend/views/MainLayout.tsx b/app/src/main/frontend/views/MainLayout.tsx index a8aa302..c7a54ee 100644 --- a/app/src/main/frontend/views/MainLayout.tsx +++ b/app/src/main/frontend/views/MainLayout.tsx @@ -14,6 +14,7 @@ import {useSnapshot} from "valtio/react"; import {gameState} from "Frontend/state/GameState"; import ScanProgressPopover from "Frontend/components/general/ScanProgressPopover"; import {isAdmin} from "Frontend/util/utils"; +import DockerHubDeprecationPopover from "Frontend/components/temp/DockerHubDeprecationPopover"; export default function MainLayout() { const navigate = useNavigate(); @@ -105,13 +106,22 @@ export default function MainLayout() { {isAdmin(auth) && - - -
- -
-
-
+
+ + +
+ +
+
+
+ + +
+ +
+
+
+
} {auth.state.user && diff --git a/app/src/main/frontend/views/SetupView.tsx b/app/src/main/frontend/views/SetupView.tsx index 38d9a4c..1d54e5d 100644 --- a/app/src/main/frontend/views/SetupView.tsx +++ b/app/src/main/frontend/views/SetupView.tsx @@ -85,17 +85,26 @@ function SetupView() { initialValues={{username: '', email: '', password: '', passwordRepeat: ''}} onSubmit={ async (values: any) => { - await SetupEndpoint.registerSuperAdmin({ - username: values.username, - password: values.password, - email: values.email - }); - addToast({ - title: "Setup finished", - description: "Have fun with Gameyfin!", - color: "success" - }) - navigate('/login'); + try { + await SetupEndpoint.registerSuperAdmin({ + username: values.username, + password: values.password, + email: values.email + }); + addToast({ + title: "Setup finished", + description: "Have fun with Gameyfin!", + color: "success" + }); + } catch (e) { + addToast({ + title: "Could not register super admin user", + description: "Maybe Gameyfin is already set up?", + color: "warning" + }); + } finally { + navigate('/login'); + } } } > diff --git a/app/src/main/kotlin/org/gameyfin/app/requests/GameRequestService.kt b/app/src/main/kotlin/org/gameyfin/app/requests/GameRequestService.kt index 3f81d65..5676e3f 100644 --- a/app/src/main/kotlin/org/gameyfin/app/requests/GameRequestService.kt +++ b/app/src/main/kotlin/org/gameyfin/app/requests/GameRequestService.kt @@ -102,7 +102,7 @@ class GameRequestService( listOf(GameRequestStatus.PENDING) ) val maxRequestsPerUser = config.get(ConfigProperties.Requests.Games.MaxOpenRequestsPerUser) ?: 0 - if (maxRequestsPerUser == 0 || (auth?.isAdmin() != true && pendingRequestsForUser.size >= maxRequestsPerUser)) { + if (maxRequestsPerUser != 0 && auth?.isAdmin() != true && pendingRequestsForUser.size >= maxRequestsPerUser) { throw EndpointException("You have reached the maximum number of pending requests (${maxRequestsPerUser})") } diff --git a/app/src/main/resources/db/migration/V2.1.1__Recreate_game_image_fks_without_unique_indexes.sql b/app/src/main/resources/db/migration/V2.1.1__Recreate_game_image_fks_without_unique_indexes.sql new file mode 100644 index 0000000..158bdeb --- /dev/null +++ b/app/src/main/resources/db/migration/V2.1.1__Recreate_game_image_fks_without_unique_indexes.sql @@ -0,0 +1,70 @@ +-- Flyway Migration: V2.1.1 +-- Purpose: Fully eliminate unintended uniqueness on GAME.COVER_IMAGE_ID / HEADER_IMAGE_ID +-- by dropping and recreating foreign keys and removing lingering unique indexes +-- Context: +-- * Original schema created UNIQUE constraints (UK52... cover, UK30... header). +-- * V2.1.0.1 dropped those constraints but H2 left behind unique indexes (UK52..._INDEX_n etc.). +-- Strategy: +-- 1. Drop the foreign keys (idempotent). +-- 2. Drop any remaining unique constraints (defensive repeat) and their indexes. +-- 3. Recreate NON-UNIQUE supporting indexes explicitly (optional but good for lookups). +-- 4. Recreate the foreign keys cleanly without reintroducing uniqueness. +-- 5. All steps are idempotent / tolerant so reruns don't fail. + +/****************************************************************************************** + * 1. Drop foreign keys so their backing indexes can be dropped safely + ******************************************************************************************/ +ALTER TABLE GAME + DROP CONSTRAINT IF EXISTS FK_GAME_COVER_IMAGE; +ALTER TABLE GAME + DROP CONSTRAINT IF EXISTS FK_GAME_HEADER_IMAGE; + +-- Also attempt legacy hashed names (in case rename earlier never ran) +ALTER TABLE GAME + DROP CONSTRAINT IF EXISTS FK6CVB43REAYSNYPI0XDY6HQTVF; -- old cover FK +ALTER TABLE GAME + DROP CONSTRAINT IF EXISTS FK8N86NDPGKMOO7YOLX6HL8N84G; +-- old header FK + +/****************************************************************************************** + * 2. Drop any lingering UNIQUE constraints again (defensive) and their indexes + ******************************************************************************************/ +ALTER TABLE GAME + DROP CONSTRAINT IF EXISTS UK52RQ62FLPBNTI77BYKM7UAHKQ; -- old unique cover +ALTER TABLE GAME + DROP CONSTRAINT IF EXISTS UK30B16LLQV54H40XIOGP7T9P35; -- old unique header +ALTER TABLE GAME + DROP CONSTRAINT IF EXISTS UQ_GAME_COVER_IMAGE_ID; -- friendly (future) name +ALTER TABLE GAME + DROP CONSTRAINT IF EXISTS UQ_GAME_HEADER_IMAGE_ID; +-- friendly (future) name + +-- Drop possible leftover unique indexes (multiple variants tried) +DROP INDEX IF EXISTS UK52RQ62FLPBNTI77BYKM7UAHKQ_INDEX_2; +DROP INDEX IF EXISTS UK52RQ62FLPBNTI77BYKM7UAHKQ_INDEX_1; +DROP INDEX IF EXISTS UK30B16LLQV54H40XIOGP7T9P35_INDEX_2; +DROP INDEX IF EXISTS UK30B16LLQV54H40XIOGP7T9P35_INDEX_1; + +/****************************************************************************************** + * 3. Create explicit NON-UNIQUE indexes (only if missing) + ******************************************************************************************/ +CREATE INDEX IF NOT EXISTS IDX_GAME_COVER_IMAGE ON GAME (COVER_IMAGE_ID); +CREATE INDEX IF NOT EXISTS IDX_GAME_HEADER_IMAGE ON GAME (HEADER_IMAGE_ID); + +/****************************************************************************************** + * 4. Recreate foreign keys (non-unique by definition) + ******************************************************************************************/ +ALTER TABLE GAME + ADD CONSTRAINT FK_GAME_COVER_IMAGE FOREIGN KEY (COVER_IMAGE_ID) REFERENCES IMAGE (ID); +ALTER TABLE GAME + ADD CONSTRAINT FK_GAME_HEADER_IMAGE FOREIGN KEY (HEADER_IMAGE_ID) REFERENCES IMAGE (ID); + +/****************************************************************************************** + * 5. (Optional manual verification after migration) + * -- SELECT INDEX_NAME, NON_UNIQUE, COLUMN_NAME FROM INFORMATION_SCHEMA.INDEXES + * -- WHERE TABLE_NAME='GAME' AND COLUMN_NAME IN ('COVER_IMAGE_ID','HEADER_IMAGE_ID'); + * Expected: ONLY non-unique indexes (NON_UNIQUE=TRUE) for those columns. + ******************************************************************************************/ + +-- End of migration. + diff --git a/build.gradle.kts b/build.gradle.kts index 665b0e0..8da615d 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -6,7 +6,7 @@ import org.jetbrains.kotlin.gradle.tasks.KotlinJvmCompile import java.nio.file.Files group = "org.gameyfin" -version = "2.1.0" +version = "2.1.1-preview" allprojects { repositories {