138 Commits

Author SHA1 Message Date
Georges-Antoine Assi
e5cb29ae80
Merge branch 'master' into feature/play-session-ingest 2026-04-06 12:42:15 -04:00
Georges-Antoine Assi
f2619ac0d1
Merge branch 'master' into pegasus-metadata-export 2026-04-06 11:06:08 -04:00
nendo
75302ed59a Add play session ingest for game time tracking
Backend API for collecting and querying play sessions, modeled after
the Argosy session data format. Clients submit batches per device,
recording both the session window and screen-on time.
2026-03-22 20:22:55 +09:00
Georges-Antoine Assi
770b8f94ac
feat: add Pegasus Frontend metadata export support
Add metadata.pegasus.txt export alongside the existing gamelist.xml
export. Restructure the export system: rename the gamelist endpoint to
a general-purpose export endpoint (`/api/export/`) with sub-routes for
each format (`/gamelist-xml`, `/pegasus`). Move config from flat
`scan.export_gamelist` to nested `scan.export.gamelist_xml` and
`scan.export.pegasus` for auto-export on scan.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 16:09:20 -04:00
Georges-Antoine Assi
e6ddc5da11
bot attempt at save sync 2026-03-14 22:13:38 -04:00
nendo
e0b25fbc6c feat(client-tokens): add client API tokens with QR pairing flow
Long-lived, revocable, scope-restricted tokens for external clients
(mobile apps, retro handhelds, third-party tools). Includes:

- Backend: model, migration, DB handler, auth integration (rmm_ prefix
  routing in HybridAuthBackend), CRUD + pairing + exchange endpoints,
  rate limiting, scope intersection enforcement, admin oversight
- Frontend: settings page with token management table, stepped
  create/deliver dialog (config -> copy/pair), QR code with RomM logo,
  admin token table, standalone /pair page for QR scan landing
- /pair page supports custom-scheme callbacks for app deep linking,
  falls back to displaying code for manual entry
- 33 backend tests across 5 classes (CRUD, auth, isolation, pairing,
  admin)
2026-03-11 10:56:35 +09:00
Georges-Antoine Assi
f6b11d3bde
split out rom endpoints 2026-03-08 14:51:28 -04:00
Georges-Antoine Assi
a999e7e055
move under rom subfolder 2026-03-08 14:22:30 -04:00
Alan Frigo
d21ce46142 feat: Implement chunked ROM uploads with new API endpoints, client-side chunking logic, and Nginx configuration. 2026-03-06 13:52:06 -03:00
nendo
36eec298d1 Add device-based save synchronization
Implement device registration and save sync tracking to enable
multi-device save management with conflict detection.

- Device CRUD endpoints (POST/GET/PUT/DELETE /api/devices)
- Save sync state tracking per device
- Conflict detection on upload (409 when device has stale sync)
- Download sync tracking (optimistic and confirmed modes)
- Track/untrack saves per device
- DEVICES_READ/WRITE scopes for authorization
2026-01-18 16:50:44 +09:00
Georges-Antoine Assi
e1a4e42171
Merge branch 'master' into emujs-netplay 2025-11-25 11:28:43 -05:00
Georges-Antoine Assi
ec6bb24662
Add new redis-backed session middleware 2025-11-22 10:47:59 -05:00
Georges-Antoine Assi
8c769a5fe8
hacks with working netplayu 2025-11-21 19:15:20 -05:00
Georges-Antoine Assi
82ca819ab2
start work on netplay endpoints 2025-11-21 11:25:31 -05:00
Georges-Antoine Assi
551ff72a8a
implement csrf middleware directly in repo 2025-11-17 21:12:29 -05:00
Georges-Antoine Assi
3cfc52234a
start work on gamelist.xml extraction 2025-10-16 23:16:39 -04:00
Georges-Antoine Assi
6d1218246b
Set same_site to lax on session cookie if OIDC enabled 2025-10-07 10:40:25 -04:00
Georges-Antoine Assi
9311d0d95f
Drop log middleware 2025-10-03 11:13:16 -04:00
Michael Manganiello
e4e3928d1b
misc: Apply import sorting 2025-09-04 11:17:00 -03:00
Michael Manganiello
63f84b78d5
misc: Create startup script to run initial tasks before main application
For steps that need to run before the web application starts, such as
scheduling tasks, this new `startup.py` script is introduced.

This fixes a recently introduced issue where task scheduling was not
being triggered, because of it being included in the
`if __name__ == "__main__":` block, which is not executed when
the application is run by Gunicorn in production environments.

We do not include this logic as part of FastAPI's lifespan
implementation, as running multiple workers with Gunicorn would
cause this logic to be executed multiple times.
2025-08-12 23:14:26 -03:00
Georges-Antoine Assi
836e7358c2
fix issues from code review 2025-08-07 09:34:43 -04:00
Georges-Antoine Assi
e156158a3e
fixse from bot review 2025-08-06 22:16:46 -04:00
Georges-Antoine Assi
6b307afcd3
Run worker as a native process 2025-08-06 21:57:32 -04:00
Michael Manganiello
f96adeeaee
misc: Upgrade to Python 3.13
Small changes to upgrade Python to version 3.13, and fixes based on a
`pyupgrade` run using the `--py313-plus` flag.
2025-07-03 23:37:00 -03:00
Michael Manganiello
fe1a9ce2a7
fix: Use aiohttp for RetroAchievements API calls
This change replaces the `httpx` client with `aiohttp` for the
RetroAchievements API service.

The main reason for this change is that `httpx` has an unavoidable log
line with `INFO` level, which includes the request full URL, containing
the user's API key.

