354 Commits

Author SHA1 Message Date
MingxuanGame
96c8b70df6 fix(chat): fix pydantic warnings for channel name 2026-01-11 16:38:03 +08:00
MingxuanGame
8923d714a7 feat(client-verification): add client verification (#104)
New configurations:

- `CHECK_CLIENT_VERSION` enables the check (default=True)
- `CLIENT_VERSION_URLS` contains a chain of valid client hashes. [osu!](https://osu.ppy.sh/home/download) and [osu! GU](https://github.com/GooGuTeam/osu/releases) are valid by default. View [g0v0-client-versions](https://github.com/GooGuTeam/g0v0-client-versions) to learn how to support your own client.

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-01-11 16:30:25 +08:00
MingxuanGame
1c3b309804 fix(user): missing the first entry 2026-01-03 16:37:55 +08:00
MingxuanGame
282eda3250 fix(user): order by id on favourite beatmapsets 2026-01-03 16:04:47 +08:00
MingxuanGame
87ffc6f581 perf(user): use keyset to boost user scores API & user beatmap API 2026-01-03 15:36:18 +08:00
dependabot[bot]
a6c596318e chore(deps): bump the minor-and-patch group with 4 updates (#99)
* chore(deps): bump the minor-and-patch group with 4 updates

Bumps the minor-and-patch group with 4 updates: [apscheduler](https://github.com/agronholm/apscheduler), [fastapi](https://github.com/fastapi/fastapi), [sqlmodel](https://github.com/fastapi/sqlmodel) and [datamodel-code-generator](https://github.com/koxudaxi/datamodel-code-generator).


Updates `apscheduler` from 3.11.1 to 3.11.2
- [Release notes](https://github.com/agronholm/apscheduler/releases)
- [Commits](https://github.com/agronholm/apscheduler/compare/3.11.1...3.11.2)

Updates `fastapi` from 0.126.0 to 0.128.0
- [Release notes](https://github.com/fastapi/fastapi/releases)
- [Commits](https://github.com/fastapi/fastapi/compare/0.126.0...0.128.0)

Updates `sqlmodel` from 0.0.27 to 0.0.30
- [Release notes](https://github.com/fastapi/sqlmodel/releases)
- [Changelog](https://github.com/fastapi/sqlmodel/blob/main/docs/release-notes.md)
- [Commits](https://github.com/fastapi/sqlmodel/compare/0.0.27...0.0.30)

Updates `datamodel-code-generator` from 0.46.0 to 0.49.0
- [Release notes](https://github.com/koxudaxi/datamodel-code-generator/releases)
- [Changelog](https://github.com/koxudaxi/datamodel-code-generator/blob/main/CHANGELOG.md)
- [Commits](https://github.com/koxudaxi/datamodel-code-generator/compare/0.46.0...0.49.0)

---
updated-dependencies:
- dependency-name: apscheduler
  dependency-version: 3.11.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: minor-and-patch
- dependency-name: fastapi
  dependency-version: 0.128.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: minor-and-patch
- dependency-name: sqlmodel
  dependency-version: 0.0.30
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: minor-and-patch
- dependency-name: datamodel-code-generator
  dependency-version: 0.49.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: minor-and-patch
...

Signed-off-by: dependabot[bot] <support@github.com>

* chore(linter): auto fix by pre-commit hooks

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2025-12-28 17:26:53 +08:00
MingxuanGame
fed1471129 fix(multiplayer): channel is not set as mp channel again 2025-12-27 19:55:42 +08:00
MingxuanGame
a58b4cb172 fix(multiplayer): channel is not set as mp channel 2025-12-27 19:30:09 +08:00
MingxuanGame
e5a4a0d9e4 fix(playlist): add playlist and room parameters to ScoreModel transform 2025-12-27 19:04:37 +08:00
MingxuanGame
f628061971 feat(score_token): add room_id to score token table 2025-12-20 19:42:14 +08:00
MingxuanGame
e0c3e06ffe fix(bbcode): fix ReDos vulnerabilities in BBCodeService (#96)
* fix(bbcode): fix ReDos of imagemap parsing

* fix(bbcode): use `regex` and add timeout to avoid too long time to parse

* feat(bbcode): use `make_tag` to generate HTML tags

* docs(bbcode): add docstrings for BBCodeService

* fix(user): validate BBCode content before processing userpage update

* fix(bbcode): catch timeout errors in BBCode parsing with MaliciousBBCodeError

* fix(bbcode): resolve reviews

* fix(bbcode): use `make_tag` in `_parse_size`

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* fix(bbcode): fix using `make_tag` in `_parse_size`

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-12-12 19:50:29 +08:00
MingxuanGame
36f5bd2ab3 fix(relationship): fix missing greenlet when adding friends 2025-12-06 01:58:57 +08:00
MingxuanGame
7b34bd8b0b feat(auth): add created_at and updated_at in OAuthToken
resolve #78
2025-11-23 13:56:28 +00:00
MingxuanGame
e049056534 fix(router): add 'user_preferences' for /me API 2025-11-23 13:45:48 +00:00
MingxuanGame
40da994ae8 refactor(database): use a new 'On-Demand' design (#86)
Technical Details: https://blog.mxgame.top/2025/11/22/An-On-Demand-Design-Within-SQLModel/
2025-11-23 21:41:02 +08:00
MingxuanGame
2bd770a995 fix(user): fix missing greenlet when invalidating cache 2025-11-09 09:35:21 +08:00
MingxuanGame
5c2687e1e4 feat(cache): add user cache invalidation for avatar, cover, and beatmapset updates 2025-11-08 18:14:51 +00:00
MingxuanGame
7d6d5696db feat(user): add api /api/v2/me/beatmapset-favourites 2025-11-08 13:02:33 +00:00
MingxuanGame
cf160f1357 feat(user-preference): restrict playmode update to official modes only 2025-10-26 14:18:00 +00:00
MingxuanGame
33f321952d feat(custom-rulesets): support custom rulesets (#23)
* feat(custom_ruleset): add custom rulesets support

* feat(custom-ruleset): add version check

* feat(custom-ruleset): add LegacyIO API to get ruleset hashes

* feat(pp): add check for rulesets whose pp cannot be calculated

* docs(readme): update README to include support for custom rulesets

* fix(custom-ruleset): make `rulesets` empty instead of throw a error when version check is disabled

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* chore(custom-ruleset): apply the latest changes of generator

c891bcd159

and

e25041ad3b

* feat(calculator): add fallback performance calculation for unsupported modes

* fix(calculator): remove debug print

* fix: resolve reviews

* feat(calculator): add difficulty calculation checks

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-10-26 21:10:36 +08:00
MingxuanGame
8f4a9d5fed feat(fetcher): use client_credentials grant type to avoid missing refresh token (#62)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-10-25 20:01:50 +08:00
MingxuanGame
2c81e22749 feat(calculator): support generate PerformanceAttributes & DifficultyAttributes from JSON Schema (#59)
Prepare for custom rulesets.

Schema Genetator: https://github.com/GooGuTeam/custom-rulesets/tree/main/CustomRulesetMetadataGenerator

```bash
dotnet -- schemas path/to/rulesets -o schema.json
```

```bash
python scripts/generate_ruleset_attributes.py schema.json 
```
2025-10-25 19:10:53 +08:00
咕谷酱
a4dbb9a167 feat(matchmaking): support matchmaking (#48) 2025-10-19 00:05:06 +08:00
MingxuanGame
8790ccad64 feat(pp-calculator): support other pp calculators (#57)
New configurations:

- CALCULATOR="rosu": specific pp calculator
- CALCULATOR_CONFIG='{}': argument passed through into calculator
2025-10-18 19:10:53 +08:00
咕谷酱
a10c07dc57 Align session verification logic with osu-web
Updated session verification method selection to match osu-web's State.php:36 logic, using SUPPORT_TOTP_VERIFICATION_VER for version checks and prioritizing TOTP when available. Added example environment files for osu-web-master to support local, dusk, and testing setups.
2025-10-12 03:34:38 +08:00
咕谷酱
0e2df8dfef Fix trusted_device flag inversion in session creation
Corrects the logic for the trusted_device parameter when creating login sessions by inverting its value. This ensures that the session accurately reflects whether the device is trusted or not.
2025-10-12 03:17:56 +08:00
咕谷酱
73d25c7604 Add Cloudflare Turnstile verification to auth flows
Introduces Cloudflare Turnstile verification for registration, OAuth password grant, and password reset endpoints (excluding osu! client). Adds related configuration options and a new service for token validation. Also refactors password change logic to support TOTP or password-based verification, improving security for users with TOTP enabled.
2025-10-12 02:39:46 +08:00
咕谷酱
6731373ded Add MailerSend and template-based email verification
Introduced support for MailerSend as an email provider alongside SMTP, with configuration options in settings. Added Jinja2-based multi-language email templates for verification emails, and refactored the email sending logic to use these templates and support language selection based on user country code. Updated related services and API endpoints to pass country code and handle new response formats. Added dependencies for Jinja2 and MailerSend.
2025-10-12 00:36:47 +08:00
MingxuanGame
a32976857f feat(score): invalidate cache when pin/unpin/reorder scores 2025-10-08 06:12:12 +00:00
MingxuanGame
6af0f814aa fix(user): restricted users cannot see their recent activities and kudosu 2025-10-08 06:08:10 +00:00
MingxuanGame
45ed9e51a9 feat(team): add playmode, description, website and statistics 2025-10-08 05:46:17 +00:00
MingxuanGame
e2f3c5099f fix(sessions): cannot find current session 2025-10-08 05:24:52 +00:00
MingxuanGame
3dd74fc703 fix(password): fix transaction has begun 2025-10-08 05:20:05 +00:00
MingxuanGame
85ac57a584 fix(password): missing import 2025-10-08 05:11:38 +00:00
MingxuanGame
fa81f837a0 fix(score): don't unpin score 2025-10-07 15:53:04 +00:00
MingxuanGame
60049a777f feat(auth): support change password 2025-10-07 13:07:14 +00:00
MingxuanGame
10caa82320 feat(user-preference): add user preference support (#55)
APIs:

- GET `/api/private/user/preferences`: Get current user's preferences.
- PATCH `/api/private/user/preferences`: Modify current user's preferences. (body: Preferences)
- PUT `/api/private/user/preferences`: Overwrite current user's preferences. (body: Preferences)
- DELETE `/api/private/user/preferences`: Reset current user's preferences. (body: list[str])
  - body specifies the content to be reset. If body is empty, reset all preferences.

User:

- `User.g0v0_playmode`: show the special ruleset like `OSURX`, and custom rulesets in the future.

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-10-06 20:57:17 +08:00
MingxuanGame
febc1d761f feat(user): implement user restrictions
## APIs Restricted for Restricted Users

A restricted user is blocked from performing the following actions, and will typically receive a `403 Forbidden` error:

*   **Chat & Notifications:**
    *   Sending any chat messages (public or private).
    *   Joining or leaving chat channels.
    *   Creating new PM channels.
*   **User Profile & Content:**
    *   Uploading a new avatar.
    *   Uploading a new profile cover image.
    *   Changing their username.
    *   Updating their userpage content.
*   **Scores & Gameplay:**
    *   Submitting scores in multiplayer rooms.
    *   Deleting their own scores (to prevent hiding evidence of cheating).
*   **Beatmaps:**
    *   Rating beatmaps.
    *   Taging beatmaps.
*   **Relationship:**
    *   Adding friends or blocking users.
    *   Removing friends or unblocking users.
*   **Teams:**
    *   Creating, updating, or deleting a team.
    *   Requesting to join a team.
    *   Handling join requests for a team they manage.
    *   Kicking a member from a team they manage.
*   **Multiplayer:**
    *   Creating or deleting multiplayer rooms.
    *   Joining or leaving multiplayer rooms.

## What is Invisible to Normal Users

*   **Leaderboards:**
    *   Beatmap leaderboards.
    *   Multiplayer (playlist) room leaderboards.
*   **User Search/Lists:**
    *   Restricted users will not appear in the results of the `/api/v2/users` endpoint.
    *   They will not appear in the list of a team's members.
*   **Relationship:**
    *   They will not appear in a user's friend list (`/friends`).
*   **Profile & History:**
    *   Attempting to view a restricted user's profile, events, kudosu history, or score history will result in a `404 Not Found` error, effectively making their profile invisible (unless the user viewing the profile is the restricted user themselves).
*   **Chat:**
    *   Normal users cannot start a new PM with a restricted user (they will get a `404 Not Found` error).
*   **Ranking:**
    *   Restricted users are excluded from any rankings.

### How to Restrict a User

Insert into `user_account_history` with `type=restriction`.

```sql
-- length is in seconds
INSERT INTO user_account_history (`description`, `length`, `permanent`, `timestamp`, `type`, `user_id`) VALUE ('some description', 86400, 0, '2025-10-05 01:00:00', 'RESTRICTION', 1);
```

---

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-10-06 11:10:25 +08:00
MingxuanGame
1db34bf5c5 feat(sync): add configuration to control syncing & support sync immediately by API 2025-10-05 03:44:46 +00:00
MingxuanGame
8884f8993c fix(beatmap): refresh current_user in batch_get_beatmaps response 2025-10-04 17:28:42 +00:00
MingxuanGame
38671cd471 feat(user): implement /users/{user_id}/beatmaps-passed
close #9
2025-10-04 09:52:15 +00:00
MingxuanGame
3f702dc5ec fix(auth): add API version check in login 2025-10-04 08:51:38 +00:00
MingxuanGame
6c23694061 fix(beatmap): refresh current user data in lookup_beatmap function 2025-10-04 08:43:48 +00:00
MingxuanGame
1163a93053 refactor(scores): rename models of score to match with filename 2025-10-04 08:01:38 +00:00
MingxuanGame
9fe493a12e refactor(cache): remove unused cache management and monitoring endpoints 2025-10-04 07:35:58 +00:00
MingxuanGame
00f53f0dc0 feat(beatmap): add asset_proxy_response decorator to beatmap lookup endpoints 2025-10-04 07:32:35 +00:00
MingxuanGame
216d3ab3bf feat(redis): refactor Redis configuration to use multiple logical databases
- Updated default REDIS_URL to remove explicit /0 suffix
- Added dedicated Redis clients:
  - db0: general cache (redis_client)
  - db1: message cache (redis_message_client)
  - db2: binary storage (redis_binary_client)
  - db3: rate limiting (redis_rate_limit_client)
- Updated configuration, Docker files, and main startup lifecycle accordingly
- Replaced `get_redis()` usage in notification server with `redis_message_client`
2025-10-04 05:39:59 +00:00
MingxuanGame
7c18fc5fb6 refactor(userpage): move APIs into g0v0 private API 2025-10-04 04:57:24 +00:00
MingxuanGame
2bfde24b84 fix(log): fix typing & exception logs 2025-10-03 17:27:47 +00:00
MingxuanGame
046f894407 refactor(assets_proxy): use decorators to simplify code 2025-10-03 17:12:28 +00:00