From 794d99add15e2618956d72d026e68c4c47ba3a2e Mon Sep 17 00:00:00 2001 From: Georges-Antoine Assi Date: Thu, 15 Feb 2024 16:58:27 -0500 Subject: [PATCH 1/9] add option to disable CSRF protection --- backend/config/__init__.py | 1 + backend/main.py | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/backend/config/__init__.py b/backend/config/__init__.py index f2320924d..9ad9d09f4 100644 --- a/backend/config/__init__.py +++ b/backend/config/__init__.py @@ -50,6 +50,7 @@ ROMM_AUTH_SECRET_KEY: Final = os.environ.get( "ROMM_AUTH_SECRET_KEY", secrets.token_hex(32) ) +DISABLE_CSRF_PROTECTION = os.environ.get("DISABLE_CSRF_PROTECTION", "false") == "true" # TASKS ENABLE_RESCAN_ON_FILESYSTEM_CHANGE: Final = ( diff --git a/backend/main.py b/backend/main.py index 19903abb0..4de00e181 100644 --- a/backend/main.py +++ b/backend/main.py @@ -3,7 +3,7 @@ import alembic.config import uvicorn -from config import DEV_HOST, DEV_PORT, ROMM_AUTH_SECRET_KEY +from config import DEV_HOST, DEV_PORT, ROMM_AUTH_SECRET_KEY, DISABLE_CSRF_PROTECTION from endpoints import ( auth, config, @@ -40,7 +40,7 @@ allow_headers=["*"], ) -if "pytest" not in sys.modules: +if "pytest" not in sys.modules and not DISABLE_CSRF_PROTECTION: # CSRF protection (except endpoints listed in exempt_urls) app.add_middleware( CustomCSRFMiddleware, From 95d184cea02662be1884cc1596a536c258ce360a Mon Sep 17 00:00:00 2001 From: Georges-Antoine Assi Date: Thu, 15 Feb 2024 16:58:42 -0500 Subject: [PATCH 2/9] reconnect scan on scanner page load --- frontend/src/App.vue | 25 +++++++++++++++++------- frontend/src/views/Library/Scan/Base.vue | 3 +++ 2 files changed, 21 insertions(+), 7 deletions(-) diff --git a/frontend/src/App.vue b/frontend/src/App.vue index a9dfd6710..75bab5a78 100644 --- a/frontend/src/App.vue +++ b/frontend/src/App.vue @@ -8,7 +8,7 @@ import socket from "@/services/socket"; import { onBeforeMount } from "vue"; import cookie from "js-cookie"; import storeGalleryFilter from "@/stores/galleryFilter"; -import storeRoms from "@/stores/roms"; +import storeRoms, { type Rom } from "@/stores/roms"; import storeScanning from "@/stores/scanning"; import type { Events } from "@/types/emitter"; import { normalizeString } from "@/utils"; @@ -28,12 +28,18 @@ const emitter = inject>("emitter"); const heartbeatStore = storeHeartbeat(); const configStore = storeConfig(); -socket.on("scan:scanning_platform", ({ name, slug, id }) => { +socket.on("scan:scanning_platform", ({ name, slug, id }: { + name: string; + slug: string; + id: number; +}) => { + scanningStore.set(true); scanningPlatforms.value.push({ name, slug, id, roms: [] }); }); -socket.on("scan:scanning_rom", ({ platform_name, platform_slug, ...rom }) => { - if (romsStore.platform.name === platform_name) { +socket.on("scan:scanning_rom", (rom: Rom) => { + scanningStore.set(true); + if (romsStore.platform.name === rom.platform_name) { romsStore.add([rom]); romsStore.setFiltered( isFiltered ? romsStore.filteredRoms : romsStore.allRoms, @@ -42,12 +48,17 @@ socket.on("scan:scanning_rom", ({ platform_name, platform_slug, ...rom }) => { } let scannedPlatform = scanningPlatforms.value.find( - (p) => p.slug === platform_slug + (p) => p.slug === rom.platform_slug ); // Add the platform if the socket dropped and it's missing - if (scannedPlatform) { - scanningPlatforms.value.push(scannedPlatform); + if (!scannedPlatform) { + scanningPlatforms.value.push({ + name: rom.platform_name, + slug: rom.platform_slug, + id: rom.platform_id, + roms: [], + }); scannedPlatform = scanningPlatforms.value.pop(); } diff --git a/frontend/src/views/Library/Scan/Base.vue b/frontend/src/views/Library/Scan/Base.vue index fbd8b1783..7e5bcb123 100644 --- a/frontend/src/views/Library/Scan/Base.vue +++ b/frontend/src/views/Library/Scan/Base.vue @@ -14,6 +14,9 @@ const rescanUnidentified = ref(false); const platforms = storePlatforms(); const platformsToScan = ref([]); +// Connect to socket on load to catch running scans +if (!socket.connected) socket.connect(); + async function scan() { scanningStore.set(true); scanningPlatforms.value = []; From cac88111896c39c131b3bcdccc6a999d60809ee9 Mon Sep 17 00:00:00 2001 From: Georges-Antoine Assi Date: Thu, 15 Feb 2024 19:36:30 -0500 Subject: [PATCH 3/9] lowercase platform slug --- frontend/src/components/Details/ActionBar.vue | 2 +- .../src/components/Game/Card/ActionBar.vue | 2 +- .../src/components/Game/DataTable/Base.vue | 2 +- frontend/src/types/index.ts | 2 ++ frontend/src/utils/index.ts | 2 +- frontend/src/views/Play/Player.vue | 19 +++++++++++++------ 6 files changed, 19 insertions(+), 10 deletions(-) diff --git a/frontend/src/components/Details/ActionBar.vue b/frontend/src/components/Details/ActionBar.vue index 2ad79f076..cc33f9dcd 100644 --- a/frontend/src/components/Details/ActionBar.vue +++ b/frontend/src/components/Details/ActionBar.vue @@ -15,7 +15,7 @@ const emitter = inject>("emitter"); const auth = storeAuth(); const emulation = ref(false); const playInfoIcon = ref("mdi-play"); -const emulationSupported = props.rom.platform_slug in platformSlugEJSCoreMap; +const emulationSupported = props.rom.platform_slug.toLowerCase() in platformSlugEJSCoreMap; function toggleEmulation() { emulation.value = !emulation.value; diff --git a/frontend/src/components/Game/Card/ActionBar.vue b/frontend/src/components/Game/Card/ActionBar.vue index 3521dfeba..038009abc 100644 --- a/frontend/src/components/Game/Card/ActionBar.vue +++ b/frontend/src/components/Game/Card/ActionBar.vue @@ -25,7 +25,7 @@ const downloadStore = storeDownload(); variant="text" /> mdi-download = D extends ( ) => infer R ? R : never; + +export type ValueOf = T[keyof T]; diff --git a/frontend/src/utils/index.ts b/frontend/src/utils/index.ts index 291c5ab51..68cf267c4 100644 --- a/frontend/src/utils/index.ts +++ b/frontend/src/utils/index.ts @@ -243,7 +243,7 @@ export function languageToEmoji(language: string) { } } -export const platformSlugEJSCoreMap: Record = { +export const platformSlugEJSCoreMap = { // "3do": "opera", Disabled until BIOS file support is added amiga: "puae", // arcade: "mame2003_plus", Disabled until BIOS file support is added diff --git a/frontend/src/views/Play/Player.vue b/frontend/src/views/Play/Player.vue index 590cd3933..6aa92673b 100644 --- a/frontend/src/views/Play/Player.vue +++ b/frontend/src/views/Play/Player.vue @@ -6,6 +6,7 @@ import screenshotApi from "@/services/api/screenshot"; import { platformSlugEJSCoreMap } from "@/utils"; import type { SaveSchema, StateSchema } from "@/__generated__"; import type { Rom } from "@/stores/roms"; +import type { ValueOf } from "@/types"; const props = defineProps<{ rom: Rom; @@ -19,10 +20,13 @@ onBeforeUnmount(() => { window.location.reload(); }); +type EJSPlatformSlug = keyof typeof platformSlugEJSCoreMap; +type EJSCore = ValueOf; + // Declare global variables for EmulatorJS declare global { interface Window { - EJS_core: string; + EJS_core: EJSCore; EJS_player: string; EJS_pathtodata: string; EJS_color: string; @@ -47,7 +51,10 @@ declare global { } } -window.EJS_core = platformSlugEJSCoreMap[props.rom.platform_slug]; +window.EJS_core = + platformSlugEJSCoreMap[ + props.rom.platform_slug.toLowerCase() as EJSPlatformSlug + ]; window.EJS_gameID = props.rom.id; window.EJS_gameUrl = `/api/roms/${props.rom.id}/content`; window.EJS_player = "#game"; @@ -102,7 +109,7 @@ async function fetchState(): Promise { return new Uint8Array(data); } } - + if (window.EJS_emulator.saveInBrowserSupported()) { const data = await window.EJS_emulator.storage.states.get( window.EJS_emulator.getBaseFileName() + ".state" @@ -112,7 +119,7 @@ async function fetchState(): Promise { return data; } } - + const file = await window.EJS_emulator.selectFile(); return new Uint8Array(await file.arrayBuffer()); } @@ -205,7 +212,7 @@ window.EJS_onSaveState = function ({ stateApi .uploadStates({ rom: props.rom, - emulator: platformSlugEJSCoreMap[props.rom.platform_slug], + emulator: window.EJS_core, states: [ new File([state], buildStateName(), { type: "application/octet-stream", @@ -331,7 +338,7 @@ window.EJS_onSaveSave = function ({ saveApi .uploadSaves({ rom: props.rom, - emulator: platformSlugEJSCoreMap[props.rom.platform_slug], + emulator: window.EJS_core, saves: [ new File([save], buildSaveName(), { type: "application/octet-stream", From e4d6c6e1c597b98a85873606558b688fa4a9bd12 Mon Sep 17 00:00:00 2001 From: Georges-Antoine Assi Date: Thu, 15 Feb 2024 20:25:13 -0500 Subject: [PATCH 4/9] small typo --- frontend/src/App.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/App.vue b/frontend/src/App.vue index 75bab5a78..1b1a7ade4 100644 --- a/frontend/src/App.vue +++ b/frontend/src/App.vue @@ -59,7 +59,7 @@ socket.on("scan:scanning_rom", (rom: Rom) => { id: rom.platform_id, roms: [], }); - scannedPlatform = scanningPlatforms.value.pop(); + scannedPlatform = scanningPlatforms.value[0]; } scannedPlatform?.roms.push(rom); From c5079f295481cc14f911c4b7c649ccb5df96b69b Mon Sep 17 00:00:00 2001 From: Georges-Antoine Assi Date: Thu, 15 Feb 2024 20:29:23 -0500 Subject: [PATCH 5/9] slight better type --- frontend/src/views/Play/Player.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/views/Play/Player.vue b/frontend/src/views/Play/Player.vue index 6aa92673b..1302003bb 100644 --- a/frontend/src/views/Play/Player.vue +++ b/frontend/src/views/Play/Player.vue @@ -39,7 +39,7 @@ declare global { EJS_cheats: string; EJS_gamePatchUrl: string; EJS_netplayServer: string; - EJS_alignStartButton: string; + EJS_alignStartButton: "top" | "center" | "bottom"; EJS_startOnLoaded: boolean; EJS_fullscreenOnLoaded: boolean; EJS_emulator: any; From 268ae2605398392fdf2373968edb9a9697fda201 Mon Sep 17 00:00:00 2001 From: Georges-Antoine Assi Date: Thu, 15 Feb 2024 20:57:51 -0500 Subject: [PATCH 6/9] remove double fetch --- frontend/src/views/Home.vue | 1 - 1 file changed, 1 deletion(-) diff --git a/frontend/src/views/Home.vue b/frontend/src/views/Home.vue index 98bb468f2..5b54d6af4 100644 --- a/frontend/src/views/Home.vue +++ b/frontend/src/views/Home.vue @@ -37,7 +37,6 @@ onMounted(async () => { platformsStore.set(platforms); const { data: currentUser } = await userApi.fetchCurrentUser(); if (currentUser) auth.setUser(currentUser); - emitter?.emit("refreshDrawer", null); } catch (error) { console.error(error); } From a24e4fe3ee89454bf7d8188aefb8b7ba478021b9 Mon Sep 17 00:00:00 2001 From: Georges-Antoine Assi Date: Thu, 15 Feb 2024 22:11:41 -0500 Subject: [PATCH 7/9] fetch on mount async --- backend/handler/gh_handler.py | 2 +- frontend/src/App.vue | 28 +++++++++---------- frontend/src/components/Dashboard/Recent.vue | 12 ++++++-- frontend/src/components/Dashboard/Summary.vue | 7 +++-- frontend/src/components/Drawer/Base.vue | 2 -- frontend/src/services/api/utils.ts | 1 + frontend/src/views/Home.vue | 27 ++++++++++++------ 7 files changed, 47 insertions(+), 32 deletions(-) create mode 100644 frontend/src/services/api/utils.ts diff --git a/backend/handler/gh_handler.py b/backend/handler/gh_handler.py index d8cf0a14f..3ddd7273e 100644 --- a/backend/handler/gh_handler.py +++ b/backend/handler/gh_handler.py @@ -35,7 +35,7 @@ def check_new_version(self) -> str: try: response = requests.get( - "https://github.com/gitapi/repos/zurdi15/romm/releases/latest", timeout=0.5 + "https://github.com/gitapi/repos/zurdi15/romm/releases/latest", timeout=5 ) except ReadTimeout: log.warning("Couldn't check last RomM version.") diff --git a/frontend/src/App.vue b/frontend/src/App.vue index 1b1a7ade4..a0e32f149 100644 --- a/frontend/src/App.vue +++ b/frontend/src/App.vue @@ -1,7 +1,6 @@