`httpx` has had an
[open discussion](https://github.com/encode/httpx/discussions/2765)
regarding this security issue for almost two years.

The change to `aiohttp` is painless, and would allow us to migrate more
of the codebase to it in the future, to avoid leaking sensitive
information in logs.
2025-06-09 09:59:56 -03:00
zurdi
1de6e7afb2
refactor: move LOGGING_CONFIG to log_middleware.py for better organization 2025-05-27 10:38:15 +00:00
zurdi
491d351eb1
feat: implement custom logging middleware and configure logging settings 2025-05-23 00:15:33 +00:00
Georges-Antoine Assi
f1f627f7c5
working pagination on roms endpoint 2025-03-14 21:10:30 -04:00
Michael Manganiello
865370ec13
misc: Move auth constants to separate file
This simplifies avoiding circular imports when trying to use auth
handlers.
2025-01-08 22:16:31 -03:00
Michael Manganiello
7dc7eea34d
feat: Initial Sentry support
This change initializes the Sentry SDK, which enables error tracking
when the `SENTRY_DSN` environment variable is set.

Drop-in alternatives to Sentry are also supported, like GlitchTip.
2024-12-27 17:03:45 -03:00
Georges-Antoine Assi
bc5c2e45f3
wokring oidc setup with authentik 2024-11-26 23:57:15 -05:00
Georges-Antoine Assi
f5941ec332
[ROMM-1218] Exempt the right path from CSRF protection for tokens 2024-11-17 13:42:48 -05:00
Georges-Antoine Assi
deae0b9f74
set docs and recod paths 2024-09-03 21:59:30 -04:00
Georges-Antoine Assi
9281760975
merge gzip changes into branch 2024-08-13 00:31:48 -04:00
Zurdi
ada7f5f837
Merge branch 'master' into fix/csrf-token 2024-08-05 20:16:52 +02:00
Georges-Antoine Assi
d17cdd6875
hopefully actually fix csrf tokens 2024-08-05 13:13:25 -04:00
Michael Manganiello
45aeaf3265
fix: Backend URL redirection logic
Fix FastAPI and nginx configuration, to make the application correctly
redirect URLs. This is specially useful when URLs ended with forward
slash are redirected to their stripped version.

Included changes:
* Stop removing the `/api` prefix in nginx rewrite rules, so FastAPI
  knows what's the original URL path being requested.
* Use `$http_host` in nginx, so FastAPI receives both the original host
  and port, to build the redirect URL (as `$host` does not include the
  port, if present).
* Make all FastAPI included routers know their prefix, to correctly
  route incoming requests.

This fix was found based on a report that redirects from URLs ended with
forward slash were not working [1].

[1] https://github.com/rommapp/romm/issues/1051#issuecomment-2269049762
2024-08-05 11:15:52 -03:00
Michael Manganiello
749e4d65c1
misc: Use PYTEST_VERSION variable to detect Pytest runs
Pytest v8.2 introduced the `PYTEST_VERSION` environment variable [1],
that can be used to check if code is running from within a pytest run.

This way, we can avoid checking the loaded `sys` modules.

[1] https://docs.pytest.org/en/stable/changelog.html#id57
2024-07-27 12:03:44 -03:00
Michael Manganiello
b9da72832d
Merge pull request #1011 from rommapp/misc/migrate-moby-handler-to-async
misc: Migrate MobyGamesHandler to async
2024-07-23 11:10:27 -03:00
Michael Manganiello
7c6dfa8e50
feat: Use ContextVar to share httpx AsyncClient instance between requests 2024-07-23 01:29:32 -03:00
Michael Manganiello
1ce20cdcfc
fix: Use namespaced cookie for session
Avoid conflicting cookie names when RomM runs in the same host as other
applications, by adding a `romm_` namespace to the session cookie.
2024-07-20 21:06:28 -03:00
Michael Manganiello
d94f5428a8
misc: Enable GZip compression for backend responses
With the introduction of non-paginated responses for ROMs, JSON
responses for big collection could easily be at >1MiB.

This change adds a FastAPI-provided middleware to enable GZip
compression for responses greater than 1KiB.
2024-07-13 16:10:46 -03:00
Michael Manganiello
b61bb11bce
feat: Use async requests to retrieve SteamGridDB covers
This change avoids blocking requests when retrieving covers from
SteamGridDB, which is the main bottleneck as the current implementation
iterates over paginated results for multiple games.

Using an asynchronous client like `httpx` provides a good performance
improvement, and reduces the latency when calling this endpoint.
Also, the inclusion of FastAPI `lifespan` allows instantiating a single
client on startup.

When testing with "Final Fantasy V Advance", the endpoint goes from ~9s
to ~1.5s to retrieve all covers.
2024-07-09 22:37:14 -03:00
zurdi
3d27a05c22
fixes from trunk 2024-07-04 23:47:14 +02:00
zurdi
2ec4debd61
setup wizard added 2024-07-04 14:19:00 +02:00
zurdi
1d6ba70080
collections get_roms endpoint added 2024-07-02 14:31:27 +02:00
Georges-Antoine Assi
9b62641d55
Merge branch 'master' into trunk-io 2024-05-31 18:42:43 -04:00
Georges-Antoine Assi
95412760be
Remove pagination from roms endpoints 2024-05-31 12:15:52 -04:00
Georges-Antoine Assi
b075e93321
Merge branch 'master' into trunk-io 2024-05-24 16:47:19 -04:00
Georges-Antoine Assi
f73a6f48b9
more refactoring 2024-05-23 21:13:17 -04:00