Commit Graph

57 Commits

Author SHA1 Message Date
Alejandro González
6dbd1e5236 fix(labrinth): make orgs with a single user and only approved projects visible to non-logged-in people (#4557)
I made a typo on PR https://github.com/modrinth/code/pull/4426 by making
the corresponding SQL query filter by projects with an unexisting
`public` status, instead of `approved`. During my testing, I used the
`archived` status, so I didn't notice it back then.
2025-10-15 18:16:44 +00:00
aecsocket
e66b131a5d See available funds history and withdrawls in user payout history (#4537)
* Add GET /v3/payouts/history

* V3 backwards compat

* Sqlx prepare

* Include user ID in GET /v3/payout
2025-10-11 10:51:38 +00:00
aecsocket
aec49cff7c Include both analytics v1 and v2 in tree (#4527)
* Include both analytics v1 and v2 in tree

* fix sqlx cache

* fix tests
2025-10-10 14:58:19 +00:00
Prospector
e9735bd9ba Revert "Analytics backend V2 (#4408)" (#4524)
This reverts commit 6919c8dea9.
2025-10-08 19:01:32 +00:00
aecsocket
6919c8dea9 Analytics backend V2 (#4408)
* start with analytics v2

* the big ass SQL query™

* downloads and views analytics working

* Implement analytics bucketing API

* allow filtering by monetization

* Use a new format for project metrics and bucketing

* revenue API works

* Add country data to analytics API

* Add checks for number of slices and time slice resolution

* work on docs

* wip: fix tests and add docs

* Fix tests

* Fix tests

* Uncomment crates

* feat: frontend CLAUDE.md (#4433)

* Slight tweaks to time slicing logic

* More tweaks

* Fix error messages

* Fix sqlx cache

---------

Co-authored-by: Calum H. <contact@cal.engineer>
2025-10-07 22:01:10 +00:00
François-Xavier Talbot
9589e23118 Link customer ID to Anrok transaction (#4509)
* Mark transactions with unresolvable addresses as unresolved

* Add customer_name + customer_id to anrok transactions

* Increase rate of Anrok syn

* Remove timer from update_tax_transactions

* chore: query cache, clippy, fmt
2025-10-06 16:06:57 +00:00
François-Xavier Talbot
7e84659249 Cleanup + fixes to index_billing/index_subscriptions (#4457)
* Parse refunds

* Cleanup index subscriptions/index billing

* chore: query cache, clippy, fmt
2025-10-03 13:01:52 +00:00
François-Xavier Talbot
beb1bdb31f Skip synchronizing transactions to Anrok if missing payment intent ID (#4446)
* Skip succeeded txns with no payment platform ID

* chore: query cache, clippy, fmt
2025-09-30 14:36:41 +00:00
François-Xavier Talbot
54747aa628 Tweaks and fixes to background tasks (#4447)
* adjustments

* chore: query cache, clippy, fmt
2025-09-30 11:43:59 +00:00
Emma Alexia
324ad65d7c Fix user deletion with new notification_deliveries table (#4437) 2025-09-29 18:04:22 +00:00
François-Xavier Talbot
b4eba5a0d5 Tax fixes (#4435)
* Only update the PaymentMethod ID if not using placeholder ID

* comment

* Create Anrok transactions for all charges

* Fix comment

* Prefer using payment method's address rather than customer address

* chore: query cache, clippy, fmt

* Retrieve stripe address from PM

* chore: query cache, clippy, fmt

* fmt

* bring back the query cache

* Better address retrieval for updating tax amounts, always update tax_last_updated

* chore: query cache, clippy, fmt

* Don't set PM in ctoken interactive session for new PIs
2025-09-28 21:13:48 +00:00
Alejandro González
bb9ce52c9d feat(labrinth): hide orgs without a purpose, re-enable organization creation (#4426)
* chore(labrinth): set `DELPHI_URL` to a valid default in `.env.local`

* feat(labrinth): make orgs not publicly visible until they meet some conditions

* Revert "Org disabled frontend (#4424)"

This reverts commit 2492b11ec0.

* changelog: update for re-enabling organization creation

* chore: run `sqlx prepare`

* chore(labrinth): tweak tests to work with new org changes

* tweak: apply @triphora's suggestion

Co-authored-by: Emma Alexia <emma@modrinth.com>
Signed-off-by: Alejandro González <7822554+AlexTMjugador@users.noreply.github.com>

* tweak: document `is_visible_organization` relationship with `Project#is_searchable`

---------

Signed-off-by: Alejandro González <7822554+AlexTMjugador@users.noreply.github.com>
Co-authored-by: Emma Alexia <emma@modrinth.com>
2025-09-26 15:42:53 +00:00
François-Xavier Talbot
14af3d0763 Billing fixes (#4422)
* Only update the PaymentMethod ID if not using placeholder ID

* comment

* Create Anrok transactions for all charges

* Fix comment

* Prefer using payment method's address rather than customer address

* chore: query cache, clippy, fmt
2025-09-26 15:39:47 +00:00
François-Xavier Talbot
4228a193e9 Charge tax on products (#4361)
* Initial Anrok integration

* Query cache, fmt, clippy

* Fmt

* Use payment intent function in edit_subscription

* Attach Anrok client, use payments in index_billing

* Integrate Anrok with refunds

* Bug fixes

* More bugfixes

* Fix resubscriptions

* Medal promotion bugfixes

* Use stripe metadata constants everywhere

* Pre-fill values in products_tax_identifiers

* Cleanup billing route module

* Cleanup

* Email notification for tax charge

* Don't charge tax on users which haven't been notified of tax change

* Fix taxnotification.amount templates

* Update .env.docker-compose

* Update .env.local

* Clippy

* Fmt

* Query cache

* Periodically update tax amount on upcoming charges

* Fix queries

* Skip indexing tax amount on charges if no charges to process

* chore: query cache, clippy, fmt

* Fix a lot of things

* Remove test code

* chore: query cache, clippy, fmt

* Fix money formatting

* Fix conflicts

* Extra documentation, handle tax association properly

* Track loss in tax drift

* chore: query cache, clippy, fmt

* Add subscription.id variable

* chore: query cache, clippy, fmt

* chore: query cache, clippy, fmt
2025-09-25 11:29:29 +00:00
François-Xavier Talbot
47020f34b6 Tax compliance adjustments (#4414)
* tax compliance adjustments

* chore: query cache, clippy, fmt
2025-09-25 11:02:33 +00:00
François-Xavier Talbot
71d63fbe17 Fix version upload for popular projects (#4410)
* Only notify users that exist

* chore: query cache, clippy, fmt
2025-09-22 15:12:17 -07:00
aecsocket
20281c4efc Allow users to manage their own affiliate codes (#4392)
* Allow users to manage their own affiliate codes

* Add a badge to restrict access to affiliate codes

* sqlx prepare and clippy
2025-09-22 16:54:09 +00:00
aecsocket
4def0e8407 Initial affiliate codes implementation (#4382)
* Initial affiliate codes implementation

* some more docs to codes

* sqlx prepare

* Address PR comments

* Address more PR comments

* fix clippy

* Switch to using Json<T> for type-safe responses
2025-09-18 15:43:34 +00:00
François-Xavier Talbot
6da190ed01 New Creator Notifications (#4383)
* Some new notification types

* Fix error

* Use existing DB models rather than inline queries

* Fix template fillout

* Fix ModerationThreadMessageReceived

* Insert more notifications, fix some formatting

* chore: query cache, clippy, fmt

* chore: query cache, clippy, fmt

* Use outer transactions to insert notifications instead of creating a new one

* Join futures
2025-09-17 19:37:21 +00:00
François-Xavier Talbot
902d749293 [DO NOT MERGE] Email notification system (#4338)
* Migration

* Fixup db models

* Redis

* Stuff

* Switch PKs to BIGSERIALs, insert to notifications_deliveries when inserting notifications

* Queue, templates

* Query cache

* Fixes, fixtures

* Perf, cache template data & HTML bodies

* Notification type configuration, ResetPassword notification type

* Reset password

* Query cache

* Clippy + fmt

* Traces, fix typo, fix user email in ResetPassword

* send_email

* Models, db

* Remove dead code, adjust notification settings in migration

* Clippy fmt

* Delete dead code, fixes

* Fmt

* Update apps/labrinth/src/queue/email.rs

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Signed-off-by: François-Xavier Talbot <108630700+fetchfern@users.noreply.github.com>

* Remove old fixtures

* Unify email retry delay

* Fix type

* External notifications

* Remove `notifications_types_preference_restrictions`, as user notification preferences is out of scope for this PR

* Query cache, fmt, clippy

* Fix join in get_many_user_exposed_on_site

* Remove migration comment

* Query cache

* Update html body urls

* Remove comment

* Add paymentfailed.service variable to PaymentFailed notification variant

* Fix compile error

* Fix deleting notifications

* Update apps/labrinth/src/database/models/user_item.rs

Co-authored-by: Josiah Glosson <soujournme@gmail.com>
Signed-off-by: François-Xavier Talbot <108630700+fetchfern@users.noreply.github.com>

* Update apps/labrinth/src/database/models/user_item.rs

Co-authored-by: Josiah Glosson <soujournme@gmail.com>
Signed-off-by: François-Xavier Talbot <108630700+fetchfern@users.noreply.github.com>

* Update Cargo.toml

Co-authored-by: Josiah Glosson <soujournme@gmail.com>
Signed-off-by: François-Xavier Talbot <108630700+fetchfern@users.noreply.github.com>

* Update apps/labrinth/migrations/20250902133943_notification-extension.sql

Co-authored-by: Josiah Glosson <soujournme@gmail.com>
Signed-off-by: François-Xavier Talbot <108630700+fetchfern@users.noreply.github.com>

* Address review comments

* Fix compliation

* Update apps/labrinth/src/database/models/users_notifications_preferences_item.rs

Co-authored-by: Josiah Glosson <soujournme@gmail.com>
Signed-off-by: François-Xavier Talbot <108630700+fetchfern@users.noreply.github.com>

* Use strfmt to format emails

* Configurable Reply-To

* Configurable Reply-To

* Refactor for email background task

* Send some emails inline

* Fix account creation email check

* Revert "Use strfmt to format emails"

This reverts commit e0d6614afe51fa6349918377e953ba294c34ae0b.

* Reintroduce fill_template

* Set password reset email inline

* Process more emails per index

* clippy fmt

* Query cache

---------

Signed-off-by: François-Xavier Talbot <108630700+fetchfern@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Josiah Glosson <soujournme@gmail.com>
2025-09-15 19:02:29 +00:00
François-Xavier Talbot
d8d9720495 Only Fire Slack Webhook Once a Day (#4368)
* Only send webhook once per day

* pat clippy's back

* damn query cache
2025-09-11 23:38:22 +00:00
Emma Alexia
c017038f71 Fix error when trying to delete user with uploaded images (#4295)
* Fix error when trying to delete user with uploaded images

`{"error":"database_error","description":"Database Error: Error while interacting with the database: error returned from database: update or delete on table \"users\" violates foreign key constraint \"uploaded_images_owner_id_fkey\" on table \"uploaded_images\""}`

* Update certain things to use Ghost instead of deleting entirely

* Fix mistake
2025-09-06 23:05:34 +00:00
François-Xavier Talbot
006b19e3c9 Creator tax compliance (#4254)
* Initial implementation

* Remove test code

* Query cache

* Appease clippy

* Precise TIN/SSN

* Make tax threshold customizable via env variable

* Address review comments
2025-08-25 16:34:58 +00:00
François-Xavier Talbot
9497ba70a4 Offers, redemption, preview subscriptions (#4121)
* Initial db migration/impl, guarded partner routes

* Add guard to /redeem

* Add `public` column to products prices, only expose public prices

* Query cache

* Add partner subscription type

* 5 days subscription interval, metadata

* Create server on redeem

* Query cache

* Fix race condition

* Unprovision Medal subscriptions

* Consider due expiring charge as unprovisionable

* Query cache

* Use a queue

* Promote to full subscription, fmt + clippy

* Patch expiring charge on promotion, comments

* Additional comments

* Add `tags` field to Archon /create request

* Address review comments

* Query cache

* Final fixes to edit_subscription

* Appease clippy

* fmt
2025-08-11 21:40:58 +00:00
Alejandro González
c7d0839bfb fix(labrinth): retire Sendy for new email newsletter subscriptions (#4073)
* tweak(frontend): do not sign up for the newsletter by default

* fix(labrinth): retire Sendy for new email newsletter subscriptions
2025-07-29 09:51:50 +00:00
Alejandro González
358cf31c87 feat(labrinth): basic offset pagination for moderation reports and projects (#4063) 2025-07-26 12:32:35 +00:00
Emma Alexia
bcf46d440b Count failed payments as "open" charges (#4013)
This allows people to cancel failed payments, currently it fails with error "There is no open charge for this subscription"
2025-07-19 14:33:37 +00:00
Jai Agrawal
33d26238ce Fix revenue route incorrect filter (and commit bank transaction) (#3874)
* Fix revenue route incorrect filtering

* Actually commit transaction
2025-06-30 14:45:23 -07:00
Jai Agrawal
8971d39683 Add bank balances to DB (#3860) 2025-06-29 14:46:54 +00:00
Jai Agrawal
cf767c7ef2 Fix platform revenue route (#3857) 2025-06-28 21:55:01 +00:00
Josiah Glosson
cc34e69524 Initial shared instances backend (#3800)
* Create base shared instance migration and initial routes

* Fix build

* Add version uploads

* Add permissions field for shared instance users

* Actually use permissions field

* Add "public" flag to shared instances that allow GETing them without authorization

* Add the ability to get and list shared instance versions

* Add the ability to delete shared instance versions

* Fix build after merge

* Secured file hosting (#3784)

* Remove Backblaze-specific file-hosting backend

* Added S3_USES_PATH_STYLE_BUCKETS

* Remove unused file_id parameter from delete_file_version

* Add support for separate public and private buckets in labrinth::file_hosting

* Rename delete_file_version to delete_file

* Add (untested) get_url_for_private_file

* Remove url field from shared instance routes

* Remove url field from shared instance routes

* Use private bucket for shared instance versions

* Make S3 environment variables fully separate between public and private buckets

* Change file host expiry for shared instances to 180 seconds

* Fix lint

* Merge shared instance migrations into a single migration

* Replace shared instance owners with Ghost instead of deleting the instance
2025-06-19 19:46:12 +00:00
Alejandro González
ef04dcc37b feat(labrinth): rework v3 side types to a single environment field (#3701)
* feat(labrinth): rework v3 side types to a single `environment` field

This field is meant to be able to represent the existing v2 side type
information and beyond, in a way that may also be slightly easier to
comprehend.

* chore(labrinth/migrations): use proper val for `HAVING` clause

* feat(labrinth): add `side_types_migration_review_status` field to projects
2025-06-16 22:44:57 +00:00
Alejandro González
97e4d8e132 fix(labrinth): ensure versions get removed from search indexes before ending route execution (#3789)
* fix(labrinth): ensure versions get removed from search indexes before ending route execution

* chore: run `sqlx prepare`

* chore(labrinth): simplify `remove_documents` a little

* chore: tweak new comment
2025-06-16 15:48:04 +00:00
Alejandro González
ee8ee7af82 feat(labrinth): ignore email case differences in password recovery flow (#3771)
* feat(labrinth): ignore email case differences in password recovery flow

* chore(labrinth): run `sqlx prepare`
2025-06-11 21:59:21 +00:00
Alejandro González
a3839461cf perf(labrinth/random_projects_get): speed up through spatial queries according to profiling results (#3762) 2025-06-09 22:19:58 +00:00
Emma Alexia
06f1df1995 Fix random_projects route not returning the requested number of projects (#3758)
* Fix random_projects route not returning the requested number of projects

* fix(labrinth): further improve random project route SQL query

* chore: fix typo in comment

* tweak(labrinth): more apparent and fast randomness for `random_projects_get`

* tweak(labrinth): even better random projects query

* chore: address formatting review

---------

Co-authored-by: Alejandro González <me@alegon.dev>
2025-06-08 23:49:39 +00:00
Emma Alexia
74cf3f076e Automatically fail payments that are older than 30 days (#3697) 2025-05-25 19:36:19 +00:00
Emma Alexia
dc0d923cee Automatically cancel servers with failed payments older than 30d (#3695) 2025-05-25 19:36:11 +00:00
Josiah Glosson
9e527ff141 Labrinth ID cleanup (#3681)
* Put all ID types in the labrinth::models::ids, and reduce code duplication with them

* Rewrite labrinth::database::models::ids and rename most DB interface ID structs to be prefixed with DB

* Run sqlx prepare

---------

Co-authored-by: Alejandro González <7822554+AlexTMjugador@users.noreply.github.com>
2025-05-22 08:34:36 +00:00
Emma Alexia
863bf62f8d Fix updated field including deleted versions (#3643)
* Fix `updated` field including deleted versions

Four years ago, I created issue modrinth/labrinth#200. Today, while it adorns a different name (modrinth/code#2766), the issue remains the same. In celebration of Modrinth's oldest bug report, here is a fix.

Instead of having a separate `updated` field, it simply pulls the publish date of the most recent version. This should also allow the `updated` column on the `mods` table to be dropped at a later date, but I would rather get confirmation that it works before we go ahead with that.

Fixes #2766

* Update apps/labrinth/src/database/models/project_item.rs

Co-authored-by: Alejandro González <7822554+AlexTMjugador@users.noreply.github.com>
Signed-off-by: Emma Alexia <wafflecoffee7@gmail.com>

---------

Signed-off-by: Emma Alexia <wafflecoffee7@gmail.com>
Co-authored-by: Alejandro González <7822554+AlexTMjugador@users.noreply.github.com>
2025-05-12 18:19:30 +00:00
Emma Alexia
9a6390bb4d Fix organization projects route properly (#3633)
* Revert "fix: capitalization of ID org route breaks projects list (#3621)"

This reverts commit e4adbb9469.

* Fix organization projects route properly

Reverted #3621 because it caused more bugs to be created, in the form of organizations with capital letters not showing any projects

* Update apps/labrinth/src/routes/v3/organizations.rs

Co-authored-by: Alejandro González <7822554+AlexTMjugador@users.noreply.github.com>
Signed-off-by: Emma Alexia <wafflecoffee7@gmail.com>

* fix copy-paste error

---------

Signed-off-by: Emma Alexia <wafflecoffee7@gmail.com>
Co-authored-by: Alejandro González <7822554+AlexTMjugador@users.noreply.github.com>
2025-05-09 23:28:52 +00:00
Emma Alexia
5c1f198397 Add ability to delete user icon (#3383)
* Add user icon delete route

By request of moderation, but also just generally nice to have

* Add relevant docs and frontend

* Add v2 version
2025-04-19 12:49:23 +00:00
Emma Alexia
d0aef27f7b Fix deleting a user that has a prior subscription (#3533)
(for real this time)
2025-04-19 04:38:54 +00:00
Emma Alexia
f2ec89e62b Fix two database errors (#3483)
* Fixes error when an admin tries transferring project ownership
* Fixes error when trying to delete a user when they previously have a transaction

Co-authored-by: Jai Agrawal <18202329+Geometrically@users.noreply.github.com>
2025-04-12 22:21:02 -07:00
Jai A
13f2961e43 run migrate 2025-04-03 17:47:30 -07:00
Jai A
d0d0dcf09f Fix billing setup 2025-04-03 15:44:53 -07:00
Josiah Glosson
c998d2566e Allow multiple labrinth instances (#3360)
* Move a lot of scheduled tasks to be runnable from the command-line

* Use pubsub to handle sockets connected to multiple Labrinths

* Clippy fix

* Fix build and merge some stuff

* Fix build fmt
:

---------

Signed-off-by: Jai Agrawal <18202329+Geometrically@users.noreply.github.com>
Co-authored-by: Jai A <jaiagr+gpg@pm.me>
Co-authored-by: Jai Agrawal <18202329+Geometrically@users.noreply.github.com>
2025-03-15 07:28:20 -07:00
Josiah Glosson
650ab71a83 Commonized networking (#3310)
* Fix not being able to connect to local friends socket

* Start basic work on tunneling protocol and move some code into a common crate

* Commonize message serialization logic

* Serialize Base62Ids as u64 when human-readability is not required

* Move ActiveSockets tuple into struct

* Make CI run when rust-common is updated

CI is currently broken for labrinth, however

* Fix theseus-release.yml to reference itself correctly

* Implement Labrinth side of tunneling

* Implement non-friend part of theseus tunneling

* Implement client-side except for socket loop

* Implement the socket loop

Doesn't work though. Debugging time!

* Fix config.rs

* Fix deadlock in labrinth socket handling

* Update dockerfile

* switch to workspace prepare at root level

* Wait for connection before tunneling in playground

* Move rust-common into labrinth

* Remove rust-common references from Actions

* Revert "Update dockerfile"

This reverts commit 3caad59bb474ce425d0b8928d7cee7ae1a5011bd.

* Fix Docker build

* Rebuild Theseus if common code changes

* Allow multiple connections from the same user

* Fix test building

* Move FriendSocketListening and FriendSocketStoppedListening to non-panicking TODO for now

* Make message_serialization macro take varargs for binary messages

* Improve syntax of message_serialization macro

* Remove the ability to connect to a virtual socket, and disable the ability to listen on one

* Allow the app to compile without running labrinth

* Clippy fix

* Update Rust and Clippy fix again

---------

Co-authored-by: Jai A <jaiagr+gpg@pm.me>
2025-02-28 10:52:47 -08:00
Jai Agrawal
067f471766 Segment pending revenue in API response (#3283) 2025-02-20 23:07:54 +00:00
Jai Agrawal
31723a2d3c Fix prorations not updating open charge (#3265) 2025-02-14 22:53:45 -08:00