Commit Graph

128 Commits

Author SHA1 Message Date
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
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
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
咕谷酱
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
fa81f837a0 fix(score): don't unpin score 2025-10-07 15:53:04 +00: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
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
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
7c18fc5fb6 refactor(userpage): move APIs into g0v0 private API 2025-10-04 04:57:24 +00:00
MingxuanGame
046f894407 refactor(assets_proxy): use decorators to simplify code 2025-10-03 17:12:28 +00:00
MingxuanGame
d490239f46 chore(linter): update ruff rules 2025-10-03 15:46:53 +00:00
MingxuanGame
0d9019c6cc refactor(signalr): remove SignalR server & msgpack_lazer_api
Maybe we can make `msgpack_lazer_api` independent?
2025-10-03 13:20:12 +00:00
MingxuanGame
d23f32f08d refactor(log): refactor the whole project
format: {time:YYYY-MM-DD HH:mm:ss} [{level}] | {name} | {message}
{name} is:
- Uvicorn: log from uvicorn server (#228B22)
- Service: log from class of `app.service` (blue)
- Fetcher: log from fetchers (magenta)
- Task: log from `app.tasks` (#FFD700)
- System: log from `system_logger` (red)
- Normal: log from `log(name)` (#FFC1C1)
- Default: the module name of caller

if you are writing services or tasks, you can just call `logger.`, we will pack it with name `Service` or `Task`
if you want to print fetcher logs, system-related logs, or normal logs, use `logger = (fetcher_logger / system_logger / log)(name)`
2025-10-03 11:53:05 +00:00
MingxuanGame
fce88272b5 refactor(task): move schedulers and startup/shutdown task into tasks directory 2025-10-03 10:15:22 +00:00
MingxuanGame
346c2557cf refactor(api): use Annotated-style dependency injection 2025-10-03 05:41:31 +00:00
MingxuanGame
37b4eadf79 refactor(database): rename filename to find the models by table name easily 2025-10-03 03:33:47 +00:00
MingxuanGame
40670c094b feat(auth): support trusted device (#52)
New API to maintain sessions and devices:

- GET /api/private/admin/sessions
- DELETE /api/private/admin/sessions/{session_id}
- GET /api/private/admin/trusted-devices
- DELETE /api/private/admin/trusted-devices/{device_id}

Auth:

web clients request `/oauth/token` and `/api/v2/session/verify` with `X-UUID` header to save the client as trusted device.

---------

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-10-03 11:26:43 +08:00
MingxuanGame
9a77c8d246 feat(beatmapset): use https://catboy.best as global downloading service 2025-10-02 14:50:36 +00:00
MingxuanGame
f31056ced3 perf(score): divide score processing into small parts and make them run in background
resolve #47
2025-10-02 14:30:57 +00:00
MingxuanGame
3f6776847e feat(beatmap,score): update beatmaps from Bancho & deleting scores (#50)
New API:

- DELETE /api/private/score/{score_id}: delete a score
- POST /api/private/beatmapsets/{beatmapset_id}/sync: request for syncing a beatmapset

New configuration:

- OLD_SCORE_PROCESSING_MODE
2025-10-02 13:36:09 +08:00
MingxuanGame
017b058e63 chore(linter): make linter happy 2025-09-30 07:57:08 +00:00
咕谷酱
3a434ee02c 修复部分报错 2025-09-24 03:04:09 +08:00
咕谷酱
86c7bbb74e 优化验证 2025-09-24 02:08:13 +08:00
咕谷酱
8054281b15 添加防止重放攻击 2025-09-24 00:35:57 +08:00
咕谷酱
79805c2858 Update ranking.py 2025-09-23 02:37:04 +08:00
咕谷酱
0cd10bc543 修复排行榜返回用户数量问题 2025-09-23 02:36:20 +08:00
咕谷酱
bb06643de8 fix error 2025-09-23 01:56:50 +08:00
咕谷酱
f8e5fdc08e 添加排行榜/战队 total字段 2025-09-23 01:54:00 +08:00
咕谷酱
edbf01daa1 添加谱面查询缓存 2025-09-23 01:34:43 +08:00
MingxuanGame
1527e23b43 feat(session-verify): 添加 TOTP 支持 (#34)
* chore(deps): add pyotp

* feat(auth): implement TOTP verification

feat(auth): implement TOTP verification and email verification services

- Added TOTP keys management with a new database model `TotpKeys`.
- Introduced `EmailVerification` and `LoginSession` models for email verification.
- Created `verification_service` to handle email verification logic and TOTP processes.
- Updated user response models to include session verification methods.
- Implemented routes for TOTP creation, verification, and fallback to email verification.
- Enhanced login session management to support new location checks and verification methods.
- Added migration script to create `totp_keys` table in the database.

* feat(config): update config example

* docs(totp): complete creating TOTP flow

* refactor(totp): resolve review

* feat(api): forbid unverified request

* fix(totp): trace session by token id to avoid other sessions are forbidden

* chore(linter): make pyright happy

* fix(totp): only mark sessions with a specified token id
2025-09-21 19:50:11 +08:00
MingxuanGame
bef303cc93 fix(ranking): missing arguments when calling get_country_ranking 2025-09-21 05:28:28 +00:00
MingxuanGame
ca9a2abc6f fix(ranking): remove redirect to make client to access
Client will not attach `Authorization` to the redirected request
2025-09-21 05:23:06 +00:00
MingxuanGame
ad78663ba0 chore(linter): make ruff happy 2025-09-20 10:41:15 +00:00
咕谷酱
08ff35509e 修复代理问题,添加头像接口 2025-09-19 17:02:24 +08:00
咕谷酱
0b43f2aad8 支持个人介绍编辑 2025-09-16 00:33:46 +08:00
咕谷酱
6baaeda1af 修复 kudosu 422 错误 2025-09-15 18:22:27 +08:00
咕谷酱
fa6b7487aa 占位 kudosu 接口 2025-09-15 18:11:45 +08:00