Skip to content

Merge to main#2

Open
fearganni wants to merge 212 commits into
OneChatCo:masterfrom
stoatchat:main
Open

Merge to main#2
fearganni wants to merge 212 commits into
OneChatCo:masterfrom
stoatchat:main

Conversation

@fearganni

Copy link
Copy Markdown

No description provided.

@fearganni fearganni requested a review from Copilot October 30, 2025 18:40

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR introduces several major changes to support a rebrand from "revoltchat" to "stoatchat" and adds new features:

  • Adds a new gifbox service for Tenor GIF proxy functionality
  • Introduces two new core libraries: revolt-coalesced for request deduplication and revolt-ratelimits for unified rate limiting
  • Refactors rate limiting implementation across services (delta, autumn, gifbox)
  • Updates organization references from "revoltchat" to "stoatchat" throughout the codebase
  • Fixes a bug in website embed URL handling (january service)
  • Improves message reply handling and Ready payload field selection

Reviewed Changes

Copilot reviewed 70 out of 71 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
crates/services/gifbox/* New service for proxying Tenor GIF API requests with caching and rate limiting
crates/core/ratelimits/* New shared rate limiting library supporting both Rocket and Axum frameworks
crates/core/coalesced/* New library for request coalescing, caching, and queuing
crates/services/january/src/website_embed.rs Bug fix: corrected variable reference from url to original_url
crates/bonfire/src/config.rs Added support for selective Ready payload field configuration via WebSocket params
scripts/* Updated to include gifbox service in build and deployment scripts
.github/workflows/* Updated organization references and Docker image names for rebrand
Cargo.toml files Version bumps to 0.8.9 across all crates

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Some(("locale", locale)),
Some(("contentfilter", "high")),
Some(("limit", &limit.to_string())),
position.is_empty().then_some(("pos", position)),

Copilot AI Oct 30, 2025

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Logic error: position.is_empty().then_some() will only include the parameter when position is empty, but it should be included when position is NOT empty. Change to (!position.is_empty()).then_some(("pos", position)) or use Some(...) with an if guard instead.

Copilot uses AI. Check for mistakes.
Some(("locale", locale)),
Some(("contentfilter", "high")),
Some(("limit", &limit.to_string())),
position.is_empty().then_some(("pos", position)),

Copilot AI Oct 30, 2025

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Logic error: position.is_empty().then_some() will only include the parameter when position is empty, but it should be included when position is NOT empty. Change to (!position.is_empty()).then_some(("pos", position)) or use Some(...) with an if guard instead.

Copilot uses AI. Check for mistakes.
Comment on lines +170 to +174
if self.categories.read().await.contains_key(&unique_key) {
if let Some(response) = self.featured.write().await.get(&unique_key) {
return Ok(response.clone());
}
}

Copilot AI Oct 30, 2025

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cache lookup error: checking self.categories but retrieving from self.featured. The first line should be if self.featured.read().await.contains_key(&unique_key) to check the correct cache.

Copilot uses AI. Check for mistakes.
Comment on lines +164 to +165
if let Some(field) = captures.get(0) {
match field.as_str() {

Copilot AI Oct 30, 2025

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Regex capture group indexing error: captures.get(0) returns the entire match, but the code should check captures.get(1) to get the first capture group (the field name without brackets). The current code will not work correctly for patterns like user_settings[key] because get(0) includes the entire match with brackets.

Copilot uses AI. Check for mistakes.
Zomatree and others added 7 commits November 6, 2025 20:26
* initial livekit support

fix up code

undo changes to compose file

add back .env.example

* move voice states to global

* track current state

* more stuff

* fix redis key inconsistancy

* split voice ops into its own library

* feat(livekit): more permission handling

* feat(livekit): push unfinished code

* fix: include voice states in servercreate event
feat: call started system message in dms

* feat: implement missing permission syncs

* fix: remove locked rocket version

* fix: remove local testing values from config

* chore: switch to ids for parameter

* feat: make Channel::server return a reference

* feat: support multiple voice nodes

* fix: expose list of nodes

* fix: respond with the url when joining a voice channel

* feat: being moved between voice channels

* fix: use existing node if someone is already in the voice channel

* refactor: Remove VoiceChannel

* chore: add pushd to debug image script

* refactor: add error messages for Rabbit issues

* docs: add some notes on overrides; fix defaults

* fix: ensure limit is always at least 1 when sent to database

* fix: change permission check for fetching channel webhooks

* chore: mount API at /0.8/ as well

* fix: ensure ratelimiter adjusts for version prefix

* chore: bump version to 0.8.2

* chore: disable LTO because it likely overloads GitHub worker

* fix: don't allow users to time themselves out
closes #376

* fix: match new error type for status code

* feat: init crond crate

* feat: file deletion implementation

* chore: fix version references

* feat: add crond container definitions

* chore: clarify cargo deny / tomls

* feat: add company information to email footers

* chore: bump version to 0.8.3

* fix: don't bump the lockfile version

* fix: include `production` default value for config

* chore: ignore python venv and dev script for user generation

Signed-off-by: IAmTomahawkx <iamtomahawkx@gmail.com>

* test: Add tests for invite/fetch

Signed-off-by: phazeschift <51278042+phazeschift@users.noreply.github.com>

* test: add utilities for common setup

Signed-off-by: phazeschift <51278042+phazeschift@users.noreply.github.com>

* test: add delete server channel test

Signed-off-by: phazeschift <51278042+phazeschift@users.noreply.github.com>

* feat: allow to set an icon when creating a group

Signed-off-by: Nils Ponsard <nilsponsard@gmail.com>

* fix: allow message pinning and unpinning for DM-like channels

Signed-off-by: Bradlee Barnes <69256931+StupidRepo@users.noreply.github.com>

* fix: remove SavedMessages and Group due to given permissions

Signed-off-by: Bradlee Barnes <69256931+StupidRepo@users.noreply.github.com>

* feat: allow bots to manage emojis (#407)

* Remove bot check on emoji create

Signed-off-by: Builderb <builderbgamer@gmail.com>

* Remove bot check on emoji delete

Signed-off-by: Builderb <builderbgamer@gmail.com>

---------

Signed-off-by: Builderb <builderbgamer@gmail.com>

* feat: add option to send message with missing replies

Signed-off-by: ShaksterNano <54268387+shaksternano@users.noreply.github.com>

* chore: bump version to 0.8.4
chore: enable webhooks in test builds

* ci: downgrade lockfile

* feat: Add Mass Mentions to the backend (#394)

* feat: create base of push daemon

Signed-off-by: IAmTomahawkx <iamtomahawkx@gmail.com>

* Add outbound senders

* Make web_push send to rabbit instead (temp stuff)

* feat: stability and friend requests

* make vapid fr stuff not suck

* swap naming of queue

* move pushd into daemons folder

* fix cargo file for move into daemons folder

* feat: probably working fcm push notifs

* comment out fcm webpush stuff since the config keys dont exist

* fix fcm, name queues according to their prod status and configure routing keys

* add pushd to docker

* mix: Remove old code, add stuff to pushd

* fix: lockfile

* feat: update rocket to 5.0.1

* fix: fix queues and ack bugs

* Move rabbit messsage processing into ack queue

* chore: update readme

* chore: optimizations for ack database hits

* pushd flowchart

* misc: update flowchart

* exit dependancy hell

* add rocket_impl flag to authifier

* make the tests file of delta actually compile

* fix: don't silence every push message

* fix: don't silence all messages

* add debug logging for sending data to rabbit from message events

* validate mentions at a server membership level

* put back that import that was actually important

* minor fix to lockfile

* update delta authifier

* feat: proper permissions for push notifications

* add unit test for mention sanitization

* remove local file dependancy on authifier

* update ports to proper defaults

* fixTM the node bindings

* Theoretically configure docker releases for pushd

Signed-off-by: IAmTomahawkx <iamtomahawkx@gmail.com>

* declare exchange in pushd and delta

* fix createbuckets script

Signed-off-by: IAmTomahawkx <iamtomahawkx@gmail.com>

* fix: reference db implementation

Signed-off-by: IAmTomahawkx <iamtomahawkx@gmail.com>

* fix: remove finally redundant code

Signed-off-by: IAmTomahawkx <iamtomahawkx@gmail.com>

* fix: changes

Signed-off-by: IAmTomahawkx <iamtomahawkx@gmail.com>

* fix: other changes

Signed-off-by: IAmTomahawkx <iamtomahawkx@gmail.com>

* fix: make channel name return result

Signed-off-by: IAmTomahawkx <iamtomahawkx@gmail.com>

* Add role mention parsing

* feat: update to mongo 3.1, add member generator.

* integrate mass mentions into pushd

* patch redis-rs with updated versions

* feat: chunk role mentions

* move permission bits to 37/38 to avoid livekit conflict

* change role mention format to <%id>

* fix the lockfile from merge

* fix: PR change requests

* feat: add tests

* fix: i am a dumbass

* fix: tests, again

---------

Signed-off-by: IAmTomahawkx <iamtomahawkx@gmail.com>

* fix: show full branch name on github webhook messages

* fix: dont leak invisible presence to others

* fix: add back missing early adopter badge

* fix: update branch from main

* fix: update branch from main

* Merge remote-tracking branch 'origin/main' into livekit

* feat: private livekit nodes

* fix: remove node from channel voice state

* fix: get_voice_state has incorrect unique_key and allowed_sources should be lowercase

* chore: bump livekit dep

* feat: ability to force disconnect existing voice connection

* chore: cleanup code

* feat: - track call length
- move voice and video limits to config
- seperate VoiceInformation into model and db model
- fix build scripts

* fix: move call system message to daemon,
check max participants when creating a token to avoid giving tokens but erroring when attempting to join,
check if the channel actually supports voice

* fix: dont set max participants in livekit

* fix: remove VoiceChannel channel type
fix: calculate user overwrites correctly
fix: dont include personal info in livekit user metadata
fix: revoke video permissons on denied publish
fix: add video to default permissions

* fix: update migration

* feat: Send push notifications for dm call start/end

* chore: cleanup

* feat: allow users to specify who is notified when starting a call

* feat: track join time

* merge: branch 'main' into feat/livekit

* fix: include voice-ingress in build

* fix: dont presume channel has a node

* chore: add error logging to internal errors

* chore: add debug logging to voice ingress

* refactor: seperate out disconnect logic

* fix: return correct error if user is already in a voice channel

* fix: dont break on user not still being in channel and force disconnecting

* fix: add Speak and Listen to default permissions

* fix: include channel ids in UserMoveVoiceChannel

* chore: add temp sentry logging system

* fix: handle track_muted and track_unmuted

* fix: dont set notification recipients when empty vec is passed

* fix: only send UserMoveVoiceChannel to the user

* fix: preserve order of replies in message (#447)

Signed-off-by: Aeledfyr <aeledfyr@gmail.com>

* fix: prevent timing out members which have TimeoutMembers permission

* chore: update ci

* fix: temporarily disable call started system messages
See #457

* fix: update code from review
Signed-off-by: izzy <me@insrt.uk>
IAmTomahawkx and others added 30 commits May 18, 2026 15:11
* fix: set env var for publishing crates

Signed-off-by: IAmTomahawkx <iamtomahawkx@gmail.com>
Release-As: 0.13.6
* chore: begin switching to lapin fully

Signed-off-by: Zomatree <me@zomatree.live>

* chore: update rest of pushd to lapin

Signed-off-by: Zomatree <me@zomatree.live>

* chore: cleanup code

Signed-off-by: Zomatree <me@zomatree.live>

* chore: cleanup code

Signed-off-by: Zomatree <me@zomatree.live>

* fix: github webui sucks

Signed-off-by: IAmTomahawkx <iamtomahawkx@gmail.com>

---------

Signed-off-by: Zomatree <me@zomatree.live>
Signed-off-by: Tom <iamtomahawkx@gmail.com>
Signed-off-by: IAmTomahawkx <iamtomahawkx@gmail.com>
Co-authored-by: Tom <iamtomahawkx@gmail.com>
Release-As: 0.13.6
* chore(main): release 0.13.6

* chore: update Cargo.lock

Signed-off-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>

---------

Signed-off-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: stoat-release[bot] <245062572+stoat-release[bot]@users.noreply.github.com>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Signed-off-by: Zomatree <me@zomatree.live>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Signed-off-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Signed-off-by: ispik <ispik@ispik.dev>
* chore(docs): update header logo

Signed-off-by: IAmTomahawkx <iamtomahawkx@gmail.com>

* fix: don't step on toes

Signed-off-by: IAmTomahawkx <iamtomahawkx@gmail.com>

---------

Signed-off-by: IAmTomahawkx <iamtomahawkx@gmail.com>
chore(docs): update favicon

Signed-off-by: Asraye <asrayeofficial@gmail.com>
* fix: openapi using old naming

Signed-off-by: IAmTomahawkx <iamtomahawkx@gmail.com>

* fix: remove january openapi security header

Signed-off-by: IAmTomahawkx <iamtomahawkx@gmail.com>

* fix(docs): more Revolt usage

Signed-off-by: IAmTomahawkx <iamtomahawkx@gmail.com>

---------

Signed-off-by: IAmTomahawkx <iamtomahawkx@gmail.com>
Signed-off-by: AsrayeDev <asrayeofficial@gmail.com>
… overrides (#805)

fix: allow true server owner to bypass rank check on channel role-permission overrides

The set_role_permissions route blocks editing a role's channel permission
overrides whenever role.rank <= the acting member's rank
(NotElevated), to prevent privilege-escalation loops.

However this check has no exemption for the server's true owner
(server.owner == user.id). If an owner has assigned themselves their
own top-level role (e.g. "Admin"/"Server Admin" - extremely common
since most server setups have the owner hold their highest role for
visible status/cosmetics), that role's rank is necessarily equal to
their own computed member rank, so the check incorrectly throws
NotElevated for the owner too - even though server owners by definition
outrank every role and every member, owner-held roles included.

This produces a confusing experience: the owner cannot edit channel-level
overrides for their own top role via the UI, with no clear explanation,
and may reasonably believe something is broken or their permissions are
miscconfigured (they aren't).

This adds a short-circuit: if the acting user is the server's owner,
skip the rank comparison entirely, matching how Stoat already treats
true ownership as an absolute bypass elsewhere in the permission system
(e.g. channel-visibility lockout cascades).

Signed-off-by: bluecords <133072610+bluecords@users.noreply.github.com>
…er owners/admins (#802)

fix: channel role permissions fail with InvalidOperation for owners/admins

Fix: explicitly populate the server reference via
set_server_from_channel() before relying on server_ref().

Signed-off-by: bluecords <133072610+bluecords@users.noreply.github.com>
Co-authored-by: izzy <me@insrt.uk>
Signed-off-by: Zomatree <me@zomatree.live>
Signed-off-by: izzy <me@insrt.uk>
Signed-off-by: İspik <ispik@ispik.dev>
Co-authored-by: stoat-release[bot] <245062572+stoat-release[bot]@users.noreply.github.com>
Co-authored-by: stoat-release[bot] <245062572+stoat-release[bot]@users.noreply.github.com>
Co-authored-by: stoat-release[bot] <245062572+stoat-release[bot]@users.noreply.github.com>
Co-authored-by: stoat-release[bot] <245062572+stoat-release[bot]@users.noreply.github.com>
Signed-off-by: Zomatree <me@zomatree.live>
)

Co-authored-by: stoat-release[bot] <245062572+stoat-release[bot]@users.noreply.github.com>
Co-authored-by: stoat-release[bot] <245062572+stoat-release[bot]@users.noreply.github.com>
Co-authored-by: stoat-release[bot] <245062572+stoat-release[bot]@users.noreply.github.com>
Signed-off-by: Zomatree <me@zomatree.live>
Signed-off-by: Zomatree <me@zomatree.live>
Signed-off-by: Zomatree <me@zomatree.live>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.