diff --git a/docs/getting-started/metadata-providers.md b/docs/getting-started/metadata-providers.md index 520eb482..1544ed42 100644 --- a/docs/getting-started/metadata-providers.md +++ b/docs/getting-started/metadata-providers.md @@ -105,6 +105,8 @@ To enable Playmatch, set `PLAYMATCH_API_ENABLED=true` in your environment variab When Playmatch is enabled, manually matching a ROM through the edit dialog also forwards the ROM's hashes, filename, filesize and resolved provider IDs as a suggestion to Playmatch. Suggestions are reviewed manually before being added to the Playmatch database, which helps improve match quality for the wider community over time. +By default RomM talks to the community-hosted Playmatch instance. To point at your own [self-hosted Playmatch](https://github.com/RetroRealm/playmatch), set `PLAYMATCH_API_URL` to its API base (e.g. `https://playmatch.example.com/api/v2`). + ### SteamGridDB SteamGridDB provides custom cover art for games or collections. It's not accessed through the scanner but from the "search cover" button when manually editing a game. diff --git a/docs/install/reverse-proxy.md b/docs/install/reverse-proxy.md index a699c8b0..da1ab420 100644 --- a/docs/install/reverse-proxy.md +++ b/docs/install/reverse-proxy.md @@ -187,3 +187,16 @@ environment: ``` If you're also using OIDC, update `OIDC_REDIRECT_URI` to match (see [OIDC Setup](../administration/oidc/index.md)). + +## Harden cookies and CORS behind HTTPS + +Two optional env vars tighten browser security once you're on HTTPS: + +```yaml +environment: + - ROMM_SESSION_SECURE_COOKIE=true + - ROMM_CORS_ALLOWED_ORIGINS=https://romm.mysite.com +``` + +- `ROMM_SESSION_SECURE_COOKIE` marks the session and CSRF cookies `Secure` so browsers only send them over HTTPS. Leave it `false` if you still reach the instance over plain HTTP, or logins will silently fail. +- `ROMM_CORS_ALLOWED_ORIGINS` is a comma-separated allowlist of origins permitted to call the API from a browser. An empty value (the default) allows any origin, so set it to your public URL (plus any companion-app origins) when you want to lock cross-origin requests down. diff --git a/docs/reference/configuration-file.md b/docs/reference/configuration-file.md index ac24a07c..21688d26 100644 --- a/docs/reference/configuration-file.md +++ b/docs/reference/configuration-file.md @@ -209,6 +209,23 @@ scan: - "moby" ``` +### `scan.priority.cover`, `scan.priority.screenshot`, `scan.priority.manual` + +Optional per-field overrides that let you prioritise sources differently for each artwork type. Any field you omit falls back to the shared [`scan.priority.artwork`](#scanpriorityartwork) order, so only set the ones you want to diverge. + +```yaml +scan: + priority: + cover: # Cover art only + - "igdb" + - "ss" + screenshot: # Screenshots only + - "ss" + - "igdb" + manual: # Game manuals only + - "launchbox" +``` + ### `scan.priority.region` Preferred region for titles, cover art, and regional variants. ScreenScraper uses this directly, and other providers respect it where possible. diff --git a/docs/resources/snippets/env-vars.md b/docs/resources/snippets/env-vars.md index 07bd40ac..df12b541 100644 --- a/docs/resources/snippets/env-vars.md +++ b/docs/resources/snippets/env-vars.md @@ -36,40 +36,42 @@ ### Authentication -| Variable | Default | Required | Description | -| ------------------------------------ | --------- | :------: | ---------------------------------------------------------- | -| `ROMM_AUTH_SECRET_KEY` | | `✓` | App secret, generate with `openssl rand -hex 32` | -| `OAUTH_ACCESS_TOKEN_EXPIRE_SECONDS` | `1800` | | Access token lifetime in seconds | -| `OAUTH_REFRESH_TOKEN_EXPIRE_SECONDS` | `604800` | | Refresh token lifetime in seconds | -| `SESSION_MAX_AGE_SECONDS` | `1209600` | | Maximum age of a session in seconds | -| `INVITE_TOKEN_EXPIRY_SECONDS` | `600` | | Invite token lifetime in seconds | -| `DISABLE_DOWNLOAD_ENDPOINT_AUTH` | `false` | | Disable auth on the download endpoint for WebRcade/Tinfoil | -| `DISABLE_CSRF_PROTECTION` | `false` | | Disable CSRF protection (not recommended) | -| `DISABLE_USERPASS_LOGIN` | `false` | | Disable username/password login when using OIDC | -| `DISABLE_SETUP_WIZARD` | `false` | | Skip the first-boot setup wizard | -| `DISABLE_LOGS_VIEWER` | `false` | | Disable the backend logs viewer | +| Variable | Default | Required | Description | +| ------------------------------------ | --------- | :------: | -------------------------------------------------------------------- | +| `ROMM_AUTH_SECRET_KEY` | | `✓` | App secret, generate with `openssl rand -hex 32` | +| `OAUTH_ACCESS_TOKEN_EXPIRE_SECONDS` | `1800` | | Access token lifetime in seconds | +| `OAUTH_REFRESH_TOKEN_EXPIRE_SECONDS` | `604800` | | Refresh token lifetime in seconds | +| `SESSION_MAX_AGE_SECONDS` | `1209600` | | Maximum age of a session in seconds | +| `INVITE_TOKEN_EXPIRY_SECONDS` | `600` | | Invite token lifetime in seconds | +| `DISABLE_DOWNLOAD_ENDPOINT_AUTH` | `false` | | Disable auth on the download endpoint for WebRcade/Tinfoil | +| `DISABLE_CSRF_PROTECTION` | `false` | | Disable CSRF protection (not recommended) | +| `DISABLE_USERPASS_LOGIN` | `false` | | Disable username/password login when using OIDC | +| `DISABLE_SETUP_WIZARD` | `false` | | Skip the first-boot setup wizard | +| `DISABLE_LOGS_VIEWER` | `false` | | Disable the backend logs viewer | +| `ROMM_CORS_ALLOWED_ORIGINS` | | | Comma-separated list of allowed CORS origins (empty allows all) | +| `ROMM_SESSION_SECURE_COOKIE` | `false` | | Mark session and CSRF cookies Secure (enable when served over HTTPS) | ### OpenID Connect -| Variable | Default | Required | Description | -| ----------------------------- | -------------------- | :------: | ------------------------------------------------------------------------------------------- | -| `OIDC_ENABLED` | `false` | | Enable OpenID Connect authentication | -| `OIDC_AUTOLOGIN` | `false` | | Skip the OIDC button on the login page and auto-redirect | -| `OIDC_ALLOW_REGISTRATION` | `true` | | Allow new accounts to be created automatically on first OIDC login | -| `OIDC_PROVIDER` | | | Name of the OIDC provider in use | -| `OIDC_CLIENT_ID` | | | Client ID for OIDC authentication | -| `OIDC_CLIENT_SECRET` | | | Client secret for OIDC authentication | -| `OIDC_REDIRECT_URI` | | | Absolute redirect URI for OIDC authentication | -| `OIDC_SERVER_APPLICATION_URL` | | | Absolute URL of the OIDC server application | -| `OIDC_SERVER_METADATA_URL` | | | URL to the OIDC provider metadata endpoint | -| `OIDC_CLAIM_ROLES` | | | OIDC claim containing user roles | -| `OIDC_ROLE_VIEWER` | | | Group value granting the User role (grants non-admins login when `OIDC_CLAIM_ROLES` is set) | -| `OIDC_ROLE_EDITOR` | | | Group value granting the User role (same effect as viewer) | -| `OIDC_ROLE_ADMIN` | | | Role value mapping to admin permissions | -| `OIDC_TLS_CACERTFILE` | | | Path to file containing trusted CA certificates | -| `OIDC_USERNAME_ATTRIBUTE` | `preferred_username` | | Attribute on OIDC user info used as the username | -| `OIDC_RP_INITIATED_LOGOUT` | `false` | | Enable RP-initiated logout flow | -| `OIDC_END_SESSION_ENDPOINT` | | | OIDC end-session endpoint override URL | +| Variable | Default | Required | Description | +| ----------------------------- | -------------------- | :------: | ------------------------------------------------------------------ | +| `OIDC_ENABLED` | `false` | | Enable OpenID Connect authentication | +| `OIDC_AUTOLOGIN` | `false` | | Skip the OIDC button on the login page and auto-redirect | +| `OIDC_ALLOW_REGISTRATION` | `true` | | Allow new accounts to be created automatically on first OIDC login | +| `OIDC_PROVIDER` | | | Name of the OIDC provider in use | +| `OIDC_CLIENT_ID` | | | Client ID for OIDC authentication | +| `OIDC_CLIENT_SECRET` | | | Client secret for OIDC authentication | +| `OIDC_REDIRECT_URI` | | | Absolute redirect URI for OIDC authentication | +| `OIDC_SERVER_APPLICATION_URL` | | | Absolute URL of the OIDC server application | +| `OIDC_SERVER_METADATA_URL` | | | URL to the OIDC provider metadata endpoint | +| `OIDC_CLAIM_ROLES` | | | OIDC claim containing user roles | +| `OIDC_ROLE_VIEWER` | | | Role value mapping to viewer permissions | +| `OIDC_ROLE_EDITOR` | | | Role value mapping to editor permissions | +| `OIDC_ROLE_ADMIN` | | | Role value mapping to admin permissions | +| `OIDC_TLS_CACERTFILE` | | | Path to file containing trusted CA certificates | +| `OIDC_USERNAME_ATTRIBUTE` | `preferred_username` | | Attribute on OIDC user info used as the username | +| `OIDC_RP_INITIATED_LOGOUT` | `false` | | Enable RP-initiated logout flow | +| `OIDC_END_SESSION_ENDPOINT` | | | OIDC end-session endpoint override URL | ### Metadata Providers @@ -137,6 +139,13 @@ | `YOUTUBE_BASE_URL` | `https://www.youtube.com` | | Base URL for alternate YouTube frontends (Piped, Invidious, etc.) | | `TINFOIL_WELCOME_MESSAGE` | `RomM Switch Library` | | Welcome message shown in Tinfoil Switch clients | +### Assets + +| Variable | Default | Required | Description | +| ----------------------------- | ----------- | :------: | ---------------------------------------------------------------------------------- | +| `MAX_ASSET_UPLOAD_SIZE_BYTES` | `536870912` | | Max size of a save/state/screenshot upload request in bytes (0 disables the limit) | +| `MAX_AUTOCLEANUP_LIMIT` | `100` | | Max number of saves a client can keep per slot when autocleanup is on (minimum 1) | + ### Logging | Variable | Default | Required | Description | @@ -186,3 +195,10 @@ | `POSTGRES_PASSWORD` | `authentik` | | Postgres password for the Authentik dev stack | | `AUTHENTIK_SECRET_KEY` | | | Authentik secret key | | `AUTHENTIK_BOOTSTRAP_PASSWORD` | | | Initial Authentik admin bootstrap password | + +### Emulator Streaming + +| Variable | Default | Required | Description | +| ------------------------- | ------- | :------: | --------------------------------------------------------------------------------- | +| `STREAMING_BROKER_SECRET` | | | - | +| `STREAMING_SAVE_TIMEOUT` | `45` | | Seconds to wait for a broker save-and-exit (raise if a broker has SAVE_WAIT > 45) | diff --git a/docs/resources/snippets/supported-platforms.md b/docs/resources/snippets/supported-platforms.md index 5fa9a5b4..429fd6c3 100644 --- a/docs/resources/snippets/supported-platforms.md +++ b/docs/resources/snippets/supported-platforms.md @@ -136,7 +136,7 @@ | Exidy Sorcerer | `exidy-sorcerer` | igdb logo screenscraper logo mobygames logo launchbox logo | | Fairchild Channel F | `fairchild-channel-f` | igdb logo screenscraper logo mobygames logo launchbox logo hasheous logo retroachivements logo libretro logo | | Family Computer | `famicom` | igdb logo screenscraper logo mobygames logo launchbox logo retroachivements logo libretro logo | -| Family Computer Disk System | `fds` | igdb logo screenscraper logo launchbox logo hasheous logo libretro logo | +| Family Computer Disk System | `fds` | igdb logo screenscraper logo launchbox logo hasheous logo retroachivements logo libretro logo | | Feature phone | `mobile-custom` | mobygames logo | | Ferranti Nimrod Computer | `nimrod` | igdb logo | | FM Towns | `fm-towns` | igdb logo screenscraper logo mobygames logo launchbox logo hasheous logo howlongtobeat logo | @@ -234,7 +234,7 @@ | MRE | `mre` | mobygames logo | | MSX | `msx` | igdb logo screenscraper logo mobygames logo launchbox logo hasheous logo retroachivements logo howlongtobeat logo libretro logo | | MSX Turbo R | `msx-turbo` | screenscraper logo | -| MSX2 | `msx2` | igdb logo screenscraper logo launchbox logo hasheous logo libretro logo | +| MSX2 | `msx2` | igdb logo screenscraper logo launchbox logo hasheous logo retroachivements logo libretro logo | | MUGEN | `mugen` | launchbox logo | | N-Gage | `ngage` | igdb logo screenscraper logo mobygames logo launchbox logo howlongtobeat logo | | N-Gage (service) | `ngage2` | mobygames logo | @@ -283,7 +283,8 @@ | Panasonic M2 | `panasonic-m2` | igdb logo | | Pandora | `pandora` | mobygames logo | | PC Booter | `pc-booter` | mobygames logo | -| PC Engine SuperGrafx | `supergrafx` | igdb logo screenscraper logo mobygames logo launchbox logo libretro logo | +| PC Engine SuperGrafx | `supergrafx` | igdb logo screenscraper logo mobygames logo launchbox logo retroachivements logo libretro logo | +| PC Win9X | `win9x` | screenscraper logo | | PC-50X Family | `pc-50x-family` | igdb logo | | PC-6001 | `pc-6001` | mobygames logo | | PC-8000 | `pc-8000` | mobygames logo | @@ -368,6 +369,7 @@ | Sord M5 | `sord-m5` | mobygames logo launchbox logo | | Spectravideo | `spectravideo` | screenscraper logo mobygames logo launchbox logo | | SRI-500/1000 | `sri-5001000` | mobygames logo | +| Steam | `steam` | | | SteamVR | `steam-vr` | igdb logo | | Sufami Turbo | `sufami-turbo` | screenscraper logo libretro logo | | Super A'Can | `super-acan` | igdb logo screenscraper logo mobygames logo | diff --git a/docs/using/uploads.md b/docs/using/uploads.md index 1221a695..42240dda 100644 --- a/docs/using/uploads.md +++ b/docs/using/uploads.md @@ -41,3 +41,4 @@ Multi-file uploads (e.g. multi-disc games) aren't supported via the UI. Instead, - **`413 Request Entity Too Large`**: your reverse proxy or ingress is capping body size (see [Reverse Proxy](../install/reverse-proxy.md) for the `client_max_body_size 0`/`proxy-body-size: "0"` fix). - **Upload progresses then fails at 99%**: the finalise step timed out. Usually reverse-proxy read timeout is too tight, so raise it. +- **Save, state, or screenshot upload rejected as too large**: these asset uploads are capped by `MAX_ASSET_UPLOAD_SIZE_BYTES` (default 512 MiB). Raise it, or set it to `0` to disable the limit (see [Environment Variables](../reference/environment-variables.md)). This is separate from ROM uploads, which are chunked and not subject to this cap. diff --git a/scripts/gen_platforms.py b/scripts/gen_platforms.py index 983a1ae9..f6995526 100644 --- a/scripts/gen_platforms.py +++ b/scripts/gen_platforms.py @@ -40,13 +40,13 @@ def main() -> int: return 1 backend = Path(romm_src).expanduser() / "backend" - script = backend / "utils" / "generate_supported_platforms.py" + script = backend / "tools" / "generate_supported_platforms.py" if not script.exists(): print(f"error: {script} not found (ROMM_SRC={romm_src})", file=sys.stderr) return 1 result = subprocess.run( - ["uv", "run", "python", "-m", "utils.generate_supported_platforms"], + ["uv", "run", "python", "-m", "tools.generate_supported_platforms"], cwd=backend, capture_output=True, text=True, diff --git a/scripts/sources.toml b/scripts/sources.toml index 0747e9f1..b3e9a8a8 100644 --- a/scripts/sources.toml +++ b/scripts/sources.toml @@ -7,4 +7,4 @@ repo = "rommapp/romm" # Set to a tag (e.g. "v5.0.0") or a full SHA. Generators fetch raw files # from raw.githubusercontent.com/${repo}/${ref}/... -ref = "master" +ref = "5.1.0-beta.2"