From e708c612cf18908d715d6897803bc4c810c0e8aa Mon Sep 17 00:00:00 2001 From: Kyle Kienapfel Date: Tue, 29 Apr 2025 18:19:43 -0700 Subject: [PATCH 01/26] fix: Actually create crond container in github workflow Just one line missing to make the container creation happen Related to eb5f5f91cdd2eb37b4b99ed66b90887b8c6f4895 Signed-off-by: Kyle Kienapfel --- .github/workflows/docker.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/docker.yaml b/.github/workflows/docker.yaml index 76107876..fdcbed2c 100644 --- a/.github/workflows/docker.yaml +++ b/.github/workflows/docker.yaml @@ -61,7 +61,7 @@ jobs: if: github.event_name != 'pull_request' strategy: matrix: - project: [delta, bonfire, autumn, january, pushd] + project: [delta, bonfire, autumn, january, pushd, crond] name: Build ${{ matrix.project }} image steps: # Configure build environment From c785ae615db8ce0a7c01fba0d512ba0c29c4b815 Mon Sep 17 00:00:00 2001 From: izzy Date: Fri, 9 May 2025 22:39:29 +0100 Subject: [PATCH 02/26] ci: new attempt at using hosted runner --- .github/workflows/docker.yaml | 196 +++++++++++++++++++++------------- scripts/build-image-layer.sh | 8 +- 2 files changed, 128 insertions(+), 76 deletions(-) diff --git a/.github/workflows/docker.yaml b/.github/workflows/docker.yaml index fdcbed2c..1d1c7cbd 100644 --- a/.github/workflows/docker.yaml +++ b/.github/workflows/docker.yaml @@ -2,24 +2,13 @@ name: Docker Test & Publish on: push: - # branches: - # - "main" tags: - "*" - paths-ignore: - - ".github/**" - - "!.github/workflows/docker.yml" - - ".vscode/**" - - "doc/**" - - ".gitignore" - - "LICENSE" - - "README" pull_request: branches: - "main" paths: - "Dockerfile" - workflow_dispatch: permissions: contents: read @@ -27,8 +16,9 @@ permissions: jobs: base: + name: Test base image build runs-on: ubuntu-latest - name: Build base image + if: github.event_name == 'pull_request' steps: # Configure build environment - name: Checkout @@ -36,33 +26,21 @@ jobs: - name: Set up Docker Buildx uses: docker/setup-buildx-action@v2 - # Authenticate with GHCR - - name: Login to Github Container Registry - if: ${{ github.event_name != 'pull_request' }} - uses: docker/login-action@v2 - with: - registry: ghcr.io - username: ${{ github.actor }} - password: ${{ secrets.GITHUB_TOKEN }} - + # Build the image - name: Build base image uses: docker/build-push-action@v4 with: context: . - push: ${{ github.event_name != 'pull_request' }} + push: false platforms: linux/amd64,linux/arm64 tags: ghcr.io/${{ github.repository_owner }}/base:latest cache-from: type=gha,scope=buildx-base-multi-arch cache-to: type=gha,scope=buildx-base-multi-arch,mode=max publish: - needs: [base] - runs-on: ubuntu-latest + runs-on: self-hosted if: github.event_name != 'pull_request' - strategy: - matrix: - project: [delta, bonfire, autumn, january, pushd, crond] - name: Build ${{ matrix.project }} image + name: Publish Docker images steps: # Configure build environment - name: Checkout @@ -70,6 +48,15 @@ jobs: - name: Set up Docker Buildx uses: docker/setup-buildx-action@v2 + # Build the image + - name: Build base image + uses: docker/build-push-action@v4 + with: + context: . + push: false + platforms: linux/amd64,linux/arm64 + tags: base:latest + # Authenticate with Docker Hub and GHCR - name: Login to DockerHub uses: docker/login-action@v2 @@ -77,6 +64,7 @@ jobs: registry: docker.io username: ${{ secrets.DOCKERHUB_USERNAME }} password: ${{ secrets.DOCKERHUB_TOKEN }} + - name: Login to Github Container Registry uses: docker/login-action@v2 with: @@ -84,58 +72,122 @@ jobs: username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} - # Resolve the correct project - - uses: kanga333/variable-mapper@master - id: export - with: - key: "${{ matrix.project }}" - map: | - { - "delta": { - "path": "crates/delta", - "tag": "${{ github.repository_owner }}/server" - }, - "bonfire": { - "path": "crates/bonfire", - "tag": "${{ github.repository_owner }}/bonfire" - }, - "autumn": { - "path": "crates/services/autumn", - "tag": "${{ github.repository_owner }}/autumn" - }, - "january": { - "path": "crates/services/january", - "tag": "${{ github.repository_owner }}/january" - }, - "pushd": { - "path": "crates/daemons/pushd", - "tag": "${{ github.repository_owner }}/pushd" - }, - "crond": { - "path": "crates/daemons/crond", - "tag": "${{ github.repository_owner }}/crond" - } - } - export_to: output - - # Configure metadata + # revoltchat/server - name: Docker meta - id: meta + id: meta-delta uses: docker/metadata-action@v4 with: images: | - docker.io/${{ steps.export.outputs.tag }} - ghcr.io/${{ steps.export.outputs.tag }} - - # Build crate image + docker.io/revoltchat/server + ghcr.io/revoltchat/server - name: Publish uses: docker/build-push-action@v4 with: context: . push: true platforms: linux/amd64,linux/arm64 - file: ${{ steps.export.outputs.path }}/Dockerfile - tags: ${{ steps.meta.outputs.tags }} + file: crates/delta/Dockerfile + tags: ${{ steps.meta-delta.outputs.tags }} build-args: | - BASE_IMAGE=ghcr.io/${{ github.repository_owner }}/base:latest - labels: ${{ steps.meta.outputs.labels }} + BASE_IMAGE=base:latest + labels: ${{ steps.meta-delta.outputs.labels }} + + # revoltchat/bonfire + - name: Docker meta + id: meta-bonfire + uses: docker/metadata-action@v4 + with: + images: | + docker.io/revoltchat/bonfire + ghcr.io/revoltchat/bonfire + - name: Publish + uses: docker/build-push-action@v4 + with: + context: . + push: true + platforms: linux/amd64,linux/arm64 + file: crates/bonfire/Dockerfile + tags: ${{ steps.meta-bonfire.outputs.tags }} + build-args: | + BASE_IMAGE=base:latest + labels: ${{ steps.meta-bonfire.outputs.labels }} + + # revoltchat/autumn + - name: Docker meta + id: meta-autumn + uses: docker/metadata-action@v4 + with: + images: | + docker.io/revoltchat/autumn + ghcr.io/revoltchat/autumn + - name: Publish + uses: docker/build-push-action@v4 + with: + context: . + push: true + platforms: linux/amd64,linux/arm64 + file: crates/services/autumn/Dockerfile + tags: ${{ steps.meta-autumn.outputs.tags }} + build-args: | + BASE_IMAGE=base:latest + labels: ${{ steps.meta-autumn.outputs.labels }} + + # revoltchat/january + - name: Docker meta + id: meta-january + uses: docker/metadata-action@v4 + with: + images: | + docker.io/revoltchat/january + ghcr.io/revoltchat/january + - name: Publish + uses: docker/build-push-action@v4 + with: + context: . + push: true + platforms: linux/amd64,linux/arm64 + file: crates/services/january/Dockerfile + tags: ${{ steps.meta-january.outputs.tags }} + build-args: | + BASE_IMAGE=base:latest + labels: ${{ steps.meta-january.outputs.labels }} + + # revoltchat/crond + - name: Docker meta + id: meta-crond + uses: docker/metadata-action@v4 + with: + images: | + docker.io/revoltchat/crond + ghcr.io/revoltchat/crond + - name: Publish + uses: docker/build-push-action@v4 + with: + context: . + push: true + platforms: linux/amd64,linux/arm64 + file: crates/daemons/crond/Dockerfile + tags: ${{ steps.meta-crond.outputs.tags }} + build-args: | + BASE_IMAGE=base:latest + labels: ${{ steps.meta-crond.outputs.labels }} + + # revoltchat/pushd + - name: Docker meta + id: meta-pushd + uses: docker/metadata-action@v4 + with: + images: | + docker.io/revoltchat/pushd + ghcr.io/revoltchat/pushd + - name: Publish + uses: docker/build-push-action@v4 + with: + context: . + push: true + platforms: linux/amd64,linux/arm64 + file: crates/daemons/pushd/Dockerfile + tags: ${{ steps.meta-pushd.outputs.tags }} + build-args: | + BASE_IMAGE=base:latest + labels: ${{ steps.meta-pushd.outputs.labels }} diff --git a/scripts/build-image-layer.sh b/scripts/build-image-layer.sh index 064ee756..0447714e 100644 --- a/scripts/build-image-layer.sh +++ b/scripts/build-image-layer.sh @@ -54,9 +54,9 @@ deps() { tee crates/core/result/src/lib.rs if [ -z "$TARGETARCH" ]; then - cargo build --locked --release + cargo build -j 24 --locked --release else - cargo build --locked --release --target "${BUILD_TARGET}" + cargo build -j 24 --locked --release --target "${BUILD_TARGET}" fi } @@ -74,9 +74,9 @@ apps() { crates/core/result/src/lib.rs if [ -z "$TARGETARCH" ]; then - cargo build --locked --release + cargo build -j 24 --locked --release else - cargo build --locked --release --target "${BUILD_TARGET}" + cargo build -j 24 --locked --release --target "${BUILD_TARGET}" mv target _target && mv _target/"${BUILD_TARGET}" target fi } From 7f85ad5e7b2c56879fc5ba0a3f68667819331800 Mon Sep 17 00:00:00 2001 From: izzy Date: Fri, 9 May 2025 22:44:58 +0100 Subject: [PATCH 03/26] ci: load the built base image into Docker --- .github/workflows/docker.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/docker.yaml b/.github/workflows/docker.yaml index 1d1c7cbd..68416d75 100644 --- a/.github/workflows/docker.yaml +++ b/.github/workflows/docker.yaml @@ -54,6 +54,7 @@ jobs: with: context: . push: false + load: true platforms: linux/amd64,linux/arm64 tags: base:latest From 70d6a5ac08743dbac6f25fc9f95c15dc66703a7b Mon Sep 17 00:00:00 2001 From: izzy Date: Fri, 9 May 2025 22:48:50 +0100 Subject: [PATCH 04/26] ci: for multi-arch builds, must push instead of load --- .github/workflows/docker.yaml | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/.github/workflows/docker.yaml b/.github/workflows/docker.yaml index 68416d75..a9cf718e 100644 --- a/.github/workflows/docker.yaml +++ b/.github/workflows/docker.yaml @@ -53,10 +53,9 @@ jobs: uses: docker/build-push-action@v4 with: context: . - push: false - load: true + push: true platforms: linux/amd64,linux/arm64 - tags: base:latest + tags: ghcr.io/${{ github.repository_owner }}/base:latest # Authenticate with Docker Hub and GHCR - name: Login to DockerHub @@ -90,7 +89,7 @@ jobs: file: crates/delta/Dockerfile tags: ${{ steps.meta-delta.outputs.tags }} build-args: | - BASE_IMAGE=base:latest + BASE_IMAGE=ghcr.io/${{ github.repository_owner }}/base:latest labels: ${{ steps.meta-delta.outputs.labels }} # revoltchat/bonfire @@ -110,7 +109,7 @@ jobs: file: crates/bonfire/Dockerfile tags: ${{ steps.meta-bonfire.outputs.tags }} build-args: | - BASE_IMAGE=base:latest + BASE_IMAGE=ghcr.io/${{ github.repository_owner }}/base:latest labels: ${{ steps.meta-bonfire.outputs.labels }} # revoltchat/autumn @@ -130,7 +129,7 @@ jobs: file: crates/services/autumn/Dockerfile tags: ${{ steps.meta-autumn.outputs.tags }} build-args: | - BASE_IMAGE=base:latest + BASE_IMAGE=ghcr.io/${{ github.repository_owner }}/base:latest labels: ${{ steps.meta-autumn.outputs.labels }} # revoltchat/january @@ -150,7 +149,7 @@ jobs: file: crates/services/january/Dockerfile tags: ${{ steps.meta-january.outputs.tags }} build-args: | - BASE_IMAGE=base:latest + BASE_IMAGE=ghcr.io/${{ github.repository_owner }}/base:latest labels: ${{ steps.meta-january.outputs.labels }} # revoltchat/crond @@ -170,7 +169,7 @@ jobs: file: crates/daemons/crond/Dockerfile tags: ${{ steps.meta-crond.outputs.tags }} build-args: | - BASE_IMAGE=base:latest + BASE_IMAGE=ghcr.io/${{ github.repository_owner }}/base:latest labels: ${{ steps.meta-crond.outputs.labels }} # revoltchat/pushd @@ -190,5 +189,5 @@ jobs: file: crates/daemons/pushd/Dockerfile tags: ${{ steps.meta-pushd.outputs.tags }} build-args: | - BASE_IMAGE=base:latest + BASE_IMAGE=ghcr.io/${{ github.repository_owner }}/base:latest labels: ${{ steps.meta-pushd.outputs.labels }} From aa8f8575bcd1e2bd6a31017daa7b624f9ef2f4d9 Mon Sep 17 00:00:00 2001 From: izzy Date: Fri, 9 May 2025 22:51:16 +0100 Subject: [PATCH 05/26] fix: include revolt-parser in build scripts --- scripts/build-image-layer.sh | 3 +++ 1 file changed, 3 insertions(+) diff --git a/scripts/build-image-layer.sh b/scripts/build-image-layer.sh index 0447714e..0d599315 100644 --- a/scripts/build-image-layer.sh +++ b/scripts/build-image-layer.sh @@ -29,6 +29,7 @@ deps() { crates/core/database/src \ crates/core/files/src \ crates/core/models/src \ + crates/core/parser/src \ crates/core/permissions/src \ crates/core/presence/src \ crates/core/result/src \ @@ -49,6 +50,7 @@ deps() { tee crates/core/database/src/lib.rs | tee crates/core/files/src/lib.rs | tee crates/core/models/src/lib.rs | + tee crates/core/parser/src/lib.rs | tee crates/core/permissions/src/lib.rs | tee crates/core/presence/src/lib.rs | tee crates/core/result/src/lib.rs @@ -69,6 +71,7 @@ apps() { crates/core/config/src/lib.rs \ crates/core/database/src/lib.rs \ crates/core/models/src/lib.rs \ + crates/core/parser/src/lib.rs \ crates/core/permissions/src/lib.rs \ crates/core/presence/src/lib.rs \ crates/core/result/src/lib.rs From 7a4e12a732cd397077ddaa099660a8525f475e16 Mon Sep 17 00:00:00 2001 From: izzy Date: Fri, 9 May 2025 22:53:22 +0100 Subject: [PATCH 06/26] ci: include parser toml in Dockerfile --- Dockerfile | 1 + Dockerfile.useCurrentArch | 1 + 2 files changed, 2 insertions(+) diff --git a/Dockerfile b/Dockerfile index c75748c2..5faaa101 100644 --- a/Dockerfile +++ b/Dockerfile @@ -24,6 +24,7 @@ COPY crates/core/config/Cargo.toml ./crates/core/config/ COPY crates/core/database/Cargo.toml ./crates/core/database/ COPY crates/core/files/Cargo.toml ./crates/core/files/ COPY crates/core/models/Cargo.toml ./crates/core/models/ +COPY crates/core/parser/Cargo.toml ./crates/core/parser/ COPY crates/core/permissions/Cargo.toml ./crates/core/permissions/ COPY crates/core/presence/Cargo.toml ./crates/core/presence/ COPY crates/core/result/Cargo.toml ./crates/core/result/ diff --git a/Dockerfile.useCurrentArch b/Dockerfile.useCurrentArch index 54b508ef..6916dac8 100644 --- a/Dockerfile.useCurrentArch +++ b/Dockerfile.useCurrentArch @@ -20,6 +20,7 @@ COPY crates/core/config/Cargo.toml ./crates/core/config/ COPY crates/core/database/Cargo.toml ./crates/core/database/ COPY crates/core/files/Cargo.toml ./crates/core/files/ COPY crates/core/models/Cargo.toml ./crates/core/models/ +COPY crates/core/parser/Cargo.toml ./crates/core/parser/ COPY crates/core/permissions/Cargo.toml ./crates/core/permissions/ COPY crates/core/presence/Cargo.toml ./crates/core/presence/ COPY crates/core/result/Cargo.toml ./crates/core/result/ From f98f09a5ea04424e5fe00bf021078ad4953f100b Mon Sep 17 00:00:00 2001 From: izzy Date: Fri, 9 May 2025 22:57:45 +0100 Subject: [PATCH 07/26] ci: bump Docker builds to Rust 1.86.0 --- Dockerfile | 2 +- Dockerfile.useCurrentArch | 2 +- README.md | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Dockerfile b/Dockerfile index 5faaa101..ffb728f0 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,5 +1,5 @@ # Build Stage -FROM --platform="${BUILDPLATFORM}" rust:1.77.2-slim-bookworm +FROM --platform="${BUILDPLATFORM}" rust:1.86.0-slim-bookworm USER 0:0 WORKDIR /home/rust/src diff --git a/Dockerfile.useCurrentArch b/Dockerfile.useCurrentArch index 6916dac8..c9e73ef4 100644 --- a/Dockerfile.useCurrentArch +++ b/Dockerfile.useCurrentArch @@ -1,5 +1,5 @@ # Build Stage -FROM rust:1.77.2-slim-bookworm +FROM rust:1.86.0-slim-bookworm USER 0:0 WORKDIR /home/rust/src diff --git a/README.md b/README.md index d0894dee..c6dbf8dc 100644 --- a/README.md +++ b/README.md @@ -34,10 +34,10 @@ The services and libraries that power the Revolt service.
## Minimum Supported Rust Version -Rust 1.76 or higher. +Rust 1.86.0 or higher. > [!CAUTION] -> The events server has a significant performance regression between Rust 1.77.2 and 1.78.0 onwards, see [issue #341](https://github.com/revoltchat/backend/issues/341). +> The events server has a significant performance regression between Rust 1.77.2 and 1.78.0 onwards, see [issue #341](https://github.com/revoltchat/backend/issues/341). This is currently solved by build time options but we are looking for a proper fix. ## Development Guide From a8a2e491b0ce00f1efe559e5b0e14a072d85b1c7 Mon Sep 17 00:00:00 2001 From: izzy Date: Fri, 9 May 2025 22:59:51 +0100 Subject: [PATCH 08/26] ci: reduce threads available to build --- scripts/build-image-layer.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/scripts/build-image-layer.sh b/scripts/build-image-layer.sh index 0d599315..4acb2f71 100644 --- a/scripts/build-image-layer.sh +++ b/scripts/build-image-layer.sh @@ -56,9 +56,9 @@ deps() { tee crates/core/result/src/lib.rs if [ -z "$TARGETARCH" ]; then - cargo build -j 24 --locked --release + cargo build -j 10 --locked --release else - cargo build -j 24 --locked --release --target "${BUILD_TARGET}" + cargo build -j 10 --locked --release --target "${BUILD_TARGET}" fi } @@ -77,9 +77,9 @@ apps() { crates/core/result/src/lib.rs if [ -z "$TARGETARCH" ]; then - cargo build -j 24 --locked --release + cargo build -j 10 --locked --release else - cargo build -j 24 --locked --release --target "${BUILD_TARGET}" + cargo build -j 10 --locked --release --target "${BUILD_TARGET}" mv target _target && mv _target/"${BUILD_TARGET}" target fi } From 4a58d6eae04c5782e55fcdd9f3934680da9a676a Mon Sep 17 00:00:00 2001 From: izzy Date: Fri, 9 May 2025 23:04:37 +0100 Subject: [PATCH 09/26] chore: enable lto for production builds (#341) --- Cargo.toml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 6c69df09..d2ae6117 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -16,6 +16,6 @@ redis23 = { package = "redis", version = "0.23.3", git = "https://github.com/rev # I'm 99% sure this is overloading the GitHub worker # hence builds have been failing since, let's just # disable it for now. In the future, we could use this -# if we were rolling our own CI. -# [profile.release] -# lto = true +# if we were rolling our own CI (that is now). +[profile.release] +lto = true From 6daa8223b2a8a6883d99da6afdd1b079697b52bd Mon Sep 17 00:00:00 2001 From: izzy Date: Fri, 9 May 2025 23:10:35 +0100 Subject: [PATCH 10/26] ci: must login to ghcr before pushing base image --- .github/workflows/docker.yaml | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/.github/workflows/docker.yaml b/.github/workflows/docker.yaml index a9cf718e..fccaf634 100644 --- a/.github/workflows/docker.yaml +++ b/.github/workflows/docker.yaml @@ -48,15 +48,6 @@ jobs: - name: Set up Docker Buildx uses: docker/setup-buildx-action@v2 - # Build the image - - name: Build base image - uses: docker/build-push-action@v4 - with: - context: . - push: true - platforms: linux/amd64,linux/arm64 - tags: ghcr.io/${{ github.repository_owner }}/base:latest - # Authenticate with Docker Hub and GHCR - name: Login to DockerHub uses: docker/login-action@v2 @@ -72,6 +63,15 @@ jobs: username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} + # Build the image + - name: Build base image + uses: docker/build-push-action@v4 + with: + context: . + push: true + platforms: linux/amd64,linux/arm64 + tags: ghcr.io/${{ github.repository_owner }}/base:latest + # revoltchat/server - name: Docker meta id: meta-delta From 3a7ebad8838f088048b0531283de7321ce7f22f2 Mon Sep 17 00:00:00 2001 From: izzy Date: Sat, 10 May 2025 16:31:37 +0100 Subject: [PATCH 11/26] merge: branch 'izzy/patch/easypwned' fix: configure new authifier properties --- Cargo.lock | 32 +++++++++---------------- crates/bonfire/Cargo.toml | 2 +- crates/core/config/Revolt.toml | 2 ++ crates/core/config/src/lib.rs | 1 + crates/core/database/Cargo.toml | 2 +- crates/core/database/src/drivers/mod.rs | 20 +++++++++++++++- crates/delta/Cargo.toml | 5 ++-- 7 files changed, 38 insertions(+), 26 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 2e0ff711..2f4b9b92 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -443,9 +443,9 @@ dependencies = [ [[package]] name = "authifier" -version = "1.0.10" +version = "1.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "edfe88c4a9fcf24b18a216b27c9766966af2a40603d24c7782237afd6ca0d5cd" +checksum = "ca26cb6b5ab776a1de5a8122fe6cc77fadd84fed30704c496f2aca451637877b" dependencies = [ "async-std", "async-trait", @@ -454,7 +454,7 @@ dependencies = [ "chrono", "futures", "handlebars", - "iso8601-timestamp 0.1.11", + "iso8601-timestamp", "lazy_static", "lettre", "log", @@ -470,6 +470,7 @@ dependencies = [ "schemars", "serde", "serde_json", + "sha1", "totp-lite", "ulid 0.5.0", "validator 0.15.0", @@ -3647,17 +3648,6 @@ dependencies = [ "waker-fn", ] -[[package]] -name = "iso8601-timestamp" -version = "0.1.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b088f3296223f11d6bd70998132653b30b6f39e6ab4be055c0bda486fa8d11c7" -dependencies = [ - "generic-array 0.14.7", - "serde", - "time", -] - [[package]] name = "iso8601-timestamp" version = "0.2.17" @@ -6095,7 +6085,7 @@ dependencies = [ "futures", "indexmap 1.9.3", "isahc", - "iso8601-timestamp 0.2.17", + "iso8601-timestamp", "linkify 0.8.1", "log", "lru 0.11.1", @@ -6140,7 +6130,7 @@ dependencies = [ "env_logger", "futures", "impl_ops", - "iso8601-timestamp 0.2.17", + "iso8601-timestamp", "lettre", "linkify 0.6.0", "log", @@ -6229,7 +6219,7 @@ name = "revolt-models" version = "0.8.4" dependencies = [ "indexmap 1.9.3", - "iso8601-timestamp 0.2.17", + "iso8601-timestamp", "num_enum 0.6.1", "once_cell", "regex", @@ -6299,7 +6289,7 @@ dependencies = [ "base64 0.22.1", "fcm_v1", "isahc", - "iso8601-timestamp 0.2.17", + "iso8601-timestamp", "log", "pretty_env_logger", "revolt-config", @@ -6517,12 +6507,12 @@ dependencies = [ [[package]] name = "rocket_authifier" -version = "1.0.10" +version = "1.0.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c2aa1bfaee106d088b78de7c3cc2a8ab2c9e05a0286b6b912f0b18ea656b329e" +checksum = "0490f4a6f0a359a9ffff9acbdf4eddf49890ec94941b8ddd88163c16f6159f5a" dependencies = [ "authifier", - "iso8601-timestamp 0.1.11", + "iso8601-timestamp", "revolt_okapi", "revolt_rocket_okapi", "rocket", diff --git a/crates/bonfire/Cargo.toml b/crates/bonfire/Cargo.toml index be3f6edc..1eb1cd9c 100644 --- a/crates/bonfire/Cargo.toml +++ b/crates/bonfire/Cargo.toml @@ -36,7 +36,7 @@ async-std = { version = "1.8.0", features = [ ] } # core -authifier = { version = "1.0.10" } +authifier = { version = "1.0.13" } revolt-result = { path = "../core/result" } revolt-models = { path = "../core/models" } revolt-config = { path = "../core/config" } diff --git a/crates/core/config/Revolt.toml b/crates/core/config/Revolt.toml index 71c09800..08b59713 100644 --- a/crates/core/config/Revolt.toml +++ b/crates/core/config/Revolt.toml @@ -54,6 +54,8 @@ authifier_shield_key = "" voso_legacy_token = "" # Whether services are behind the Cloudflare network trust_cloudflare = false +# easypwned endpoint +easypwned = "" [api.security.captcha] # hCaptcha configuration diff --git a/crates/core/config/src/lib.rs b/crates/core/config/src/lib.rs index 6dd730e6..274baef3 100644 --- a/crates/core/config/src/lib.rs +++ b/crates/core/config/src/lib.rs @@ -168,6 +168,7 @@ pub struct ApiSecurity { pub voso_legacy_token: String, pub captcha: ApiSecurityCaptcha, pub trust_cloudflare: bool, + pub easypwned: String, } #[derive(Deserialize, Debug, Clone)] diff --git a/crates/core/database/Cargo.toml b/crates/core/database/Cargo.toml index d32e5268..1f0fc7e6 100644 --- a/crates/core/database/Cargo.toml +++ b/crates/core/database/Cargo.toml @@ -97,7 +97,7 @@ web-push = "0.10.0" revolt_a2 = { version = "0.10", default-features = false, features = ["ring"] } # Authifier -authifier = { version = "1.0.10", features = ["rocket_impl"] } +authifier = { version = "1.0.13", features = ["rocket_impl"] } # RabbitMQ amqprs = { version = "1.7.0" } diff --git a/crates/core/database/src/drivers/mod.rs b/crates/core/database/src/drivers/mod.rs index 11fd5822..6dfdd7e8 100644 --- a/crates/core/database/src/drivers/mod.rs +++ b/crates/core/database/src/drivers/mod.rs @@ -102,6 +102,9 @@ impl Database { let config = config().await; let mut auth_config = authifier::Config { + password_scanning: authifier::config::PasswordScanning::EasyPwned { + endpoint: config.api.security.easypwned, + }, email_verification: if !config.api.smtp.host.is_empty() { EmailVerificationConfig::Enabled { smtp: SMTPSettings { @@ -118,6 +121,7 @@ impl Database { ), port: config.api.smtp.port, use_tls: config.api.smtp.use_tls, + use_starttls: None, }, expiry: Default::default(), templates: if config.production { @@ -134,6 +138,13 @@ impl Database { url: format!("{}/login/reset/", config.hosts.app), html: Some(include_str!("../../templates/reset.html").into()), }, + reset_existing: Template { + title: "You already have a Revolt account, reset your password." + .into(), + text: include_str!("../../templates/reset.txt").into(), + url: format!("{}/login/reset/", config.hosts.app), + html: Some(include_str!("../../templates/reset.html").into()), + }, deletion: Template { title: "Confirm account deletion.".into(), text: include_str!("../../templates/deletion.txt").into(), @@ -156,9 +167,16 @@ impl Database { url: format!("{}/login/reset/", config.hosts.app), html: None, }, + reset_existing: Template { + title: "Reset your password.".into(), + text: include_str!("../../templates/reset.whitelabel.txt").into(), + url: format!("{}/login/reset/", config.hosts.app), + html: None, + }, deletion: Template { title: "Confirm account deletion.".into(), - text: include_str!("../../templates/deletion.whitelabel.txt").into(), + text: include_str!("../../templates/deletion.whitelabel.txt") + .into(), url: format!("{}/delete/", config.hosts.app), html: None, }, diff --git a/crates/delta/Cargo.toml b/crates/delta/Cargo.toml index 536276aa..c6217c2a 100644 --- a/crates/delta/Cargo.toml +++ b/crates/delta/Cargo.toml @@ -52,10 +52,11 @@ async-std = { version = "1.8.0", features = [ lettre = "0.10.0-alpha.4" # web + rocket = { version = "0.5.1", default-features = false, features = ["json"] } rocket_cors = { git = "https://github.com/lawliet89/rocket_cors", rev = "072d90359b23e9b291df6b672c07c93de9c46011" } rocket_empty = { version = "0.1.1", features = ["schema"] } -rocket_authifier = { version = "1.0.10" } +rocket_authifier = { version = "1.0.13" } rocket_prometheus = "0.10.0-rc.3" # spec generation @@ -66,7 +67,7 @@ revolt_rocket_okapi = { version = "0.10.0", features = ["swagger"] } amqprs = { version = "1.7.0" } # core -authifier = "1.0.10" +authifier = "1.0.13" revolt-config = { path = "../core/config" } revolt-database = { path = "../core/database", features = [ "rocket-impl", From 20617943056f56c5a0851049ecaefbd693d6bc50 Mon Sep 17 00:00:00 2001 From: izzy Date: Sat, 10 May 2025 16:36:41 +0100 Subject: [PATCH 12/26] docs: configure reset existing email template --- crates/core/database/src/drivers/mod.rs | 6 +- .../database/templates/reset-existing.html | 188 ++++++++++++++++++ .../templates/reset-existing.original.html | 41 ++++ .../database/templates/reset-existing.txt | 19 ++ 4 files changed, 252 insertions(+), 2 deletions(-) create mode 100644 crates/core/database/templates/reset-existing.html create mode 100644 crates/core/database/templates/reset-existing.original.html create mode 100644 crates/core/database/templates/reset-existing.txt diff --git a/crates/core/database/src/drivers/mod.rs b/crates/core/database/src/drivers/mod.rs index 6dfdd7e8..013b0846 100644 --- a/crates/core/database/src/drivers/mod.rs +++ b/crates/core/database/src/drivers/mod.rs @@ -141,9 +141,11 @@ impl Database { reset_existing: Template { title: "You already have a Revolt account, reset your password." .into(), - text: include_str!("../../templates/reset.txt").into(), + text: include_str!("../../templates/reset-existing.txt").into(), url: format!("{}/login/reset/", config.hosts.app), - html: Some(include_str!("../../templates/reset.html").into()), + html: Some( + include_str!("../../templates/reset-existing.html").into(), + ), }, deletion: Template { title: "Confirm account deletion.".into(), diff --git a/crates/core/database/templates/reset-existing.html b/crates/core/database/templates/reset-existing.html new file mode 100644 index 00000000..00ef782b --- /dev/null +++ b/crates/core/database/templates/reset-existing.html @@ -0,0 +1,188 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/crates/core/database/templates/reset-existing.original.html b/crates/core/database/templates/reset-existing.original.html new file mode 100644 index 00000000..1273a69c --- /dev/null +++ b/crates/core/database/templates/reset-existing.original.html @@ -0,0 +1,41 @@ + + + + + + +
+ +
+

Password Reset

+

+ You tried to create a new account with or try to re-verify this email + but there is already an existing verified account under this email. +

+

+ If you wish, you can now proceed to reset the password on it, click + below to continue. +

+ Reset +
+
+ This email is intended for {{email}}
+ Sent from Revolt
+ Made in Europe +
+
+ Revolt Platforms Ltd. is a company incorporated and registered under the + laws of England and Wales.
+ Registered Company Number: 16260658
+ Registered Office:
+ Suite 5703 Unit 3A, 34-35 Hatton Garden,
+ Holborn, United Kingdom, EC1N 8DX +
+
+ + diff --git a/crates/core/database/templates/reset-existing.txt b/crates/core/database/templates/reset-existing.txt new file mode 100644 index 00000000..8c8fc9ed --- /dev/null +++ b/crates/core/database/templates/reset-existing.txt @@ -0,0 +1,19 @@ +You tried to create a new account with or try +to re-verify this email but there is already +an existing verified account under this email. + +If you wish, you can now proceed to reset the +password on it, click below to continue. + +Please navigate to: {{url}} + +This email is intended for {{email}} +Sent by Revolt +Made in Europe + +Revolt Platforms Ltd. is a company incorporated and registered under the laws of England and Wales. + +Registration Number: 16260658 +Registered Office: +Suite 5703 Unit 3A, 34-35 Hatton Garden, +Holborn, United Kingdom, EC1N 8DX From a4a093447526b14984ece6be4f2cf6d30c1fe49b Mon Sep 17 00:00:00 2001 From: izzy Date: Sat, 10 May 2025 16:38:26 +0100 Subject: [PATCH 13/26] feat: add use_starttls config option for SMTP --- Revolt.toml | 1 + crates/core/config/src/lib.rs | 3 ++- crates/core/database/src/drivers/mod.rs | 2 +- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/Revolt.toml b/Revolt.toml index 6847f3e5..33e04434 100644 --- a/Revolt.toml +++ b/Revolt.toml @@ -38,6 +38,7 @@ from_address = "development@revolt.chat" reply_to = "support@revolt.chat" port = 14025 use_tls = false +use_starttls = false [files.s3] # S3 protocol endpoint diff --git a/crates/core/config/src/lib.rs b/crates/core/config/src/lib.rs index 274baef3..8f67c76a 100644 --- a/crates/core/config/src/lib.rs +++ b/crates/core/config/src/lib.rs @@ -123,6 +123,7 @@ pub struct ApiSmtp { pub reply_to: Option, pub port: Option, pub use_tls: Option, + pub use_starttls: Option, } #[derive(Deserialize, Debug, Clone)] @@ -178,7 +179,7 @@ pub struct ApiWorkers { #[derive(Deserialize, Debug, Clone)] pub struct ApiUsers { - pub early_adopter_cutoff: Option + pub early_adopter_cutoff: Option, } #[derive(Deserialize, Debug, Clone)] diff --git a/crates/core/database/src/drivers/mod.rs b/crates/core/database/src/drivers/mod.rs index 013b0846..775047ff 100644 --- a/crates/core/database/src/drivers/mod.rs +++ b/crates/core/database/src/drivers/mod.rs @@ -121,7 +121,7 @@ impl Database { ), port: config.api.smtp.port, use_tls: config.api.smtp.use_tls, - use_starttls: None, + use_starttls: config.api.smtp.use_starttls, }, expiry: Default::default(), templates: if config.production { From 9632a0dc1b7e1cd1bc123af14215e17dad4a25de Mon Sep 17 00:00:00 2001 From: izzy Date: Sat, 10 May 2025 16:40:02 +0100 Subject: [PATCH 14/26] refactor: remove crate `bindings/node` --- Cargo.lock | 99 ------------- Cargo.toml | 1 - Dockerfile | 1 - Dockerfile.useCurrentArch | 1 - README.md | 31 ++-- crates/bindings/node/.gitignore | 7 - crates/bindings/node/Cargo.toml | 25 ---- crates/bindings/node/README.md | 92 ------------ crates/bindings/node/index.d.ts | 84 ----------- crates/bindings/node/package.json | 36 ----- crates/bindings/node/pnpm-lock.yaml | 117 --------------- crates/bindings/node/src/lib.rs | 221 ---------------------------- crates/bindings/node/test.js | 53 ------- crates/bindings/package-lock.json | 6 - scripts/build-image-layer.sh | 2 - 15 files changed, 15 insertions(+), 761 deletions(-) delete mode 100644 crates/bindings/node/.gitignore delete mode 100644 crates/bindings/node/Cargo.toml delete mode 100644 crates/bindings/node/README.md delete mode 100644 crates/bindings/node/index.d.ts delete mode 100644 crates/bindings/node/package.json delete mode 100644 crates/bindings/node/pnpm-lock.yaml delete mode 100644 crates/bindings/node/src/lib.rs delete mode 100644 crates/bindings/node/test.js delete mode 100644 crates/bindings/package-lock.json diff --git a/Cargo.lock b/Cargo.lock index 2f4b9b92..b0372552 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3986,16 +3986,6 @@ dependencies = [ "pkg-config", ] -[[package]] -name = "libloading" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc2f4eb4bc735547cfed7c0a4922cbd04a4655978c09b54f1f7b228750664c34" -dependencies = [ - "cfg-if", - "windows-targets 0.52.6", -] - [[package]] name = "libm" version = "0.2.11" @@ -4489,43 +4479,6 @@ dependencies = [ "tempfile", ] -[[package]] -name = "neon" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d75440242411c87dc39847b0e33e961ec1f10326a9d8ecf9c1ea64a3b3c13dc" -dependencies = [ - "getrandom", - "libloading", - "neon-macros", - "once_cell", - "semver", - "send_wrapper", - "smallvec", -] - -[[package]] -name = "neon-macros" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6813fde79b646e47e7ad75f480aa80ef76a5d9599e2717407961531169ee38b" -dependencies = [ - "quote 1.0.38", - "syn 2.0.94", - "syn-mid", -] - -[[package]] -name = "neon-serde4" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8778b4afaa506e067da24566623873c38797987be593232a4f9ad82c84bb3eb3" -dependencies = [ - "neon", - "num", - "serde", -] - [[package]] name = "new_debug_unreachable" version = "1.0.6" @@ -4567,19 +4520,6 @@ dependencies = [ "winapi", ] -[[package]] -name = "num" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "35bd024e8b2ff75562e5f34e7f4905839deb4b22955ef5e73d2fea1b9813cb23" -dependencies = [ - "num-complex", - "num-integer", - "num-iter", - "num-rational", - "num-traits", -] - [[package]] name = "num-bigint" version = "0.4.6" @@ -4607,15 +4547,6 @@ dependencies = [ "zeroize", ] -[[package]] -name = "num-complex" -version = "0.4.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73f88a1307638156682bada9d7604135552957b7818057dcef22705b4d509495" -dependencies = [ - "num-traits", -] - [[package]] name = "num-conv" version = "0.1.0" @@ -6233,19 +6164,6 @@ dependencies = [ "validator 0.16.1", ] -[[package]] -name = "revolt-nodejs-bindings" -version = "0.8.4" -dependencies = [ - "async-std", - "neon", - "neon-serde4", - "revolt-config", - "revolt-database", - "revolt-result", - "serde", -] - [[package]] name = "revolt-parser" version = "0.1.0" @@ -6991,12 +6909,6 @@ version = "1.0.24" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3cb6eb87a131f756572d7fb904f6e7b68633f09cca868c5df1c4b8d1a694bbba" -[[package]] -name = "send_wrapper" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd0b0ec5f1c1ca621c432a25813d8d60c88abe6d3e08a3eb9cf37d97a0fe3d73" - [[package]] name = "sentry" version = "0.31.8" @@ -7587,17 +7499,6 @@ dependencies = [ "unicode-ident", ] -[[package]] -name = "syn-mid" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5dc35bb08dd1ca3dfb09dce91fd2d13294d6711c88897d9a9d60acf39bce049" -dependencies = [ - "proc-macro2", - "quote 1.0.38", - "syn 2.0.94", -] - [[package]] name = "sync_wrapper" version = "0.1.2" diff --git a/Cargo.toml b/Cargo.toml index d2ae6117..19808e67 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,7 +6,6 @@ members = [ "crates/bonfire", "crates/core/*", "crates/services/*", - "crates/bindings/*", "crates/daemons/*", ] diff --git a/Dockerfile b/Dockerfile index ffb728f0..524e7e0e 100644 --- a/Dockerfile +++ b/Dockerfile @@ -17,7 +17,6 @@ RUN sh /tmp/build-image-layer.sh tools # Build all dependencies COPY Cargo.toml Cargo.lock ./ -COPY crates/bindings/node/Cargo.toml ./crates/bindings/node/ COPY crates/bonfire/Cargo.toml ./crates/bonfire/ COPY crates/delta/Cargo.toml ./crates/delta/ COPY crates/core/config/Cargo.toml ./crates/core/config/ diff --git a/Dockerfile.useCurrentArch b/Dockerfile.useCurrentArch index c9e73ef4..f36c0808 100644 --- a/Dockerfile.useCurrentArch +++ b/Dockerfile.useCurrentArch @@ -13,7 +13,6 @@ COPY scripts/build-image-layer.sh /tmp/ # Build all dependencies COPY Cargo.toml Cargo.lock ./ -COPY crates/bindings/node/Cargo.toml ./crates/bindings/node/ COPY crates/bonfire/Cargo.toml ./crates/bonfire/ COPY crates/delta/Cargo.toml ./crates/delta/ COPY crates/core/config/Cargo.toml ./crates/core/config/ diff --git a/README.md b/README.md index c6dbf8dc..1973ee20 100644 --- a/README.md +++ b/README.md @@ -12,22 +12,21 @@ The services and libraries that power the Revolt service.

-| Crate | Path | Description | | -| ------------------ | -------------------------------------------------- | ---------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `core/config` | [crates/core/config](crates/core/config) | Core: Configuration | ![Crates.io Version](https://img.shields.io/crates/v/revolt-config) ![Crates.io Version](https://img.shields.io/crates/msrv/revolt-config) ![Crates.io Version](https://img.shields.io/crates/size/revolt-config) ![Crates.io License](https://img.shields.io/crates/l/revolt-config) | -| `core/database` | [crates/core/database](crates/core/database) | Core: Database Implementation | ![Crates.io Version](https://img.shields.io/crates/v/revolt-database) ![Crates.io Version](https://img.shields.io/crates/msrv/revolt-database) ![Crates.io Version](https://img.shields.io/crates/size/revolt-database) ![Crates.io License](https://img.shields.io/crates/l/revolt-database) | -| `core/files` | [crates/core/files](crates/core/files) | Core: S3 and encryption subroutines | ![Crates.io Version](https://img.shields.io/crates/v/revolt-files) ![Crates.io Version](https://img.shields.io/crates/msrv/revolt-files) ![Crates.io Version](https://img.shields.io/crates/size/revolt-files) ![Crates.io License](https://img.shields.io/crates/l/revolt-files) | -| `core/models` | [crates/core/models](crates/core/models) | Core: API Models | ![Crates.io Version](https://img.shields.io/crates/v/revolt-models) ![Crates.io Version](https://img.shields.io/crates/msrv/revolt-models) ![Crates.io Version](https://img.shields.io/crates/size/revolt-models) ![Crates.io License](https://img.shields.io/crates/l/revolt-models) | -| `core/permissions` | [crates/core/permissions](crates/core/permissions) | Core: Permission Logic | ![Crates.io Version](https://img.shields.io/crates/v/revolt-permissions) ![Crates.io Version](https://img.shields.io/crates/msrv/revolt-permissions) ![Crates.io Version](https://img.shields.io/crates/size/revolt-permissions) ![Crates.io License](https://img.shields.io/crates/l/revolt-permissions) | -| `core/presence` | [crates/core/presence](crates/core/presence) | Core: User Presence | ![Crates.io Version](https://img.shields.io/crates/v/revolt-presence) ![Crates.io Version](https://img.shields.io/crates/msrv/revolt-presence) ![Crates.io Version](https://img.shields.io/crates/size/revolt-presence) ![Crates.io License](https://img.shields.io/crates/l/revolt-presence) | -| `core/result` | [crates/core/result](crates/core/result) | Core: Result and Error types | ![Crates.io Version](https://img.shields.io/crates/v/revolt-result) ![Crates.io Version](https://img.shields.io/crates/msrv/revolt-result) ![Crates.io Version](https://img.shields.io/crates/size/revolt-result) ![Crates.io License](https://img.shields.io/crates/l/revolt-result) | -| `delta` | [crates/delta](crates/delta) | REST API server | ![License](https://img.shields.io/badge/license-AGPL--3.0--or--later-blue) | -| `bonfire` | [crates/bonfire](crates/bonfire) | WebSocket events server | ![License](https://img.shields.io/badge/license-AGPL--3.0--or--later-blue) | -| `services/january` | [crates/services/january](crates/services/january) | Proxy server | ![License](https://img.shields.io/badge/license-AGPL--3.0--or--later-blue) | -| `services/autumn` | [crates/services/autumn](crates/services/autumn) | File server | ![License](https://img.shields.io/badge/license-AGPL--3.0--or--later-blue) | -| `bindings/node` | [crates/bindings/node](crates/bindings/node) | Node.js bindings for the Revolt software | ![License](https://img.shields.io/badge/license-AGPL--3.0--or--later-blue) | -| `daemons/crond` | [crates/daemons/crond](crates/daemons/crond) | Timed data clean up daemon server | ![License](https://img.shields.io/badge/license-AGPL--3.0--or--later-blue) | -| `daemons/pushd` | [crates/daemons/pushd](crates/daemons/pushd) | Push notification daemon server | ![License](https://img.shields.io/badge/license-AGPL--3.0--or--later-blue) | +| Crate | Path | Description | | +| ------------------ | -------------------------------------------------- | ----------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `core/config` | [crates/core/config](crates/core/config) | Core: Configuration | ![Crates.io Version](https://img.shields.io/crates/v/revolt-config) ![Crates.io Version](https://img.shields.io/crates/msrv/revolt-config) ![Crates.io Version](https://img.shields.io/crates/size/revolt-config) ![Crates.io License](https://img.shields.io/crates/l/revolt-config) | +| `core/database` | [crates/core/database](crates/core/database) | Core: Database Implementation | ![Crates.io Version](https://img.shields.io/crates/v/revolt-database) ![Crates.io Version](https://img.shields.io/crates/msrv/revolt-database) ![Crates.io Version](https://img.shields.io/crates/size/revolt-database) ![Crates.io License](https://img.shields.io/crates/l/revolt-database) | +| `core/files` | [crates/core/files](crates/core/files) | Core: S3 and encryption subroutines | ![Crates.io Version](https://img.shields.io/crates/v/revolt-files) ![Crates.io Version](https://img.shields.io/crates/msrv/revolt-files) ![Crates.io Version](https://img.shields.io/crates/size/revolt-files) ![Crates.io License](https://img.shields.io/crates/l/revolt-files) | +| `core/models` | [crates/core/models](crates/core/models) | Core: API Models | ![Crates.io Version](https://img.shields.io/crates/v/revolt-models) ![Crates.io Version](https://img.shields.io/crates/msrv/revolt-models) ![Crates.io Version](https://img.shields.io/crates/size/revolt-models) ![Crates.io License](https://img.shields.io/crates/l/revolt-models) | +| `core/permissions` | [crates/core/permissions](crates/core/permissions) | Core: Permission Logic | ![Crates.io Version](https://img.shields.io/crates/v/revolt-permissions) ![Crates.io Version](https://img.shields.io/crates/msrv/revolt-permissions) ![Crates.io Version](https://img.shields.io/crates/size/revolt-permissions) ![Crates.io License](https://img.shields.io/crates/l/revolt-permissions) | +| `core/presence` | [crates/core/presence](crates/core/presence) | Core: User Presence | ![Crates.io Version](https://img.shields.io/crates/v/revolt-presence) ![Crates.io Version](https://img.shields.io/crates/msrv/revolt-presence) ![Crates.io Version](https://img.shields.io/crates/size/revolt-presence) ![Crates.io License](https://img.shields.io/crates/l/revolt-presence) | +| `core/result` | [crates/core/result](crates/core/result) | Core: Result and Error types | ![Crates.io Version](https://img.shields.io/crates/v/revolt-result) ![Crates.io Version](https://img.shields.io/crates/msrv/revolt-result) ![Crates.io Version](https://img.shields.io/crates/size/revolt-result) ![Crates.io License](https://img.shields.io/crates/l/revolt-result) | +| `delta` | [crates/delta](crates/delta) | REST API server | ![License](https://img.shields.io/badge/license-AGPL--3.0--or--later-blue) | +| `bonfire` | [crates/bonfire](crates/bonfire) | WebSocket events server | ![License](https://img.shields.io/badge/license-AGPL--3.0--or--later-blue) | +| `services/january` | [crates/services/january](crates/services/january) | Proxy server | ![License](https://img.shields.io/badge/license-AGPL--3.0--or--later-blue) | +| `services/autumn` | [crates/services/autumn](crates/services/autumn) | File server | ![License](https://img.shields.io/badge/license-AGPL--3.0--or--later-blue) | +| `daemons/crond` | [crates/daemons/crond](crates/daemons/crond) | Timed data clean up daemon server | ![License](https://img.shields.io/badge/license-AGPL--3.0--or--later-blue) | +| `daemons/pushd` | [crates/daemons/pushd](crates/daemons/pushd) | Push notification daemon server | ![License](https://img.shields.io/badge/license-AGPL--3.0--or--later-blue) |
diff --git a/crates/bindings/node/.gitignore b/crates/bindings/node/.gitignore deleted file mode 100644 index c76a159c..00000000 --- a/crates/bindings/node/.gitignore +++ /dev/null @@ -1,7 +0,0 @@ -target -index.node -**/node_modules -**/.DS_Store -npm-debug.log* -cargo.log -cross.log diff --git a/crates/bindings/node/Cargo.toml b/crates/bindings/node/Cargo.toml deleted file mode 100644 index e2cfba1c..00000000 --- a/crates/bindings/node/Cargo.toml +++ /dev/null @@ -1,25 +0,0 @@ -[package] -name = "revolt-nodejs-bindings" -version = "0.8.4" -description = "Node.js bindings for the Revolt software" -authors = ["Paul Makles "] -license = "MIT" -edition = "2021" -exclude = ["index.node"] - -[lib] -crate-type = ["cdylib"] - -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html - -[dependencies] -neon = "1.0.0" -neon-serde4 = "1.0.0" - -serde = { version = "1", features = ["derive"] } - -async-std = "1.12.0" - -revolt-config = { version = "0.8.4", path = "../../core/config" } -revolt-result = { version = "0.8.4", path = "../../core/result" } -revolt-database = { version = "0.8.4", path = "../../core/database" } diff --git a/crates/bindings/node/README.md b/crates/bindings/node/README.md deleted file mode 100644 index f2ccee6e..00000000 --- a/crates/bindings/node/README.md +++ /dev/null @@ -1,92 +0,0 @@ -# revolt.node - -**revolt.node:** Node.js bindings for the Revolt software - -This project was bootstrapped by [create-neon](https://www.npmjs.com/package/create-neon). - -## Building revolt.node - -Building revolt.node requires a [supported version of Node and Rust](https://github.com/neon-bindings/neon#platform-support). - -To run the build, run: - -```sh -$ npm run build -``` - -This command uses the [@neon-rs/cli](https://www.npmjs.com/package/@neon-rs/cli) utility to assemble the binary Node addon from the output of `cargo`. - -## Exploring revolt.node - -After building revolt.node, you can explore its exports at the Node console: - -```sh -$ npm i -$ npm run build -$ node -> require('.').hello() -'hello node' -``` - -## Available Scripts - -In the project directory, you can run: - -#### `npm install` - -Installs the project, including running `npm run build`. - -#### `npm run build` - -Builds the Node addon (`index.node`) from source, generating a release build with `cargo --release`. - -Additional [`cargo build`](https://doc.rust-lang.org/cargo/commands/cargo-build.html) arguments may be passed to `npm run build` and similar commands. For example, to enable a [cargo feature](https://doc.rust-lang.org/cargo/reference/features.html): - -``` -npm run build -- --feature=beetle -``` - -#### `npm run debug` - -Similar to `npm run build` but generates a debug build with `cargo`. - -#### `npm run cross` - -Similar to `npm run build` but uses [cross-rs](https://github.com/cross-rs/cross) to cross-compile for another platform. Use the [`CARGO_BUILD_TARGET`](https://doc.rust-lang.org/cargo/reference/config.html#buildtarget) environment variable to select the build target. - -#### `npm test` - -Runs the unit tests by calling `cargo test`. You can learn more about [adding tests to your Rust code](https://doc.rust-lang.org/book/ch11-01-writing-tests.html) from the [Rust book](https://doc.rust-lang.org/book/). - -## Project Layout - -The directory structure of this project is: - -``` -revolt.node/ -├── Cargo.toml -├── README.md -├── src/ -| └── lib.rs -├── index.node -├── package.json -└── target/ -``` - -| Entry | Purpose | -|----------------|------------------------------------------------------------------------------------------------------------------------------------------| -| `Cargo.toml` | The Cargo [manifest file](https://doc.rust-lang.org/cargo/reference/manifest.html), which informs the `cargo` command. | -| `README.md` | This file. | -| `src/` | The directory tree containing the Rust source code for the project. | -| `lib.rs` | Entry point for the Rust source code. | -| `index.node` | The main module, a [Node addon](https://nodejs.org/api/addons.html) generated by the build and pointed to by `"main"` in `package.json`. | -| `package.json` | The npm [manifest file](https://docs.npmjs.com/cli/v7/configuring-npm/package-json), which informs the `npm` command. | -| `target/` | Binary artifacts generated by the Rust build. | - -## Learn More - -Learn more about: - -- [Neon](https://neon-bindings.com). -- [Rust](https://www.rust-lang.org). -- [Node](https://nodejs.org). diff --git a/crates/bindings/node/index.d.ts b/crates/bindings/node/index.d.ts deleted file mode 100644 index 0417ba4d..00000000 --- a/crates/bindings/node/index.d.ts +++ /dev/null @@ -1,84 +0,0 @@ -import { Channel, User } from "revolt-api"; - -/** - * Opaque type for Revolt database - */ -export declare interface Database {} - -/** - * Opaque type for Revolt database - */ -export declare interface OpaqueUser {} - -/** - * Error type from Revolt backend - */ -export declare interface Err { - type: string; - location: string; -} - -/** - * Initialises background tasks and logging, must be called before anything else! - * Can be called multiple times! - */ -export declare function init(); - -/** - * Gets a new handle to the Revolt database - * @returns {Database} Handle - */ -export declare function database(): Database; - -/** - * Fetch user from database - * @param {string} userId User's ID - * @this {Database} - */ -export declare function database_fetch_user(userId: string): OpaqueUser; - -/** - * Fetch user from database - * @param {string} username Username - * @param {string} discriminator Discriminator - * @this {Database} - */ -export declare function database_fetch_user_by_username( - username: string, - discriminator: string -): OpaqueUser; - -/** - * Gets model data as JSON - * @this {OpaqueUser} - */ -export declare function model_data(): User; - -/** - * Gets error if the model failed to fetch - * @this {OpaqueUser} - */ -export declare function model_error(): Err; - -/** - * Open a direct message channel between two users - * @param {string} userA User A ID - * @param {string} userB User B ID - * @returns Existing or newly created channel - */ -export declare function proc_channels_create_dm( - userA: string, - userB: string -): Promise; - -/** - * Suspend a user - * @param {string} user User - * @param {number} duration Duration (in days), set to 0 for indefinite - * @param {string} reason Pipe-separated list of reasons (e.g. reason1|reason2|reason3) - */ -export declare function proc_users_suspend( - user: OpaqueUser, - duration: number, - reason: string -): Promise<{ error: Err }>; diff --git a/crates/bindings/node/package.json b/crates/bindings/node/package.json deleted file mode 100644 index 70768a86..00000000 --- a/crates/bindings/node/package.json +++ /dev/null @@ -1,36 +0,0 @@ -{ - "name": "revolt-nodejs-bindings", - "version": "0.7.15-rev0.0.3", - "description": "Node.js bindings for the Revolt software", - "main": "index.node", - "scripts": { - "test": "cargo test", - "cargo-build": "cargo build --message-format=json > cargo.log", - "cross-build": "cross build --message-format=json > cross.log", - "postcargo-build": "neon dist < cargo.log", - "postcross-build": "neon dist -m /target < cross.log", - "debug": "npm run cargo-build --", - "build": "npm run cargo-build -- --release", - "cross": "npm run cross-build -- --release" - }, - "author": "Paul Makles", - "license": "AGPL-3.0", - "devDependencies": { - "@neon-rs/cli": "0.1.73" - }, - "repository": { - "type": "git", - "url": "git+https://github.com/revoltchat/backend" - }, - "keywords": [ - "revolt", - "chat" - ], - "bugs": { - "url": "https://github.com/revoltchat/backend/issues" - }, - "homepage": "https://github.com/revoltchat/backend#readme", - "dependencies": { - "revolt-api": "^0.7.15" - } -} \ No newline at end of file diff --git a/crates/bindings/node/pnpm-lock.yaml b/crates/bindings/node/pnpm-lock.yaml deleted file mode 100644 index 1d623ad9..00000000 --- a/crates/bindings/node/pnpm-lock.yaml +++ /dev/null @@ -1,117 +0,0 @@ -lockfileVersion: '6.0' - -settings: - autoInstallPeers: true - excludeLinksFromLockfile: false - -dependencies: - revolt-api: - specifier: ^0.7.15 - version: 0.7.15 - -devDependencies: - '@neon-rs/cli': - specifier: 0.1.73 - version: 0.1.73 - -packages: - - /@cargo-messages/android-arm-eabi@0.1.72: - resolution: {integrity: sha512-gGZxIM1mj+Y5x+ULND6ZCNr7f70OJi9wDlycSK8hGONy9wrChN6JAIHryddC5cqcwlYAoQ6IDcDFElnhAYbybA==} - cpu: [arm] - os: [android] - requiresBuild: true - dev: true - optional: true - - /@cargo-messages/darwin-arm64@0.1.72: - resolution: {integrity: sha512-EAzN5MLaXPljZKZDO5qR+aBs44eSq2ZbEnS7AI/FziE3MzeXbrGOS3fLba5+7yWPFXJyZolXzePm8N1EBv8ovg==} - cpu: [arm64] - os: [darwin] - requiresBuild: true - dev: true - optional: true - - /@cargo-messages/darwin-x64@0.1.72: - resolution: {integrity: sha512-RLo6j8s3nYbjdd1LDct4wamfChyRit7zokUuxtIYCu9XOlltkN5vnj1vwnrPvoqCMZ/7CbbuHFwSTn9A71de/w==} - cpu: [x64] - os: [darwin] - requiresBuild: true - dev: true - optional: true - - /@cargo-messages/linux-arm-gnueabihf@0.1.72: - resolution: {integrity: sha512-tHsRshuzfjrX6SDW3jg6al8vMNLTMgczGnVYl5RuBZf/yrAUuwe30KxA9ge6w6mW6Ox797DyBchzAc9OLgTgmQ==} - cpu: [arm] - os: [linux] - requiresBuild: true - dev: true - optional: true - - /@cargo-messages/linux-x64-gnu@0.1.72: - resolution: {integrity: sha512-VGtL6CCnUbhsP4aYuBNT5kfrAL7o0qjrxw97a+ax13t+nJd26tVEEIKHMu5drvvS/Nm/hn7sLT8zMnnCv0pvHg==} - cpu: [x64] - os: [linux] - requiresBuild: true - dev: true - optional: true - - /@cargo-messages/win32-arm64-msvc@0.1.72: - resolution: {integrity: sha512-V93Cgz39K+yqa3MveNbhh29pYCp8izK5uEavjPoxlNxAbsMCWH+s0verGDdUcfGxjR1H2V7oZ4FszPqR2SqMRQ==} - cpu: [arm64] - os: [win32] - requiresBuild: true - dev: true - optional: true - - /@cargo-messages/win32-x64-msvc@0.1.72: - resolution: {integrity: sha512-knz3uSrO0OSbq3U5VWfCY8FB4NsM43BOWLZ7x4sfaMOC1XWv+IyvDdkLe6DhJx8KUw46KIAimYs9YROrp6l46Q==} - cpu: [x64] - os: [win32] - requiresBuild: true - dev: true - optional: true - - /@neon-rs/cli@0.1.73: - resolution: {integrity: sha512-1kv8S/feB6UQWQQwsnGfkSkEBOtlFDNExnioL81E2BwvUWgjQPaseHgpi2EpWVgsPUgur5eBm4QowmlpWkD4/w==} - hasBin: true - optionalDependencies: - '@cargo-messages/android-arm-eabi': 0.1.72 - '@cargo-messages/darwin-arm64': 0.1.72 - '@cargo-messages/darwin-x64': 0.1.72 - '@cargo-messages/linux-arm-gnueabihf': 0.1.72 - '@cargo-messages/linux-x64-gnu': 0.1.72 - '@cargo-messages/win32-arm64-msvc': 0.1.72 - '@cargo-messages/win32-x64-msvc': 0.1.72 - dev: true - - /axios@0.26.1: - resolution: {integrity: sha512-fPwcX4EvnSHuInCMItEhAGnaSEXRBjtzh9fOtsE6E1G6p7vl7edEeZe11QHf18+6+9gR5PbKV/sGKNaD8YaMeA==} - dependencies: - follow-redirects: 1.15.6 - transitivePeerDependencies: - - debug - dev: false - - /follow-redirects@1.15.6: - resolution: {integrity: sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==} - engines: {node: '>=4.0'} - peerDependencies: - debug: '*' - peerDependenciesMeta: - debug: - optional: true - dev: false - - /lodash.defaultsdeep@4.6.1: - resolution: {integrity: sha512-3j8wdDzYuWO3lM3Reg03MuQR957t287Rpcxp1njpEa8oDrikb+FwGdW3n+FELh/A6qib6yPit0j/pv9G/yeAqA==} - dev: false - - /revolt-api@0.7.15: - resolution: {integrity: sha512-rWRnjBFvoXt/RHRxHg9KuP+x1Jk61KdsOpKOczVJg5tIqGDmqp/6QZHw5rJTtG+wCH3Ah3YKwY+MM5NHfg1W3Q==} - dependencies: - axios: 0.26.1 - lodash.defaultsdeep: 4.6.1 - transitivePeerDependencies: - - debug - dev: false diff --git a/crates/bindings/node/src/lib.rs b/crates/bindings/node/src/lib.rs deleted file mode 100644 index 85b39183..00000000 --- a/crates/bindings/node/src/lib.rs +++ /dev/null @@ -1,221 +0,0 @@ -#[macro_use] -extern crate serde; - -use std::sync::OnceLock; - -use neon::prelude::*; -use revolt_database::{Database, DatabaseInfo}; - -fn js_init(mut cx: FunctionContext) -> JsResult { - // static INIT: OnceLock<()> = OnceLock::new(); - // if INIT.get().is_none() { - // INIT.get_or_init(|| { - // async_std::task::block_on(async { - // revolt_config::configure!(api); - - // match DatabaseInfo::Auto.connect().await { - // Ok(db) => { - // let authifier_db = db.clone().to_authifier().await.database; - // revolt_database::tasks::start_workers(db, authifier_db); - // Ok(()) - // } - // Err(err) => Err(err), - // } - // }) - // .or_else(|err| cx.throw_error(err)) - // .unwrap(); - // }); - // } - - Ok(cx.undefined()) -} - -struct DatabaseBinding(Database, Channel); -impl Finalize for DatabaseBinding {} -impl DatabaseBinding { - fn take(&self) -> (Database, Channel) { - (self.0.clone(), self.1.clone()) - } -} - -fn js_database(mut cx: FunctionContext) -> JsResult> { - let db = async_std::task::block_on(DatabaseInfo::Auto.connect()) - .or_else(|err| cx.throw_error(err))?; - - let channel = cx.channel(); - Ok(cx.boxed(DatabaseBinding(db, channel))) -} - -// Implementations for models -#[derive(Clone)] -#[allow(clippy::large_enum_variant)] -enum Model { - User(revolt_database::User), - Error(revolt_result::Error), -} - -impl Model { - fn give(&self) -> Model { - self.clone() - } -} - -impl Finalize for Model {} - -macro_rules! shim_boxed { - ($cx: ident, $name: ident, $model: ident, $( $variable: ident $type: ident $id: expr )+, $cmd: ident, $( $arg: expr, )+) => { - fn $name(mut cx: FunctionContext) -> JsResult { - $( - let $variable = cx.argument::<$type>($id)?.value(&mut cx); - )+ - - let (db, channel) = cx.this::>()?.take(); - let (deferred, promise) = cx.promise(); - - async_std::task::spawn(async move { - let result = db.$cmd($($arg,)+).await; - deferred.settle_with(&channel, move |mut cx| { - Ok(cx.boxed(match result { - Ok(value) => Model::$model(value), - Err(error) => Model::Error(error) - })) - }) - }); - - Ok(promise) - } - - $cx.export_function(stringify!($name), $name)?; - }; -} - -fn js_data(mut cx: FunctionContext) -> JsResult { - match cx.this::>()?.give() { - Model::Error(_) => neon_serde4::to_value(&mut cx, &None::<()>), - Model::User(user) => neon_serde4::to_value(&mut cx, &user), - } - .or_else(|e| cx.throw_error(e.to_string())) -} - -fn js_error(mut cx: FunctionContext) -> JsResult { - let value = match cx.this::>()?.give() { - Model::Error(err) => Some(err), - _ => None, - }; - - neon_serde4::to_value(&mut cx, &value).or_else(|e| cx.throw_error(e.to_string())) -} - -// Basic data implementation -#[derive(Serialize, Deserialize)] -struct ResultBinding { - #[serde(flatten)] - value: Option, - error: Option, -} - -macro_rules! shim { - ($cx: ident, $name: ident, $( $variable: ident $type: ident $id: expr )*, $( $model: ident $modelType: ident $modelId: expr )*, | $db: ident | $closure: expr, $( $arg: expr, )+) => { - fn $name(mut cx: FunctionContext) -> JsResult { - $( - let $variable = cx.argument::<$type>($id)?.value(&mut cx); - )* - - $( - let mut $model = if let Model::$modelType(value) = cx.argument::>($modelId)?.give() { - value - } else { - unreachable!() - }; - )* - - let (db, channel) = cx.this::>()?.take(); - let (deferred, promise) = cx.promise(); - - async_std::task::spawn(async move { - #[allow(clippy::redundant_closure_call)] - let result = (|$db: $crate::Database| $closure)(db.clone()).await; - deferred.settle_with(&channel, move |mut cx| { - neon_serde4::to_value( - &mut cx, - &match result { - Ok(value) => ResultBinding { - value: Some(value), - error: None, - }, - Err(error) => ResultBinding { - value: None, - error: Some(error), - }, - }, - ) - .or_else(|e| cx.throw_error(e.to_string())) - }) - }); - - Ok(promise) - } - - $cx.export_function(stringify!($name), $name)?; - }; -} - -#[neon::main] -fn main(mut cx: ModuleContext) -> NeonResult<()> { - // initialise required background stuff - cx.export_function("init", js_init)?; - - // database & model stuff - cx.export_function("database", js_database)?; - cx.export_function("model_data", js_data)?; - cx.export_function("model_error", js_error)?; - - shim_boxed!( - cx, - database_fetch_user, - User, - user_id JsString 0, - fetch_user, - &user_id, - ); - - shim_boxed!( - cx, - database_fetch_user_by_username, - User, - username JsString 0 - discriminator JsString 1, - fetch_user_by_username, - &username, &discriminator, - ); - - // procedure calls - shim!( - cx, - proc_channels_create_dm, - user_a JsString 0 - user_b JsString 1, - , - |db| async move { - let user_a = db.fetch_user(&user_a).await?; - let user_b = db.fetch_user(&user_b).await?; - revolt_database::Channel::create_dm(&db, &user_a, &user_b).await - }, - &userA, &userB, - ); - - shim!( - cx, - proc_users_suspend, - duration JsNumber 1 - reason JsString 2, - user User 0, - |db| async move { - let duration = duration as usize; - user.suspend(&db, if duration == 0 { None } else { Some(duration) }, Some(reason.split('|').map(|x| x.to_owned()).collect())).await - }, - &user, - ); - - Ok(()) -} diff --git a/crates/bindings/node/test.js b/crates/bindings/node/test.js deleted file mode 100644 index d8f60174..00000000 --- a/crates/bindings/node/test.js +++ /dev/null @@ -1,53 +0,0 @@ -const Internal = require("."); - -// playing around with class wrapper, not practical -class Model { - constructor(model) { - this.model = model; - } - - data() { - return Internal.model_data.bind(this.model)(); - } - - error() { - return Internal.model_error.bind(this.model)(); - } -} - -class User extends Model { - constructor(db, user) { - super(user); - this.db = db; - } -} - -class Database { - constructor() { - this.db = Internal.database(); - } - - async fetchUser(userId) { - return new User( - this, - await Internal.database_fetch_user.bind(this.db)(userId) - ); - } - - async fetchUserByUsername(username, discriminator) { - return new User( - this, - await Internal.database_fetch_user_by_username.bind(this.db)( - username, - discriminator - ) - ); - } -} - -const db = new Database(); -db.fetchUserByUsername("dos", "7624").then((user) => console.info(user.data())); -db.fetchUserByUsername("dos", "1111").then((user) => console.info(user.data())); -db.fetchUserByUsername("dos", "1111").then((user) => - console.info(user.error()) -); diff --git a/crates/bindings/package-lock.json b/crates/bindings/package-lock.json deleted file mode 100644 index 9376d3a9..00000000 --- a/crates/bindings/package-lock.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "name": "bindings", - "lockfileVersion": 3, - "requires": true, - "packages": {} -} diff --git a/scripts/build-image-layer.sh b/scripts/build-image-layer.sh index 4acb2f71..0a0fa32b 100644 --- a/scripts/build-image-layer.sh +++ b/scripts/build-image-layer.sh @@ -22,7 +22,6 @@ tools() { deps() { mkdir -p \ - crates/bindings/node/src \ crates/bonfire/src \ crates/delta/src \ crates/core/config/src \ @@ -45,7 +44,6 @@ deps() { tee crates/daemons/crond/src/main.rs | tee crates/daemons/pushd/src/main.rs echo '' | - tee crates/bindings/node/src/lib.rs | tee crates/core/config/src/lib.rs | tee crates/core/database/src/lib.rs | tee crates/core/files/src/lib.rs | From 68bcfcb6265257265d3cc2b590c53927f3fb9b3b Mon Sep 17 00:00:00 2001 From: izzy Date: Sat, 10 May 2025 16:43:30 +0100 Subject: [PATCH 15/26] fix: ensure easypwned api is actually set before using --- crates/core/database/src/drivers/mod.rs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/crates/core/database/src/drivers/mod.rs b/crates/core/database/src/drivers/mod.rs index 775047ff..1c9ae967 100644 --- a/crates/core/database/src/drivers/mod.rs +++ b/crates/core/database/src/drivers/mod.rs @@ -3,6 +3,7 @@ mod reference; use authifier::config::Captcha; use authifier::config::EmailVerificationConfig; +use authifier::config::PasswordScanning; use authifier::config::ResolveIp; use authifier::config::SMTPSettings; use authifier::config::Shield; @@ -102,8 +103,12 @@ impl Database { let config = config().await; let mut auth_config = authifier::Config { - password_scanning: authifier::config::PasswordScanning::EasyPwned { - endpoint: config.api.security.easypwned, + password_scanning: if config.api.security.easypwned.is_empty() { + Default::default() + } else { + PasswordScanning::EasyPwned { + endpoint: config.api.security.easypwned, + } }, email_verification: if !config.api.smtp.host.is_empty() { EmailVerificationConfig::Enabled { From 8ea8f50fb8a5b737339088a50d1aa5d282303c1e Mon Sep 17 00:00:00 2001 From: izzy Date: Sat, 10 May 2025 16:51:38 +0100 Subject: [PATCH 16/26] chore: bump version to 0.8.5 closes #402 --- Cargo.lock | 28 ++++++++++++++-------------- crates/bonfire/Cargo.toml | 4 ++-- crates/core/config/Cargo.toml | 4 ++-- crates/core/database/Cargo.toml | 14 +++++++------- crates/core/files/Cargo.toml | 6 +++--- crates/core/models/Cargo.toml | 6 +++--- crates/core/parser/Cargo.toml | 4 ++-- crates/core/permissions/Cargo.toml | 4 ++-- crates/core/presence/Cargo.toml | 2 +- crates/core/result/Cargo.toml | 2 +- crates/daemons/crond/Cargo.toml | 10 +++++----- crates/daemons/pushd/Cargo.toml | 10 +++++----- crates/delta/Cargo.toml | 2 +- crates/services/autumn/Cargo.toml | 10 +++++----- crates/services/january/Cargo.toml | 10 +++++----- 15 files changed, 58 insertions(+), 58 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b0372552..6d6ef809 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5904,7 +5904,7 @@ dependencies = [ [[package]] name = "revolt-autumn" -version = "0.8.4" +version = "0.8.5" dependencies = [ "axum", "axum-macros", @@ -5941,7 +5941,7 @@ dependencies = [ [[package]] name = "revolt-bonfire" -version = "0.8.4" +version = "0.8.5" dependencies = [ "async-channel 2.3.1", "async-std", @@ -5971,7 +5971,7 @@ dependencies = [ [[package]] name = "revolt-config" -version = "0.8.4" +version = "0.8.5" dependencies = [ "async-std", "cached", @@ -5987,7 +5987,7 @@ dependencies = [ [[package]] name = "revolt-crond" -version = "0.8.4" +version = "0.8.5" dependencies = [ "log", "revolt-config", @@ -5999,7 +5999,7 @@ dependencies = [ [[package]] name = "revolt-database" -version = "0.8.4" +version = "0.8.5" dependencies = [ "amqprs", "async-lock 2.8.0", @@ -6049,7 +6049,7 @@ dependencies = [ [[package]] name = "revolt-delta" -version = "0.8.4" +version = "0.8.5" dependencies = [ "amqprs", "async-channel 1.9.0", @@ -6096,7 +6096,7 @@ dependencies = [ [[package]] name = "revolt-files" -version = "0.8.4" +version = "0.8.5" dependencies = [ "aes-gcm", "aws-config", @@ -6119,7 +6119,7 @@ dependencies = [ [[package]] name = "revolt-january" -version = "0.8.4" +version = "0.8.5" dependencies = [ "async-recursion", "axum", @@ -6147,7 +6147,7 @@ dependencies = [ [[package]] name = "revolt-models" -version = "0.8.4" +version = "0.8.5" dependencies = [ "indexmap 1.9.3", "iso8601-timestamp", @@ -6166,14 +6166,14 @@ dependencies = [ [[package]] name = "revolt-parser" -version = "0.1.0" +version = "0.1.1" dependencies = [ "logos", ] [[package]] name = "revolt-permissions" -version = "0.8.4" +version = "0.8.5" dependencies = [ "async-std", "async-trait", @@ -6188,7 +6188,7 @@ dependencies = [ [[package]] name = "revolt-presence" -version = "0.8.4" +version = "0.8.5" dependencies = [ "async-std", "log", @@ -6199,7 +6199,7 @@ dependencies = [ [[package]] name = "revolt-pushd" -version = "0.8.4" +version = "0.8.5" dependencies = [ "amqprs", "async-trait", @@ -6225,7 +6225,7 @@ dependencies = [ [[package]] name = "revolt-result" -version = "0.8.4" +version = "0.8.5" dependencies = [ "axum", "revolt_okapi", diff --git a/crates/bonfire/Cargo.toml b/crates/bonfire/Cargo.toml index 1eb1cd9c..ac852bae 100644 --- a/crates/bonfire/Cargo.toml +++ b/crates/bonfire/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-bonfire" -version = "0.8.4" +version = "0.8.5" license = "AGPL-3.0-or-later" edition = "2021" @@ -41,7 +41,7 @@ revolt-result = { path = "../core/result" } revolt-models = { path = "../core/models" } revolt-config = { path = "../core/config" } revolt-database = { path = "../core/database" } -revolt-permissions = { version = "0.8.4", path = "../core/permissions" } +revolt-permissions = { version = "0.8.5", path = "../core/permissions" } revolt-presence = { path = "../core/presence", features = ["redis-is-patched"] } # redis diff --git a/crates/core/config/Cargo.toml b/crates/core/config/Cargo.toml index 00c8a00c..2411d099 100644 --- a/crates/core/config/Cargo.toml +++ b/crates/core/config/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-config" -version = "0.8.4" +version = "0.8.5" edition = "2021" license = "MIT" authors = ["Paul Makles "] @@ -34,4 +34,4 @@ pretty_env_logger = "0.4.0" sentry = "0.31.5" # Core -revolt-result = { version = "0.8.4", path = "../result", optional = true } +revolt-result = { version = "0.8.5", path = "../result", optional = true } diff --git a/crates/core/database/Cargo.toml b/crates/core/database/Cargo.toml index 1f0fc7e6..709cb577 100644 --- a/crates/core/database/Cargo.toml +++ b/crates/core/database/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-database" -version = "0.8.4" +version = "0.8.5" edition = "2021" license = "AGPL-3.0-or-later" authors = ["Paul Makles "] @@ -24,19 +24,19 @@ default = ["mongodb", "async-std-runtime", "tasks"] [dependencies] # Core -revolt-config = { version = "0.8.4", path = "../config", features = [ +revolt-config = { version = "0.8.5", path = "../config", features = [ "report-macros", ] } -revolt-result = { version = "0.8.4", path = "../result" } -revolt-models = { version = "0.8.4", path = "../models", features = [ +revolt-result = { version = "0.8.5", path = "../result" } +revolt-models = { version = "0.8.5", path = "../models", features = [ "validator", ] } -revolt-presence = { version = "0.8.4", path = "../presence" } -revolt-permissions = { version = "0.8.4", path = "../permissions", features = [ +revolt-presence = { version = "0.8.5", path = "../presence" } +revolt-permissions = { version = "0.8.5", path = "../permissions", features = [ "serde", "bson", ] } -revolt-parser = { version = "0.1.0", path = "../parser" } +revolt-parser = { version = "0.1.1", path = "../parser" } # Utility log = "0.4" diff --git a/crates/core/files/Cargo.toml b/crates/core/files/Cargo.toml index e8303136..3d77ba63 100644 --- a/crates/core/files/Cargo.toml +++ b/crates/core/files/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-files" -version = "0.8.4" +version = "0.8.5" edition = "2021" license = "AGPL-3.0-or-later" authors = ["Paul Makles "] @@ -20,10 +20,10 @@ typenum = "1.17.0" aws-config = "1.5.5" aws-sdk-s3 = { version = "1.46.0", features = ["behavior-version-latest"] } -revolt-config = { version = "0.8.4", path = "../config", features = [ +revolt-config = { version = "0.8.5", path = "../config", features = [ "report-macros", ] } -revolt-result = { version = "0.8.4", path = "../result" } +revolt-result = { version = "0.8.5", path = "../result" } # image processing jxl-oxide = "0.8.1" diff --git a/crates/core/models/Cargo.toml b/crates/core/models/Cargo.toml index c2c667be..d1308d39 100644 --- a/crates/core/models/Cargo.toml +++ b/crates/core/models/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-models" -version = "0.8.4" +version = "0.8.5" edition = "2021" license = "MIT" authors = ["Paul Makles "] @@ -20,8 +20,8 @@ default = ["serde", "partials", "rocket"] [dependencies] # Core -revolt-config = { version = "0.8.4", path = "../config" } -revolt-permissions = { version = "0.8.4", path = "../permissions" } +revolt-config = { version = "0.8.5", path = "../config" } +revolt-permissions = { version = "0.8.5", path = "../permissions" } # Utility regex = "1.11" diff --git a/crates/core/parser/Cargo.toml b/crates/core/parser/Cargo.toml index f9b0c700..6a6913ad 100644 --- a/crates/core/parser/Cargo.toml +++ b/crates/core/parser/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "revolt-parser" -version = "0.1.0" +version = "0.1.1" edition = "2021" [dependencies] -logos = { version = "*" } \ No newline at end of file +logos = { version = "*" } diff --git a/crates/core/permissions/Cargo.toml b/crates/core/permissions/Cargo.toml index f2ffb04c..3b2f9ac8 100644 --- a/crates/core/permissions/Cargo.toml +++ b/crates/core/permissions/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-permissions" -version = "0.8.4" +version = "0.8.5" edition = "2021" license = "MIT" authors = ["Paul Makles "] @@ -21,7 +21,7 @@ async-std = { version = "1.8.0", features = ["attributes"] } [dependencies] # Core -revolt-result = { version = "0.8.4", path = "../result" } +revolt-result = { version = "0.8.5", path = "../result" } # Utility auto_ops = "0.3.0" diff --git a/crates/core/presence/Cargo.toml b/crates/core/presence/Cargo.toml index 3470514f..874e65c6 100644 --- a/crates/core/presence/Cargo.toml +++ b/crates/core/presence/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-presence" -version = "0.8.4" +version = "0.8.5" edition = "2021" license = "AGPL-3.0-or-later" authors = ["Paul Makles "] diff --git a/crates/core/result/Cargo.toml b/crates/core/result/Cargo.toml index 28ad81c8..6add1173 100644 --- a/crates/core/result/Cargo.toml +++ b/crates/core/result/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-result" -version = "0.8.4" +version = "0.8.5" edition = "2021" license = "MIT" authors = ["Paul Makles "] diff --git a/crates/daemons/crond/Cargo.toml b/crates/daemons/crond/Cargo.toml index d394df0d..30250745 100644 --- a/crates/daemons/crond/Cargo.toml +++ b/crates/daemons/crond/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-crond" -version = "0.8.4" +version = "0.8.5" license = "AGPL-3.0-or-later" authors = ["Paul Makles "] edition = "2021" @@ -16,7 +16,7 @@ log = "0.4" tokio = { version = "1" } # Core -revolt-database = { version = "0.8.4", path = "../../core/database" } -revolt-result = { version = "0.8.4", path = "../../core/result" } -revolt-config = { version = "0.8.4", path = "../../core/config" } -revolt-files = { version = "0.8.4", path = "../../core/files" } +revolt-database = { version = "0.8.5", path = "../../core/database" } +revolt-result = { version = "0.8.5", path = "../../core/result" } +revolt-config = { version = "0.8.5", path = "../../core/config" } +revolt-files = { version = "0.8.5", path = "../../core/files" } diff --git a/crates/daemons/pushd/Cargo.toml b/crates/daemons/pushd/Cargo.toml index 441fa87f..6ad8bc1a 100644 --- a/crates/daemons/pushd/Cargo.toml +++ b/crates/daemons/pushd/Cargo.toml @@ -1,16 +1,16 @@ [package] name = "revolt-pushd" -version = "0.8.4" +version = "0.8.5" edition = "2021" license = "AGPL-3.0-or-later" [dependencies] -revolt-config = { version = "0.8.4", path = "../../core/config" } -revolt-database = { version = "0.8.4", path = "../../core/database" } -revolt-models = { version = "0.8.4", path = "../../core/models", features = [ +revolt-config = { version = "0.8.5", path = "../../core/config" } +revolt-database = { version = "0.8.5", path = "../../core/database" } +revolt-models = { version = "0.8.5", path = "../../core/models", features = [ "validator", ] } -revolt-presence = { version = "0.8.1", path = "../../core/presence", features = [ +revolt-presence = { version = "0.8.5", path = "../../core/presence", features = [ "redis-is-patched", ] } diff --git a/crates/delta/Cargo.toml b/crates/delta/Cargo.toml index c6217c2a..46ec7c4a 100644 --- a/crates/delta/Cargo.toml +++ b/crates/delta/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-delta" -version = "0.8.4" +version = "0.8.5" license = "AGPL-3.0-or-later" authors = ["Paul Makles "] edition = "2018" diff --git a/crates/services/autumn/Cargo.toml b/crates/services/autumn/Cargo.toml index dc242413..395640aa 100644 --- a/crates/services/autumn/Cargo.toml +++ b/crates/services/autumn/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-autumn" -version = "0.8.4" +version = "0.8.5" edition = "2021" license = "AGPL-3.0-or-later" @@ -43,12 +43,12 @@ tracing = "0.1" tracing-subscriber = { version = "0.3", features = ["env-filter"] } # Core crates -revolt-files = { version = "0.8.4", path = "../../core/files" } -revolt-config = { version = "0.8.4", path = "../../core/config" } -revolt-database = { version = "0.8.4", path = "../../core/database", features = [ +revolt-files = { version = "0.8.5", path = "../../core/files" } +revolt-config = { version = "0.8.5", path = "../../core/config" } +revolt-database = { version = "0.8.5", path = "../../core/database", features = [ "axum-impl", ] } -revolt-result = { version = "0.8.4", path = "../../core/result", features = [ +revolt-result = { version = "0.8.5", path = "../../core/result", features = [ "utoipa", "axum", ] } diff --git a/crates/services/january/Cargo.toml b/crates/services/january/Cargo.toml index 01b6f402..ce368a6a 100644 --- a/crates/services/january/Cargo.toml +++ b/crates/services/january/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-january" -version = "0.8.4" +version = "0.8.5" edition = "2021" license = "AGPL-3.0-or-later" @@ -32,13 +32,13 @@ tracing = "0.1" tracing-subscriber = { version = "0.3", features = ["env-filter"] } # Core crates -revolt-config = { version = "0.8.4", path = "../../core/config" } -revolt-models = { version = "0.8.4", path = "../../core/models" } -revolt-result = { version = "0.8.4", path = "../../core/result", features = [ +revolt-config = { version = "0.8.5", path = "../../core/config" } +revolt-models = { version = "0.8.5", path = "../../core/models" } +revolt-result = { version = "0.8.5", path = "../../core/result", features = [ "utoipa", "axum", ] } -revolt-files = { version = "0.8.4", path = "../../core/files" } +revolt-files = { version = "0.8.5", path = "../../core/files" } # Axum / web server axum = { version = "0.7.5" } From 01e0f9e5587eb193993917111d3a5e210a9f5fdd Mon Sep 17 00:00:00 2001 From: izzy Date: Mon, 12 May 2025 12:15:23 +0100 Subject: [PATCH 17/26] fix: add Authifier migration for last_seen --- .../models/admin_migrations/ops/mongodb/scripts.rs | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/crates/core/database/src/models/admin_migrations/ops/mongodb/scripts.rs b/crates/core/database/src/models/admin_migrations/ops/mongodb/scripts.rs index 16618ea9..a00cfab7 100644 --- a/crates/core/database/src/models/admin_migrations/ops/mongodb/scripts.rs +++ b/crates/core/database/src/models/admin_migrations/ops/mongodb/scripts.rs @@ -21,7 +21,7 @@ struct MigrationInfo { revision: i32, } -pub const LATEST_REVISION: i32 = 31; +pub const LATEST_REVISION: i32 = 32; pub async fn migrate_database(db: &MongoDb) { let migrations = db.col::("migrations"); @@ -1128,6 +1128,17 @@ pub async fn run_migrations(db: &MongoDb, revision: i32) -> i32 { } } + if revision <= 32 { + info!( + "Running migration [revision 32 / 12-05-2025]: (Authifier) Add last_seen to sessions." + ); + + let db = authifier::Database::MongoDb(authifier::database::MongoDb(db.db())); + db.run_migration(authifier::Migration::M2025_02_20AddLastSeenToSession) + .await + .unwrap(); + } + // Reminder to update LATEST_REVISION when adding new migrations. LATEST_REVISION.max(revision) } From 2aff76c3691408beefca068c3ece266837723905 Mon Sep 17 00:00:00 2001 From: izzy Date: Tue, 13 May 2025 10:41:03 +0100 Subject: [PATCH 18/26] refactor(pushd): add non-panic error handling to all queue consumers --- .vscode/settings.json | 4 +- Cargo.lock | 181 +++++++++++++++--- crates/core/config/Cargo.toml | 4 +- crates/core/config/src/lib.rs | 2 + crates/daemons/pushd/Cargo.toml | 7 +- .../src/consumers/inbound/fr_accepted.rs | 45 +++-- .../src/consumers/inbound/fr_received.rs | 45 +++-- .../pushd/src/consumers/inbound/generic.rs | 45 +++-- .../src/consumers/inbound/mass_mention.rs | 75 +++++--- .../pushd/src/consumers/inbound/message.rs | 45 +++-- .../pushd/src/consumers/outbound/apn.rs | 45 +++-- .../pushd/src/consumers/outbound/fcm.rs | 49 +++-- .../pushd/src/consumers/outbound/vapid.rs | 94 +++++---- crates/daemons/pushd/src/main.rs | 3 + 14 files changed, 460 insertions(+), 184 deletions(-) diff --git a/.vscode/settings.json b/.vscode/settings.json index 7f8ecfcd..707af02f 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,6 +1,6 @@ { "editor.formatOnSave": true, - "rust-analyzer.checkOnSave.command": "clippy", + "rust-analyzer.check.command": "clippy", "nixEnvSelector.suggestion": false, "nixEnvSelector.nixFile": "${workspaceFolder}/default.nix" -} \ No newline at end of file +} diff --git a/Cargo.lock b/Cargo.lock index 6d6ef809..ae209196 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -58,7 +58,7 @@ version = "0.7.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "891477e0c6a8957309ee5c45a6368af3ae14bb510732d2684ffa19af310920f9" dependencies = [ - "getrandom", + "getrandom 0.2.15", "once_cell", "version_check", ] @@ -70,7 +70,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" dependencies = [ "cfg-if", - "getrandom", + "getrandom 0.2.15", "once_cell", "version_check", "zerocopy", @@ -139,9 +139,12 @@ dependencies = [ [[package]] name = "anyhow" -version = "1.0.95" +version = "1.0.98" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34ac096ce696dc2fcabef30516bb13c0a68a11d30131d3df6f04711467681b04" +checksum = "e16d2d3311acee920a9eb8d33b8cbc1787ce4a264e85f964c2404b969bdcd487" +dependencies = [ + "backtrace", +] [[package]] name = "arbitrary" @@ -2056,7 +2059,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e9b3460f44bea8cd47f45a0c70892f1eff856d97cd55358b2f73f663789f6190" dependencies = [ "ct-codecs", - "getrandom", + "getrandom 0.2.15", ] [[package]] @@ -2675,10 +2678,22 @@ dependencies = [ "cfg-if", "js-sys", "libc", - "wasi", + "wasi 0.11.0+wasi-snapshot-preview1", "wasm-bindgen", ] +[[package]] +name = "getrandom" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26145e563e54f2cadc477553f1ec5ee650b00862f0a58bcd12cbdc5f0ea2d2f4" +dependencies = [ + "cfg-if", + "libc", + "r-efi", + "wasi 0.14.2+wasi-0.2.4", +] + [[package]] name = "getset" version = "0.1.3" @@ -4313,7 +4328,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2886843bf800fba2e3377cff24abf6379b4c4d5c6681eaf9ea5b0d15090450bd" dependencies = [ "libc", - "wasi", + "wasi 0.11.0+wasi-snapshot-preview1", "windows-sys 0.52.0", ] @@ -4933,7 +4948,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b7cafe60d6cf8e62e1b9b2ea516a089c008945bb5a275416789e7db0bc199dc" dependencies = [ "memchr", - "thiserror 2.0.9", + "thiserror 2.0.12", "ucd-trie", ] @@ -5386,7 +5401,7 @@ dependencies = [ "libc", "once_cell", "raw-cpuid", - "wasi", + "wasi 0.11.0+wasi-snapshot-preview1", "web-sys", "winapi", ] @@ -5430,6 +5445,12 @@ version = "0.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5a3866219251662ec3b26fc217e3e05bf9c4f84325234dfb96bf0bf840889e49" +[[package]] +name = "r-efi" +version = "5.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74765f6d916ee2faa39bc8e68e4f3ed8949b48cccdac59983d287a7cb71ce9c5" + [[package]] name = "radium" version = "0.7.0" @@ -5466,6 +5487,16 @@ dependencies = [ "rand_core 0.6.4", ] +[[package]] +name = "rand" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fbfd9d094a40bf3ae768db9361049ace4c0e04a4fd6b359518bd7b73a73dd97" +dependencies = [ + "rand_chacha 0.9.0", + "rand_core 0.9.3", +] + [[package]] name = "rand_chacha" version = "0.1.1" @@ -5486,6 +5517,16 @@ dependencies = [ "rand_core 0.6.4", ] +[[package]] +name = "rand_chacha" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb" +dependencies = [ + "ppv-lite86", + "rand_core 0.9.3", +] + [[package]] name = "rand_core" version = "0.3.1" @@ -5507,7 +5548,16 @@ version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" dependencies = [ - "getrandom", + "getrandom 0.2.15", +] + +[[package]] +name = "rand_core" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38" +dependencies = [ + "getrandom 0.3.3", ] [[package]] @@ -5982,6 +6032,7 @@ dependencies = [ "pretty_env_logger", "revolt-result", "sentry", + "sentry-anyhow", "serde", ] @@ -6202,6 +6253,7 @@ name = "revolt-pushd" version = "0.8.5" dependencies = [ "amqprs", + "anyhow", "async-trait", "authifier", "base64 0.22.1", @@ -6214,6 +6266,7 @@ dependencies = [ "revolt-database", "revolt-models", "revolt-presence", + "revolt-result", "revolt_a2", "revolt_optional_struct", "serde", @@ -6356,7 +6409,7 @@ checksum = "c17fa4cb658e3583423e915b9f3acc01cceaee1860e33d59ebae66adc3a2dc0d" dependencies = [ "cc", "cfg-if", - "getrandom", + "getrandom 0.2.15", "libc", "spin", "untrusted", @@ -6918,9 +6971,9 @@ dependencies = [ "httpdate", "native-tls", "reqwest 0.11.27", - "sentry-backtrace", + "sentry-backtrace 0.31.8", "sentry-contexts", - "sentry-core", + "sentry-core 0.31.8", "sentry-debug-images", "sentry-panic", "sentry-tracing", @@ -6928,6 +6981,17 @@ dependencies = [ "ureq", ] +[[package]] +name = "sentry-anyhow" +version = "0.38.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c93cfb800654dc846ccbeb35254a2f6f194aaf7e187223fd90aeb7afafe722c" +dependencies = [ + "anyhow", + "sentry-backtrace 0.38.1", + "sentry-core 0.38.1", +] + [[package]] name = "sentry-backtrace" version = "0.31.8" @@ -6937,7 +7001,18 @@ dependencies = [ "backtrace", "once_cell", "regex", - "sentry-core", + "sentry-core 0.31.8", +] + +[[package]] +name = "sentry-backtrace" +version = "0.38.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8dace796060e4ad10e3d1405b122ae184a8b2e71dce05ae450e4f81b7686b0d9" +dependencies = [ + "backtrace", + "regex", + "sentry-core 0.38.1", ] [[package]] @@ -6950,7 +7025,7 @@ dependencies = [ "libc", "os_info", "rustc_version", - "sentry-core", + "sentry-core 0.31.8", "uname", ] @@ -6962,7 +7037,18 @@ checksum = "901f761681f97db3db836ef9e094acdd8756c40215326c194201941947164ef1" dependencies = [ "once_cell", "rand 0.8.5", - "sentry-types", + "sentry-types 0.31.8", + "serde", + "serde_json", +] + +[[package]] +name = "sentry-core" +version = "0.38.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7426d4beec270cfdbb50f85f0bb2ce176ea57eed0b11741182a163055a558187" +dependencies = [ + "sentry-types 0.38.1", "serde", "serde_json", ] @@ -6975,7 +7061,7 @@ checksum = "afdb263e73d22f39946f6022ed455b7561b22ff5553aca9be3c6a047fa39c328" dependencies = [ "findshlibs", "once_cell", - "sentry-core", + "sentry-core 0.31.8", ] [[package]] @@ -6984,8 +7070,8 @@ version = "0.31.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "74fbf1c163f8b6a9d05912e1b272afa27c652e8b47ea60cb9a57ad5e481eea99" dependencies = [ - "sentry-backtrace", - "sentry-core", + "sentry-backtrace 0.31.8", + "sentry-core 0.31.8", ] [[package]] @@ -6994,8 +7080,8 @@ version = "0.31.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "82eabcab0a047040befd44599a1da73d3adb228ff53b5ed9795ae04535577704" dependencies = [ - "sentry-backtrace", - "sentry-core", + "sentry-backtrace 0.31.8", + "sentry-core 0.31.8", "tracing-core", "tracing-subscriber", ] @@ -7017,6 +7103,23 @@ dependencies = [ "uuid", ] +[[package]] +name = "sentry-types" +version = "0.38.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04b6c9287202294685cb1f749b944dbbce8160b81a1061ecddc073025fed129f" +dependencies = [ + "debugid", + "hex", + "rand 0.9.1", + "serde", + "serde_json", + "thiserror 2.0.12", + "time", + "url", + "uuid", +] + [[package]] name = "serde" version = "1.0.217" @@ -7647,7 +7750,7 @@ checksum = "9a8a559c81686f576e8cd0290cd2a24a2a9ad80c98b3478856500fcbd7acd704" dependencies = [ "cfg-if", "fastrand 2.3.0", - "getrandom", + "getrandom 0.2.15", "once_cell", "rustix", "windows-sys 0.59.0", @@ -7684,11 +7787,11 @@ dependencies = [ [[package]] name = "thiserror" -version = "2.0.9" +version = "2.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f072643fd0190df67a8bab670c20ef5d8737177d6ac6b2e9a236cb096206b2cc" +checksum = "567b8a2dae586314f7be2a752ec7474332959c6460e02bde30d702a66d488708" dependencies = [ - "thiserror-impl 2.0.9", + "thiserror-impl 2.0.12", ] [[package]] @@ -7704,9 +7807,9 @@ dependencies = [ [[package]] name = "thiserror-impl" -version = "2.0.9" +version = "2.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b50fa271071aae2e6ee85f842e2e28ba8cd2c5fb67f11fcb1fd70b276f9e7d4" +checksum = "7f7cf42b4507d8ea322120659672cf1b9dbb93f8f2d4ecfd6e51350ff5b17a1d" dependencies = [ "proc-macro2", "quote 1.0.38", @@ -8199,7 +8302,7 @@ version = "1.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "04f903f293d11f31c0c29e4148f6dc0d033a7f80cebc0282bea147611667d289" dependencies = [ - "getrandom", + "getrandom 0.2.15", "rand 0.8.5", "web-time", ] @@ -8459,7 +8562,7 @@ version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f8c5f0a0af699448548ad1a2fbf920fb4bee257eae39953ba95cb84891a0446a" dependencies = [ - "getrandom", + "getrandom 0.2.15", "serde", ] @@ -8606,13 +8709,22 @@ version = "0.11.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" +[[package]] +name = "wasi" +version = "0.14.2+wasi-0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9683f9a5a998d873c0d21fcbe3c083009670149a8fab228644b8bd36b2c48cb3" +dependencies = [ + "wit-bindgen-rt", +] + [[package]] name = "wasix" version = "0.12.21" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c1fbb4ef9bbca0c1170e0b00dd28abc9e3b68669821600cad1caaed606583c6d" dependencies = [ - "wasi", + "wasi 0.11.0+wasi-snapshot-preview1", ] [[package]] @@ -9061,6 +9173,15 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "wit-bindgen-rt" +version = "0.39.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f42320e61fe2cfd34354ecb597f86f413484a798ba44a8ca1165c58d42da6c1" +dependencies = [ + "bitflags 2.6.0", +] + [[package]] name = "write16" version = "1.0.0" diff --git a/crates/core/config/Cargo.toml b/crates/core/config/Cargo.toml index 2411d099..a2beff9a 100644 --- a/crates/core/config/Cargo.toml +++ b/crates/core/config/Cargo.toml @@ -9,9 +9,10 @@ description = "Revolt Backend: Configuration" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [features] +anyhow = ["dep:sentry-anyhow"] report-macros = ["revolt-result"] test = ["async-std"] -default = ["test"] +default = ["test", "anyhow"] [dependencies] # Utility @@ -32,6 +33,7 @@ pretty_env_logger = "0.4.0" # Sentry sentry = "0.31.5" +sentry-anyhow = { version = "0.38.1", optional = true } # Core revolt-result = { version = "0.8.5", path = "../result", optional = true } diff --git a/crates/core/config/src/lib.rs b/crates/core/config/src/lib.rs index 8f67c76a..b4b3bed2 100644 --- a/crates/core/config/src/lib.rs +++ b/crates/core/config/src/lib.rs @@ -7,6 +7,7 @@ use once_cell::sync::Lazy; use serde::Deserialize; pub use sentry::{capture_error, capture_message, Level}; +pub use sentry_anyhow::capture_anyhow; #[cfg(feature = "report-macros")] #[macro_export] @@ -343,6 +344,7 @@ pub struct Sentry { pub events: String, pub files: String, pub proxy: String, + pub pushd: String, pub crond: String, } diff --git a/crates/daemons/pushd/Cargo.toml b/crates/daemons/pushd/Cargo.toml index 6ad8bc1a..699654de 100644 --- a/crates/daemons/pushd/Cargo.toml +++ b/crates/daemons/pushd/Cargo.toml @@ -5,7 +5,10 @@ edition = "2021" license = "AGPL-3.0-or-later" [dependencies] -revolt-config = { version = "0.8.5", path = "../../core/config" } +revolt-result = { version = "0.8.5", path = "../../core/result" } +revolt-config = { version = "0.8.5", path = "../../core/config", features = [ + "report-macros", +] } revolt-database = { version = "0.8.5", path = "../../core/database" } revolt-models = { version = "0.8.5", path = "../../core/models", features = [ "validator", @@ -14,6 +17,8 @@ revolt-presence = { version = "0.8.5", path = "../../core/presence", features = "redis-is-patched", ] } +anyhow = { version = "1.0.98" } + amqprs = { version = "1.7.0" } fcm_v1 = "0.3.0" web-push = "0.10.0" diff --git a/crates/daemons/pushd/src/consumers/inbound/fr_accepted.rs b/crates/daemons/pushd/src/consumers/inbound/fr_accepted.rs index ff084a83..d525138c 100644 --- a/crates/daemons/pushd/src/consumers/inbound/fr_accepted.rs +++ b/crates/daemons/pushd/src/consumers/inbound/fr_accepted.rs @@ -7,6 +7,7 @@ use amqprs::{ consumer::AsyncConsumer, BasicProperties, Deliver, }; +use anyhow::Result; use async_trait::async_trait; use log::debug; use revolt_database::{events::rabbit::*, Database}; @@ -54,21 +55,16 @@ impl FRAcceptedConsumer { channel: None, } } -} -#[allow(unused_variables)] -#[async_trait] -impl AsyncConsumer for FRAcceptedConsumer { - /// This consumer handles delegating messages into their respective platform queues. - async fn consume( + async fn consume_event( &mut self, - channel: &Channel, - deliver: Deliver, - basic_properties: BasicProperties, + _channel: &Channel, + _deliver: Deliver, + _basic_properties: BasicProperties, content: Vec, - ) { - let content = String::from_utf8(content).unwrap(); - let payload: FRAcceptedPayload = serde_json::from_str(content.as_str()).unwrap(); + ) -> Result<()> { + let content = String::from_utf8(content)?; + let payload: FRAcceptedPayload = serde_json::from_str(content.as_str())?; debug!("Received FR accept event"); @@ -111,11 +107,34 @@ impl AsyncConsumer for FRAcceptedConsumer { .insert("endpoint".to_string(), sub.endpoint.clone()); } - let payload = serde_json::to_string(&sendable).unwrap(); + let payload = serde_json::to_string(&sendable)?; publish_message(self, payload.into(), args).await; } } } + + Ok(()) + } +} + +#[allow(unused_variables)] +#[async_trait] +impl AsyncConsumer for FRAcceptedConsumer { + /// This consumer handles delegating messages into their respective platform queues. + async fn consume( + &mut self, + channel: &Channel, + deliver: Deliver, + basic_properties: BasicProperties, + content: Vec, + ) { + if let Err(err) = self + .consume_event(channel, deliver, basic_properties, content) + .await + { + revolt_config::capture_anyhow(&err); + eprintln!("Failed to process friend request accepted event: {err:?}"); + } } } diff --git a/crates/daemons/pushd/src/consumers/inbound/fr_received.rs b/crates/daemons/pushd/src/consumers/inbound/fr_received.rs index c52dfec1..f64bc92b 100644 --- a/crates/daemons/pushd/src/consumers/inbound/fr_received.rs +++ b/crates/daemons/pushd/src/consumers/inbound/fr_received.rs @@ -7,6 +7,7 @@ use amqprs::{ consumer::AsyncConsumer, BasicProperties, Deliver, }; +use anyhow::Result; use async_trait::async_trait; use log::debug; use revolt_database::{events::rabbit::*, Database}; @@ -54,21 +55,16 @@ impl FRReceivedConsumer { channel: None, } } -} -#[allow(unused_variables)] -#[async_trait] -impl AsyncConsumer for FRReceivedConsumer { - /// This consumer handles delegating messages into their respective platform queues. - async fn consume( + async fn consume_event( &mut self, - channel: &Channel, - deliver: Deliver, - basic_properties: BasicProperties, + _channel: &Channel, + _deliver: Deliver, + _basic_properties: BasicProperties, content: Vec, - ) { - let content = String::from_utf8(content).unwrap(); - let payload: FRReceivedPayload = serde_json::from_str(content.as_str()).unwrap(); + ) -> Result<()> { + let content = String::from_utf8(content)?; + let payload: FRReceivedPayload = serde_json::from_str(content.as_str())?; debug!("Received FR received event"); @@ -111,11 +107,34 @@ impl AsyncConsumer for FRReceivedConsumer { .insert("endpoint".to_string(), sub.endpoint.clone()); } - let payload = serde_json::to_string(&sendable).unwrap(); + let payload = serde_json::to_string(&sendable)?; publish_message(self, payload.into(), args).await; } } } + + Ok(()) + } +} + +#[allow(unused_variables)] +#[async_trait] +impl AsyncConsumer for FRReceivedConsumer { + /// This consumer handles delegating messages into their respective platform queues. + async fn consume( + &mut self, + channel: &Channel, + deliver: Deliver, + basic_properties: BasicProperties, + content: Vec, + ) { + if let Err(err) = self + .consume_event(channel, deliver, basic_properties, content) + .await + { + revolt_config::capture_anyhow(&err); + eprintln!("Failed to process friend request received event: {err:?}"); + } } } diff --git a/crates/daemons/pushd/src/consumers/inbound/generic.rs b/crates/daemons/pushd/src/consumers/inbound/generic.rs index 58070f66..aa3950d7 100644 --- a/crates/daemons/pushd/src/consumers/inbound/generic.rs +++ b/crates/daemons/pushd/src/consumers/inbound/generic.rs @@ -7,6 +7,7 @@ use amqprs::{ consumer::AsyncConsumer, BasicProperties, Deliver, }; +use anyhow::Result; use async_trait::async_trait; use log::debug; use revolt_database::{events::rabbit::*, Database}; @@ -54,21 +55,16 @@ impl GenericConsumer { channel: None, } } -} -#[allow(unused_variables)] -#[async_trait] -impl AsyncConsumer for GenericConsumer { - /// This consumer handles delegating messages into their respective platform queues. - async fn consume( + async fn consume_event( &mut self, - channel: &Channel, - deliver: Deliver, - basic_properties: BasicProperties, + _channel: &Channel, + _deliver: Deliver, + _basic_properties: BasicProperties, content: Vec, - ) { - let content = String::from_utf8(content).unwrap(); - let payload: MessageSentPayload = serde_json::from_str(content.as_str()).unwrap(); + ) -> Result<()> { + let content = String::from_utf8(content)?; + let payload: MessageSentPayload = serde_json::from_str(content.as_str())?; debug!("Received message event on origin"); @@ -117,11 +113,34 @@ impl AsyncConsumer for GenericConsumer { .insert("endpoint".to_string(), sub.endpoint.clone()); } - let payload = serde_json::to_string(&sendable).unwrap(); + let payload = serde_json::to_string(&sendable)?; publish_message(self, payload.into(), args).await; } } } + + Ok(()) + } +} + +#[allow(unused_variables)] +#[async_trait] +impl AsyncConsumer for GenericConsumer { + /// This consumer handles delegating messages into their respective platform queues. + async fn consume( + &mut self, + channel: &Channel, + deliver: Deliver, + basic_properties: BasicProperties, + content: Vec, + ) { + if let Err(err) = self + .consume_event(channel, deliver, basic_properties, content) + .await + { + revolt_config::capture_anyhow(&err); + eprintln!("Failed to process generic event: {err:?}"); + } } } diff --git a/crates/daemons/pushd/src/consumers/inbound/mass_mention.rs b/crates/daemons/pushd/src/consumers/inbound/mass_mention.rs index a44dcb1e..bf5dd453 100644 --- a/crates/daemons/pushd/src/consumers/inbound/mass_mention.rs +++ b/crates/daemons/pushd/src/consumers/inbound/mass_mention.rs @@ -10,6 +10,7 @@ use amqprs::{ consumer::AsyncConsumer, BasicProperties, Deliver, }; +use anyhow::Result; use async_trait::async_trait; use revolt_database::{ events::rabbit::*, util::bulk_permissions::BulkDatabasePermissionQuery, Database, Member, @@ -61,7 +62,11 @@ impl MassMessageConsumer { } } - async fn fire_notification_for_users(&mut self, push: &PushNotification, users: &[String]) { + async fn fire_notification_for_users( + &mut self, + push: &PushNotification, + users: &[String], + ) -> Result<()> { if let Ok(sessions) = self .authifier_db .find_sessions_with_subscription(users) @@ -105,29 +110,26 @@ impl MassMessageConsumer { .insert("endpoint".to_string(), sub.endpoint.clone()); } - let payload = serde_json::to_string(&sendable).unwrap(); + let payload = serde_json::to_string(&sendable)?; publish_message(self, payload.into(), args).await; } } } - } -} -#[allow(unused_variables)] -#[async_trait] -impl AsyncConsumer for MassMessageConsumer { - /// This consumer handles adding mentions for all the users affected by a mass mention ping, and then sends out push notifications - async fn consume( + Ok(()) + } + + async fn consume_event( &mut self, - channel: &Channel, - deliver: Deliver, - basic_properties: BasicProperties, + _channel: &Channel, + _deliver: Deliver, + _basic_properties: BasicProperties, content: Vec, - ) { + ) -> Result<()> { let config = revolt_config::config().await; - let content = String::from_utf8(content).unwrap(); - let payload: MassMessageSentPayload = serde_json::from_str(content.as_str()).unwrap(); + let content = String::from_utf8(content)?; + let payload: MassMessageSentPayload = serde_json::from_str(content.as_str())?; debug!("Received mass message event"); @@ -159,8 +161,7 @@ impl AsyncConsumer for MassMessageConsumer { let mut db_query = self .db .fetch_all_members_chunked(&payload.server_id) - .await - .expect("Failed to fetch members from database"); + .await?; let mut exhausted = false; let ack_chnl = vec![push.channel.id().to_string()]; @@ -203,7 +204,8 @@ impl AsyncConsumer for MassMessageConsumer { target_users, online_users ); - self.fire_notification_for_users(&push, &target_users).await; + self.fire_notification_for_users(&push, &target_users) + .await?; if exhausted { break; @@ -211,19 +213,11 @@ impl AsyncConsumer for MassMessageConsumer { } } else if let Some(roles) = &push.message.role_mentions { // role mentions - let _role_members = self + let mut role_members = self .db .fetch_all_members_with_roles_chunked(&payload.server_id, roles) - .await; + .await?; - debug!("role members: {:?}", _role_members); - - if _role_members.is_err() { - revolt_config::capture_error(&_role_members.err().unwrap()); - return; - } - - let mut role_members = _role_members.unwrap(); let mut chunk = vec![]; let mut exhausted = false; @@ -266,10 +260,33 @@ impl AsyncConsumer for MassMessageConsumer { debug!("targets: {:?}", targets); - self.fire_notification_for_users(&push, &targets).await; + self.fire_notification_for_users(&push, &targets).await?; } } } } + + Ok(()) + } +} + +#[allow(unused_variables)] +#[async_trait] +impl AsyncConsumer for MassMessageConsumer { + /// This consumer handles adding mentions for all the users affected by a mass mention ping, and then sends out push notifications + async fn consume( + &mut self, + channel: &Channel, + deliver: Deliver, + basic_properties: BasicProperties, + content: Vec, + ) { + if let Err(err) = self + .consume_event(channel, deliver, basic_properties, content) + .await + { + revolt_config::capture_anyhow(&err); + eprintln!("Failed to process mass message event: {err:?}"); + } } } diff --git a/crates/daemons/pushd/src/consumers/inbound/message.rs b/crates/daemons/pushd/src/consumers/inbound/message.rs index 99e61cbd..6b9d00fe 100644 --- a/crates/daemons/pushd/src/consumers/inbound/message.rs +++ b/crates/daemons/pushd/src/consumers/inbound/message.rs @@ -7,6 +7,7 @@ use amqprs::{ consumer::AsyncConsumer, BasicProperties, Deliver, }; +use anyhow::Result; use async_trait::async_trait; use log::debug; use revolt_database::{events::rabbit::*, Database}; @@ -54,21 +55,16 @@ impl MessageConsumer { channel: None, } } -} -#[allow(unused_variables)] -#[async_trait] -impl AsyncConsumer for MessageConsumer { - /// This consumer handles delegating messages into their respective platform queues. - async fn consume( + async fn consume_event( &mut self, - channel: &Channel, - deliver: Deliver, - basic_properties: BasicProperties, + _channel: &Channel, + _deliver: Deliver, + _basic_properties: BasicProperties, content: Vec, - ) { - let content = String::from_utf8(content).unwrap(); - let payload: MessageSentPayload = serde_json::from_str(content.as_str()).unwrap(); + ) -> Result<()> { + let content = String::from_utf8(content)?; + let payload: MessageSentPayload = serde_json::from_str(content.as_str())?; debug!("Received message event on origin"); @@ -117,11 +113,34 @@ impl AsyncConsumer for MessageConsumer { .insert("endpoint".to_string(), sub.endpoint.clone()); } - let payload = serde_json::to_string(&sendable).unwrap(); + let payload = serde_json::to_string(&sendable)?; publish_message(self, payload.into(), args).await; } } } + + Ok(()) + } +} + +#[allow(unused_variables)] +#[async_trait] +impl AsyncConsumer for MessageConsumer { + /// This consumer handles delegating messages into their respective platform queues. + async fn consume( + &mut self, + channel: &Channel, + deliver: Deliver, + basic_properties: BasicProperties, + content: Vec, + ) { + if let Err(err) = self + .consume_event(channel, deliver, basic_properties, content) + .await + { + revolt_config::capture_anyhow(&err); + eprintln!("Failed to process message event: {err:?}"); + } } } diff --git a/crates/daemons/pushd/src/consumers/outbound/apn.rs b/crates/daemons/pushd/src/consumers/outbound/apn.rs index f9a09cc8..7cc43c76 100644 --- a/crates/daemons/pushd/src/consumers/outbound/apn.rs +++ b/crates/daemons/pushd/src/consumers/outbound/apn.rs @@ -1,6 +1,7 @@ use std::{borrow::Cow, collections::BTreeMap, io::Cursor}; use amqprs::{channel::Channel as AmqpChannel, consumer::AsyncConsumer, BasicProperties, Deliver}; +use anyhow::{anyhow, Result}; use async_trait::async_trait; use base64::{ engine::{self}, @@ -122,20 +123,16 @@ impl ApnsOutboundConsumer { Ok(ApnsOutboundConsumer { db, client }) } -} -#[allow(unused_variables)] -#[async_trait] -impl AsyncConsumer for ApnsOutboundConsumer { - async fn consume( + async fn consume_event( &mut self, - channel: &AmqpChannel, - deliver: Deliver, - basic_properties: BasicProperties, + _channel: &AmqpChannel, + _deliver: Deliver, + _basic_properties: BasicProperties, content: Vec, - ) { - let content = String::from_utf8(content).unwrap(); - let payload: PayloadToService = serde_json::from_str(content.as_str()).unwrap(); + ) -> Result<()> { + let content = String::from_utf8(content)?; + let payload: PayloadToService = serde_json::from_str(content.as_str())?; let payload_options = NotificationOptions { apns_id: None, @@ -159,7 +156,7 @@ impl AsyncConsumer for ApnsOutboundConsumer { alert.from_user.username, alert.from_user.discriminator ))) .clone() - .unwrap(), + .ok_or_else(|| anyhow!("missing name"))?, )]; let apn_payload = Payload { @@ -205,7 +202,7 @@ impl AsyncConsumer for ApnsOutboundConsumer { alert.accepted_user.username, alert.accepted_user.discriminator ))) .clone() - .unwrap(), + .ok_or_else(|| anyhow!("missing name"))?, )]; let apn_payload = Payload { @@ -355,5 +352,27 @@ impl AsyncConsumer for ApnsOutboundConsumer { } } } + + Ok(()) + } +} + +#[allow(unused_variables)] +#[async_trait] +impl AsyncConsumer for ApnsOutboundConsumer { + async fn consume( + &mut self, + channel: &AmqpChannel, + deliver: Deliver, + basic_properties: BasicProperties, + content: Vec, + ) { + if let Err(err) = self + .consume_event(channel, deliver, basic_properties, content) + .await + { + revolt_config::capture_anyhow(&err); + eprintln!("Failed to process APN event: {err:?}"); + } } } diff --git a/crates/daemons/pushd/src/consumers/outbound/fcm.rs b/crates/daemons/pushd/src/consumers/outbound/fcm.rs index 61700bbb..1e3f1d2a 100644 --- a/crates/daemons/pushd/src/consumers/outbound/fcm.rs +++ b/crates/daemons/pushd/src/consumers/outbound/fcm.rs @@ -2,6 +2,7 @@ use std::{collections::HashMap, time::Duration}; use amqprs::{channel::Channel as AmqpChannel, consumer::AsyncConsumer, BasicProperties, Deliver}; +use anyhow::{anyhow, bail, Result}; use async_trait::async_trait; use fcm_v1::{ android::AndroidConfig, @@ -64,22 +65,16 @@ impl FcmOutboundConsumer { ), }) } -} -#[allow(unused_variables)] -#[async_trait] -impl AsyncConsumer for FcmOutboundConsumer { - async fn consume( + async fn consume_event( &mut self, - channel: &AmqpChannel, - deliver: Deliver, - basic_properties: BasicProperties, + _channel: &AmqpChannel, + _deliver: Deliver, + _basic_properties: BasicProperties, content: Vec, - ) { - let content = String::from_utf8(content).unwrap(); - let payload: PayloadToService = serde_json::from_str(content.as_str()).unwrap(); - - let config = revolt_config::config().await; + ) -> Result<()> { + let content = String::from_utf8(content)?; + let payload: PayloadToService = serde_json::from_str(content.as_str())?; #[allow(clippy::needless_late_init)] let resp: Result; @@ -94,7 +89,7 @@ impl AsyncConsumer for FcmOutboundConsumer { alert.from_user.username, alert.from_user.discriminator ))) .clone() - .unwrap(); + .ok_or_else(|| anyhow!("missing name"))?; let mut data = HashMap::new(); data.insert( @@ -122,7 +117,7 @@ impl AsyncConsumer for FcmOutboundConsumer { alert.accepted_user.username, alert.accepted_user.discriminator ))) .clone() - .unwrap(); + .ok_or_else(|| anyhow!("missing name"))?; let mut data: HashMap = HashMap::new(); data.insert( @@ -175,7 +170,7 @@ impl AsyncConsumer for FcmOutboundConsumer { } PayloadKind::BadgeUpdate(_) => { - panic!("FCM cannot handle badge updates, and they should not be sent here.") + bail!("FCM cannot handle badge updates and they should not be sent here."); } } @@ -195,5 +190,27 @@ impl AsyncConsumer for FcmOutboundConsumer { } } } + + Ok(()) + } +} + +#[allow(unused_variables)] +#[async_trait] +impl AsyncConsumer for FcmOutboundConsumer { + async fn consume( + &mut self, + channel: &AmqpChannel, + deliver: Deliver, + basic_properties: BasicProperties, + content: Vec, + ) { + if let Err(err) = self + .consume_event(channel, deliver, basic_properties, content) + .await + { + revolt_config::capture_anyhow(&err); + eprintln!("Failed to process FCM event: {err:?}"); + } } } diff --git a/crates/daemons/pushd/src/consumers/outbound/vapid.rs b/crates/daemons/pushd/src/consumers/outbound/vapid.rs index fb735d5e..92ce6e56 100644 --- a/crates/daemons/pushd/src/consumers/outbound/vapid.rs +++ b/crates/daemons/pushd/src/consumers/outbound/vapid.rs @@ -2,13 +2,13 @@ use std::collections::HashMap; use amqprs::{channel::Channel as AmqpChannel, consumer::AsyncConsumer, BasicProperties, Deliver}; +use anyhow::{anyhow, bail, Result}; use async_trait::async_trait; use base64::{ engine::{self}, Engine as _, }; use revolt_database::{events::rabbit::*, Database}; -// use revolt_models::v0::{Channel, PushNotification}; use web_push::{ ContentEncoding, IsahcWebPushClient, SubscriptionInfo, SubscriptionKeys, VapidSignatureBuilder, WebPushClient, WebPushError, WebPushMessageBuilder, @@ -21,11 +21,11 @@ pub struct VapidOutboundConsumer { } impl VapidOutboundConsumer { - pub async fn new(db: Database) -> Result { + pub async fn new(db: Database) -> Result { let config = revolt_config::config().await; if config.pushd.vapid.private_key.is_empty() | config.pushd.vapid.public_key.is_empty() { - return Err("No Vapid keys present"); + bail!("no Vapid keys present"); } let web_push_private_key = engine::general_purpose::URL_SAFE_NO_PAD @@ -38,28 +38,30 @@ impl VapidOutboundConsumer { pkey: web_push_private_key, }) } -} -#[allow(unused_variables)] -#[async_trait] -impl AsyncConsumer for VapidOutboundConsumer { - async fn consume( + async fn consume_event( &mut self, - channel: &AmqpChannel, - deliver: Deliver, - basic_properties: BasicProperties, + _channel: &AmqpChannel, + _deliver: Deliver, + _basic_properties: BasicProperties, content: Vec, - ) { - let content = String::from_utf8(content).unwrap(); - let payload: PayloadToService = serde_json::from_str(content.as_str()).unwrap(); - - let config = revolt_config::config().await; + ) -> Result<()> { + let content = String::from_utf8(content)?; + let payload: PayloadToService = serde_json::from_str(content.as_str())?; let subscription = SubscriptionInfo { - endpoint: payload.extras.get("endpoint").unwrap().clone(), + endpoint: payload + .extras + .get("endpoint") + .ok_or_else(|| anyhow!("missing endpoint"))? + .clone(), keys: SubscriptionKeys { auth: payload.token, - p256dh: payload.extras.get("p256dh").unwrap().clone(), + p256dh: payload + .extras + .get("p256dh") + .ok_or_else(|| anyhow!("missing p256dh"))? + .clone(), }, }; @@ -76,12 +78,12 @@ impl AsyncConsumer for VapidOutboundConsumer { alert.from_user.username, alert.from_user.discriminator ))) .clone() - .unwrap(); + .ok_or_else(|| anyhow!("missing name"))?; let mut body = HashMap::new(); body.insert("body", format!("{} sent you a friend request", name)); - payload_body = serde_json::to_string(&body).unwrap(); + payload_body = serde_json::to_string(&body)?; } PayloadKind::FRAccepted(alert) => { let name = alert @@ -92,21 +94,21 @@ impl AsyncConsumer for VapidOutboundConsumer { alert.accepted_user.username, alert.accepted_user.discriminator ))) .clone() - .unwrap(); + .ok_or_else(|| anyhow!("missing name"))?; let mut body = HashMap::new(); body.insert("body", format!("{} accepted your friend request", name)); - payload_body = serde_json::to_string(&body).unwrap(); + payload_body = serde_json::to_string(&body)?; } PayloadKind::Generic(alert) => { - payload_body = serde_json::to_string(&alert).unwrap(); + payload_body = serde_json::to_string(&alert)?; } PayloadKind::MessageNotification(alert) => { - payload_body = serde_json::to_string(&alert).unwrap(); + payload_body = serde_json::to_string(&alert)?; } PayloadKind::BadgeUpdate(_) => { - panic!("Vapid cannot handle badge updates, and they should not be sent here.") + bail!("Vapid cannot handle badge updates and they should not be sent here."); } } @@ -122,28 +124,40 @@ impl AsyncConsumer for VapidOutboundConsumer { Ok(msg) => { if let Err(err) = self.client.send(msg).await { if err == WebPushError::Unauthorized { - if let Err(err) = self - .db + self.db .remove_push_subscription_by_session_id(&payload.session_id) - .await - { - revolt_config::capture_error(&err); - } + .await?; } } + + Ok(()) } - Err(err) => { - revolt_config::capture_error(&err); - } + Err(err) => Err(err.into()), } } - Err(err) => { - revolt_config::capture_error(&err); - } + Err(err) => Err(err.into()), }, - Err(err) => { - revolt_config::capture_error(&err); - } + Err(err) => Err(err.into()), + } + } +} + +#[allow(unused_variables)] +#[async_trait] +impl AsyncConsumer for VapidOutboundConsumer { + async fn consume( + &mut self, + channel: &AmqpChannel, + deliver: Deliver, + basic_properties: BasicProperties, + content: Vec, + ) { + if let Err(err) = self + .consume_event(channel, deliver, basic_properties, content) + .await + { + revolt_config::capture_anyhow(&err); + eprintln!("Failed to process Vapid event: {err:?}"); } } } diff --git a/crates/daemons/pushd/src/main.rs b/crates/daemons/pushd/src/main.rs index 1560b049..57be4d89 100644 --- a/crates/daemons/pushd/src/main.rs +++ b/crates/daemons/pushd/src/main.rs @@ -27,6 +27,9 @@ async fn main() { let config = config().await; pretty_env_logger::init(); + // Configure logging and environment + revolt_config::configure!(pushd); + // Setup database let db = revolt_database::DatabaseInfo::Auto.connect().await.unwrap(); let authifier: authifier::Database; From 69ae76717558591605c976a2c98241a4073ee9fc Mon Sep 17 00:00:00 2001 From: izzy Date: Tue, 13 May 2025 10:48:56 +0100 Subject: [PATCH 19/26] refactor: some clippy recommendations --- crates/bonfire/src/events/impl.rs | 13 +++++----- crates/bonfire/src/websocket.rs | 2 +- crates/core/database/src/models/bots/model.rs | 1 - .../src/models/channel_webhooks/model.rs | 2 +- .../database/src/models/channels/model.rs | 11 +++----- .../database/src/models/file_hashes/model.rs | 2 +- .../database/src/models/messages/model.rs | 23 +++++++++------- .../src/models/safety_snapshots/model.rs | 4 +-- .../database/src/models/server_bans/model.rs | 1 + .../src/models/server_members/model.rs | 2 +- .../core/database/src/models/servers/model.rs | 2 +- .../core/database/src/models/users/model.rs | 19 ++++++-------- .../core/database/src/models/users/schema.rs | 2 +- crates/core/database/src/tasks/ack.rs | 1 - crates/core/database/src/util/bridge/v0.rs | 6 ++--- .../database/src/util/bulk_permissions.rs | 6 ++--- crates/core/database/src/util/permissions.rs | 26 +++++++++---------- crates/core/models/src/v0/messages.rs | 2 +- .../src/routes/channels/members_fetch.rs | 1 - .../routes/channels/message_bulk_delete.rs | 1 - .../delta/src/routes/channels/message_edit.rs | 1 - .../src/routes/channels/permissions_set.rs | 3 +-- .../src/routes/customisation/emoji_delete.rs | 3 +-- crates/delta/src/routes/mod.rs | 2 +- crates/delta/src/routes/servers/ban_create.rs | 5 +--- .../routes/servers/permissions_set_default.rs | 2 +- crates/delta/src/routes/servers/roles_edit.rs | 1 - .../src/routes/users/fetch_user_flags.rs | 1 - .../routes/webhooks/webhook_execute_github.rs | 3 ++- 29 files changed, 67 insertions(+), 81 deletions(-) diff --git a/crates/bonfire/src/events/impl.rs b/crates/bonfire/src/events/impl.rs index 36518e0e..62da6108 100644 --- a/crates/bonfire/src/events/impl.rs +++ b/crates/bonfire/src/events/impl.rs @@ -175,7 +175,7 @@ impl State { .iter() .find(|e| matches!(e, ReadyPayloadFields::UserSettings(_))) { - Some(db.fetch_user_settings(&user.id, &keys).await?) + Some(db.fetch_user_settings(&user.id, keys).await?) } else { None }; @@ -199,12 +199,11 @@ impl State { .collect(); // Make all users appear from our perspective. - let mut users: Vec = join_all(users - .into_iter() - .map(|other_user| async { - let is_online = online_ids.contains(&other_user.id); - other_user.into_known(&user, is_online).await - })).await; + let mut users: Vec = join_all(users.into_iter().map(|other_user| async { + let is_online = online_ids.contains(&other_user.id); + other_user.into_known(&user, is_online).await + })) + .await; // Make sure we see our own user correctly. users.push(user.into_self(true).await); diff --git a/crates/bonfire/src/websocket.rs b/crates/bonfire/src/websocket.rs index 810befbf..dbebfdbd 100644 --- a/crates/bonfire/src/websocket.rs +++ b/crates/bonfire/src/websocket.rs @@ -3,7 +3,7 @@ use std::{collections::HashSet, net::SocketAddr, sync::Arc}; use async_tungstenite::WebSocketStream; use authifier::AuthifierEvent; use fred::{ - error::{RedisError, RedisErrorKind}, + error::RedisErrorKind, interfaces::{ClientLike, EventInterface, PubsubInterface}, types::RedisConfig, }; diff --git a/crates/core/database/src/models/bots/model.rs b/crates/core/database/src/models/bots/model.rs index 0a796049..24c56bb1 100644 --- a/crates/core/database/src/models/bots/model.rs +++ b/crates/core/database/src/models/bots/model.rs @@ -1,4 +1,3 @@ -use revolt_config::config; use revolt_result::Result; use ulid::Ulid; diff --git a/crates/core/database/src/models/channel_webhooks/model.rs b/crates/core/database/src/models/channel_webhooks/model.rs index b163cbfe..cdf94db4 100644 --- a/crates/core/database/src/models/channel_webhooks/model.rs +++ b/crates/core/database/src/models/channel_webhooks/model.rs @@ -142,7 +142,7 @@ mod tests { ..Default::default() }; - db.insert_webhook(&webhook).await.unwrap(); + webhook.create(&db).await.unwrap(); let mut updated_webhook = webhook.clone(); updated_webhook diff --git a/crates/core/database/src/models/channels/model.rs b/crates/core/database/src/models/channels/model.rs index 359d7a4a..536632a7 100644 --- a/crates/core/database/src/models/channels/model.rs +++ b/crates/core/database/src/models/channels/model.rs @@ -328,13 +328,10 @@ impl Channel { db.insert_channel(&channel).await?; - match &channel { - Channel::DirectMessage { .. } => { - let event = EventV1::ChannelCreate(channel.clone().into()); - event.clone().private(user_a.id.clone()).await; - event.private(user_b.id.clone()).await; - } - _ => {} + if let Channel::DirectMessage { .. } = &channel { + let event = EventV1::ChannelCreate(channel.clone().into()); + event.clone().private(user_a.id.clone()).await; + event.private(user_b.id.clone()).await; }; Ok(channel) diff --git a/crates/core/database/src/models/file_hashes/model.rs b/crates/core/database/src/models/file_hashes/model.rs index 46a249f0..cec7a39d 100644 --- a/crates/core/database/src/models/file_hashes/model.rs +++ b/crates/core/database/src/models/file_hashes/model.rs @@ -28,7 +28,7 @@ auto_derived_partial!( /// Size of this file (in bytes) pub size: isize, }, - "PartialFile" + "PartialFileHash" ); auto_derived!( diff --git a/crates/core/database/src/models/messages/model.rs b/crates/core/database/src/models/messages/model.rs index 02ad765f..2c24567a 100644 --- a/crates/core/database/src/models/messages/model.rs +++ b/crates/core/database/src/models/messages/model.rs @@ -5,7 +5,7 @@ use iso8601_timestamp::Timestamp; use revolt_config::{config, FeaturesLimits}; use revolt_models::v0::{ self, BulkMessageResponse, DataMessageSend, Embed, MessageAuthor, MessageFlags, MessageSort, - MessageWebhook, PushNotification, ReplyIntent, SendableEmbed, Text + MessageWebhook, PushNotification, ReplyIntent, SendableEmbed, Text, }; use revolt_permissions::{calculate_channel_permissions, ChannelPermission, PermissionValue}; use revolt_result::{ErrorType, Result}; @@ -286,9 +286,9 @@ impl Message { .map_err(|_| create_error!(InvalidOperation))?; // Check the message is not empty - if (data.content.as_ref().map_or(true, |v| v.is_empty())) - && (data.attachments.as_ref().map_or(true, |v| v.is_empty())) - && (data.embeds.as_ref().map_or(true, |v| v.is_empty())) + if (data.content.as_ref().is_none_or(|v| v.is_empty())) + && (data.attachments.as_ref().is_none_or(|v| v.is_empty())) + && (data.embeds.as_ref().is_none_or(|v| v.is_empty())) { return Err(create_error!(EmptyMessage)); } @@ -382,7 +382,7 @@ impl Message { mut user_mentions, mut role_mentions, mut mentions_everyone, - mut mentions_online + mut mentions_online, } = message_mentions; if allow_mass_mentions && server_id.is_some() && !role_mentions.is_empty() { @@ -489,7 +489,9 @@ impl Message { let valid_members = db.fetch_members(server.as_str(), &mentions_vec[..]).await; if let Ok(valid_members) = valid_members { - let valid_mentions = HashSet::<&String, RandomState>::from_iter(valid_members.iter().map(|m| &m.id.user)); + let valid_mentions = HashSet::<&String, RandomState>::from_iter( + valid_members.iter().map(|m| &m.id.user), + ); user_mentions.retain(|m| valid_mentions.contains(m)); // quick pass, validate mentions are in the server @@ -503,7 +505,8 @@ impl Message { .members_can_see_channel() .await; - user_mentions.retain(|m| *member_channel_view_perms.get(m).unwrap_or(&false)); + user_mentions + .retain(|m| *member_channel_view_perms.get(m).unwrap_or(&false)); } } else { revolt_config::capture_error(&valid_members.unwrap_err()); @@ -517,7 +520,9 @@ impl Message { } if !user_mentions.is_empty() { - message.mentions.replace(user_mentions.into_iter().collect()); + message + .mentions + .replace(user_mentions.into_iter().collect()); } if !role_mentions.is_empty() { @@ -651,7 +656,7 @@ impl Message { pub async fn send( &mut self, db: &Database, - amqp: Option<&AMQP>, // this is optional mostly for tests. + _amqp: Option<&AMQP>, // this is optional mostly for tests. author: MessageAuthor<'_>, user: Option, member: Option, diff --git a/crates/core/database/src/models/safety_snapshots/model.rs b/crates/core/database/src/models/safety_snapshots/model.rs index e82ab388..e277f3a9 100644 --- a/crates/core/database/src/models/safety_snapshots/model.rs +++ b/crates/core/database/src/models/safety_snapshots/model.rs @@ -85,8 +85,8 @@ impl SnapshotContent { Ok(( SnapshotContent::Message { message, - prior_context: prior_context.into_iter().map(Into::into).collect(), - leading_context: leading_context.into_iter().map(Into::into).collect(), + prior_context: prior_context.into_iter().collect(), + leading_context: leading_context.into_iter().collect(), }, files, )) diff --git a/crates/core/database/src/models/server_bans/model.rs b/crates/core/database/src/models/server_bans/model.rs index 46e8a889..51044efe 100644 --- a/crates/core/database/src/models/server_bans/model.rs +++ b/crates/core/database/src/models/server_bans/model.rs @@ -13,6 +13,7 @@ auto_derived!( } ); +#[allow(clippy::disallowed_methods)] impl ServerBan { /// Create ban pub async fn create( diff --git a/crates/core/database/src/models/server_members/model.rs b/crates/core/database/src/models/server_members/model.rs index 72e16162..25b6979a 100644 --- a/crates/core/database/src/models/server_members/model.rs +++ b/crates/core/database/src/models/server_members/model.rs @@ -159,7 +159,7 @@ impl Member { } /// Update member data - pub async fn update<'a>( + pub async fn update( &mut self, db: &Database, partial: PartialMember, diff --git a/crates/core/database/src/models/servers/model.rs b/crates/core/database/src/models/servers/model.rs index 67c4daed..33cfa713 100644 --- a/crates/core/database/src/models/servers/model.rs +++ b/crates/core/database/src/models/servers/model.rs @@ -285,7 +285,7 @@ impl Role { } /// Update server data - pub async fn update<'a>( + pub async fn update( &mut self, db: &Database, server_id: &str, diff --git a/crates/core/database/src/models/users/model.rs b/crates/core/database/src/models/users/model.rs index 4fbf3029..fc2866cf 100644 --- a/crates/core/database/src/models/users/model.rs +++ b/crates/core/database/src/models/users/model.rs @@ -8,7 +8,7 @@ use iso8601_timestamp::Timestamp; use once_cell::sync::Lazy; use rand::seq::SliceRandom; use revolt_config::{config, FeaturesLimits}; -use revolt_models::v0::{self, UserFlags, UserBadges}; +use revolt_models::v0::{self, UserBadges, UserFlags}; use revolt_presence::filter_online; use revolt_result::{create_error, Result}; use serde_json::json; @@ -349,16 +349,13 @@ impl User { ) -> Result> { let online_ids = filter_online(ids).await; - Ok(join_all( - db - .fetch_users(ids) - .await? - .into_iter() - .map(|user| async { + Ok( + join_all(db.fetch_users(ids).await?.into_iter().map(|user| async { let is_online = online_ids.contains(&user.id); user.into_known(perspective, is_online).await - }) - ).await) + })) + .await, + ) } /// Find a free discriminator for a given username @@ -639,7 +636,7 @@ impl User { } /// Update user data - pub async fn update<'a>( + pub async fn update( &mut self, db: &Database, partial: PartialUser, @@ -817,7 +814,7 @@ impl User { if let Some(cutoff) = config.api.users.early_adopter_cutoff { if Ulid::from_string(&self.id).unwrap().timestamp_ms() < cutoff { - return badges + UserBadges::EarlyAdopter as u32 + return badges + UserBadges::EarlyAdopter as u32; }; }; diff --git a/crates/core/database/src/models/users/schema.rs b/crates/core/database/src/models/users/schema.rs index d887b895..28f5e42e 100644 --- a/crates/core/database/src/models/users/schema.rs +++ b/crates/core/database/src/models/users/schema.rs @@ -6,7 +6,7 @@ use revolt_rocket_okapi::{ use crate::User; -impl<'r> OpenApiFromRequest<'r> for User { +impl OpenApiFromRequest<'_> for User { fn from_request_input( _gen: &mut OpenApiGenerator, _name: String, diff --git a/crates/core/database/src/tasks/ack.rs b/crates/core/database/src/tasks/ack.rs index 1d2aff38..6b036da1 100644 --- a/crates/core/database/src/tasks/ack.rs +++ b/crates/core/database/src/tasks/ack.rs @@ -4,7 +4,6 @@ use crate::{Database, Message, AMQP}; use deadqueue::limited::Queue; use once_cell::sync::Lazy; use revolt_models::v0::PushNotification; -use rocket::form::validate::Contains; use std::{ collections::{HashMap, HashSet}, time::Duration, diff --git a/crates/core/database/src/util/bridge/v0.rs b/crates/core/database/src/util/bridge/v0.rs index 8872ef10..12f7c8fc 100644 --- a/crates/core/database/src/util/bridge/v0.rs +++ b/crates/core/database/src/util/bridge/v0.rs @@ -1,7 +1,7 @@ use revolt_models::v0::*; use revolt_permissions::{calculate_user_permissions, UserPermission}; -use crate::{util::permissions::DatabasePermissionQuery, Database, FileUsedFor}; +use crate::{util::permissions::DatabasePermissionQuery, Database}; impl crate::Bot { pub fn into_public_bot(self, user: crate::User) -> PublicBot { @@ -488,7 +488,7 @@ impl crate::Message { reactions: self.reactions, interactions: self.interactions.into(), masquerade: self.masquerade.map(Into::into), - flags: self.flags.map(|flags| flags as u32).unwrap_or_default(), + flags: self.flags.unwrap_or_default(), pinned: self.pinned, } } @@ -517,7 +517,7 @@ impl From for PartialMessage { reactions: value.reactions, interactions: value.interactions.map(Into::into), masquerade: value.masquerade.map(Into::into), - flags: value.flags.map(|flags| flags as u32), + flags: value.flags, pinned: value.pinned, } } diff --git a/crates/core/database/src/util/bulk_permissions.rs b/crates/core/database/src/util/bulk_permissions.rs index 928acfce..9e7a1f7a 100644 --- a/crates/core/database/src/util/bulk_permissions.rs +++ b/crates/core/database/src/util/bulk_permissions.rs @@ -87,7 +87,7 @@ impl<'z> BulkDatabasePermissionQuery<'z> { } } - pub fn channel(self, channel: &'z Channel) -> BulkDatabasePermissionQuery { + pub fn channel(self, channel: &'z Channel) -> BulkDatabasePermissionQuery<'z> { BulkDatabasePermissionQuery { channel: Some(channel.clone()), ..self @@ -109,7 +109,7 @@ impl<'z> BulkDatabasePermissionQuery<'z> { } } - pub fn members(self, members: &'z [Member]) -> BulkDatabasePermissionQuery { + pub fn members(self, members: &'z [Member]) -> BulkDatabasePermissionQuery<'z> { BulkDatabasePermissionQuery { members: Some(members.to_owned()), cached_member_perms: None, @@ -120,7 +120,7 @@ impl<'z> BulkDatabasePermissionQuery<'z> { } } - pub fn users(self, users: &'z [User]) -> BulkDatabasePermissionQuery { + pub fn users(self, users: &'z [User]) -> BulkDatabasePermissionQuery<'z> { BulkDatabasePermissionQuery { users: Some(users.to_owned()), cached_member_perms: None, diff --git a/crates/core/database/src/util/permissions.rs b/crates/core/database/src/util/permissions.rs index e80b0da1..605b05b7 100644 --- a/crates/core/database/src/util/permissions.rs +++ b/crates/core/database/src/util/permissions.rs @@ -305,16 +305,14 @@ impl PermissionQuery for DatabasePermissionQuery<'_> { /// Are we a recipient of this channel? async fn are_we_part_of_the_channel(&mut self) -> bool { - if let Some(channel) = &self.channel { - match channel { - Cow::Borrowed(Channel::DirectMessage { recipients, .. }) - | Cow::Owned(Channel::DirectMessage { recipients, .. }) - | Cow::Borrowed(Channel::Group { recipients, .. }) - | Cow::Owned(Channel::Group { recipients, .. }) => { - recipients.contains(&self.perspective.id) - } - _ => false, - } + if let Some( + Cow::Borrowed(Channel::DirectMessage { recipients, .. }) + | Cow::Owned(Channel::DirectMessage { recipients, .. }) + | Cow::Borrowed(Channel::Group { recipients, .. }) + | Cow::Owned(Channel::Group { recipients, .. }), + ) = &self.channel + { + recipients.contains(&self.perspective.id) } else { false } @@ -420,7 +418,7 @@ impl<'a> DatabasePermissionQuery<'a> { } /// Use user - pub fn user(self, user: &'a User) -> DatabasePermissionQuery { + pub fn user(self, user: &'a User) -> DatabasePermissionQuery<'a> { DatabasePermissionQuery { user: Some(Cow::Borrowed(user)), ..self @@ -428,7 +426,7 @@ impl<'a> DatabasePermissionQuery<'a> { } /// Use channel - pub fn channel(self, channel: &'a Channel) -> DatabasePermissionQuery { + pub fn channel(self, channel: &'a Channel) -> DatabasePermissionQuery<'a> { DatabasePermissionQuery { channel: Some(Cow::Borrowed(channel)), ..self @@ -436,7 +434,7 @@ impl<'a> DatabasePermissionQuery<'a> { } /// Use server - pub fn server(self, server: &'a Server) -> DatabasePermissionQuery { + pub fn server(self, server: &'a Server) -> DatabasePermissionQuery<'a> { DatabasePermissionQuery { server: Some(Cow::Borrowed(server)), ..self @@ -444,7 +442,7 @@ impl<'a> DatabasePermissionQuery<'a> { } /// Use member - pub fn member(self, member: &'a Member) -> DatabasePermissionQuery { + pub fn member(self, member: &'a Member) -> DatabasePermissionQuery<'a> { DatabasePermissionQuery { member: Some(Cow::Borrowed(member)), ..self diff --git a/crates/core/models/src/v0/messages.rs b/crates/core/models/src/v0/messages.rs index 0324e8b1..1ef8aab0 100644 --- a/crates/core/models/src/v0/messages.rs +++ b/crates/core/models/src/v0/messages.rs @@ -399,7 +399,7 @@ impl Interactions { } } -impl<'a> MessageAuthor<'a> { +impl MessageAuthor<'_> { pub fn id(&self) -> &str { match self { MessageAuthor::User(user) => &user.id, diff --git a/crates/delta/src/routes/channels/members_fetch.rs b/crates/delta/src/routes/channels/members_fetch.rs index 64a14a9b..4a6688bf 100644 --- a/crates/delta/src/routes/channels/members_fetch.rs +++ b/crates/delta/src/routes/channels/members_fetch.rs @@ -1,4 +1,3 @@ -use futures::future::join_all; use revolt_database::{ util::{permissions::DatabasePermissionQuery, reference::Reference}, Channel, Database, User, diff --git a/crates/delta/src/routes/channels/message_bulk_delete.rs b/crates/delta/src/routes/channels/message_bulk_delete.rs index 6cb2b37a..446b1e26 100644 --- a/crates/delta/src/routes/channels/message_bulk_delete.rs +++ b/crates/delta/src/routes/channels/message_bulk_delete.rs @@ -8,7 +8,6 @@ use revolt_permissions::{calculate_channel_permissions, ChannelPermission}; use revolt_result::{create_error, Result}; use rocket::{serde::json::Json, State}; use rocket_empty::EmptyResponse; -use serde::Deserialize; use validator::Validate; /// # Bulk Delete Messages diff --git a/crates/delta/src/routes/channels/message_edit.rs b/crates/delta/src/routes/channels/message_edit.rs index 3662ee63..2b5d24f7 100644 --- a/crates/delta/src/routes/channels/message_edit.rs +++ b/crates/delta/src/routes/channels/message_edit.rs @@ -1,5 +1,4 @@ use iso8601_timestamp::Timestamp; -use revolt_config::config; use revolt_database::{ tasks, util::{permissions::DatabasePermissionQuery, reference::Reference}, diff --git a/crates/delta/src/routes/channels/permissions_set.rs b/crates/delta/src/routes/channels/permissions_set.rs index b4b3c3dc..70ded35d 100644 --- a/crates/delta/src/routes/channels/permissions_set.rs +++ b/crates/delta/src/routes/channels/permissions_set.rs @@ -1,12 +1,11 @@ use revolt_database::{ util::{permissions::DatabasePermissionQuery, reference::Reference}, - Channel, Database, User, + Database, User, }; use revolt_models::v0; use revolt_permissions::{calculate_channel_permissions, ChannelPermission, Override}; use revolt_result::{create_error, Result}; use rocket::{serde::json::Json, State}; -use serde::Deserialize; /// # Set Role Permission /// diff --git a/crates/delta/src/routes/customisation/emoji_delete.rs b/crates/delta/src/routes/customisation/emoji_delete.rs index 53cbb837..05d89eb0 100644 --- a/crates/delta/src/routes/customisation/emoji_delete.rs +++ b/crates/delta/src/routes/customisation/emoji_delete.rs @@ -3,7 +3,7 @@ use revolt_database::{ Database, EmojiParent, User, }; use revolt_permissions::{calculate_server_permissions, ChannelPermission}; -use revolt_result::{create_error, Result}; +use revolt_result::Result; use rocket::State; use rocket_empty::EmptyResponse; @@ -18,7 +18,6 @@ pub async fn delete_emoji( user: User, emoji_id: Reference, ) -> Result { - // Fetch the emoji let emoji = emoji_id.as_emoji(db).await?; diff --git a/crates/delta/src/routes/mod.rs b/crates/delta/src/routes/mod.rs index 5107e7c2..25ed460d 100644 --- a/crates/delta/src/routes/mod.rs +++ b/crates/delta/src/routes/mod.rs @@ -1,4 +1,4 @@ -use revolt_config::{config, Settings}; +use revolt_config::Settings; use revolt_rocket_okapi::{revolt_okapi::openapi3::OpenApi, settings::OpenApiSettings}; pub use rocket::http::Status; pub use rocket::response::Redirect; diff --git a/crates/delta/src/routes/servers/ban_create.rs b/crates/delta/src/routes/servers/ban_create.rs index 8003e79e..a73be114 100644 --- a/crates/delta/src/routes/servers/ban_create.rs +++ b/crates/delta/src/routes/servers/ban_create.rs @@ -4,12 +4,9 @@ use revolt_database::{ }; use revolt_models::v0; -use revolt_permissions::{ - calculate_channel_permissions, calculate_server_permissions, ChannelPermission, -}; +use revolt_permissions::{calculate_server_permissions, ChannelPermission}; use revolt_result::{create_error, Result}; use rocket::{serde::json::Json, State}; -use serde::{Deserialize, Serialize}; use validator::Validate; /// # Ban User diff --git a/crates/delta/src/routes/servers/permissions_set_default.rs b/crates/delta/src/routes/servers/permissions_set_default.rs index 8189e956..96bda2de 100644 --- a/crates/delta/src/routes/servers/permissions_set_default.rs +++ b/crates/delta/src/routes/servers/permissions_set_default.rs @@ -1,6 +1,6 @@ use revolt_database::{ util::{permissions::DatabasePermissionQuery, reference::Reference}, - Database, PartialServer, Server, User, + Database, PartialServer, User, }; use revolt_models::v0; use revolt_permissions::{ diff --git a/crates/delta/src/routes/servers/roles_edit.rs b/crates/delta/src/routes/servers/roles_edit.rs index c7f5124c..72ec6635 100644 --- a/crates/delta/src/routes/servers/roles_edit.rs +++ b/crates/delta/src/routes/servers/roles_edit.rs @@ -6,7 +6,6 @@ use revolt_models::v0; use revolt_permissions::{calculate_server_permissions, ChannelPermission}; use revolt_result::{create_error, Result}; use rocket::{serde::json::Json, State}; -use serde::{Deserialize, Serialize}; use validator::Validate; /// # Edit Role diff --git a/crates/delta/src/routes/users/fetch_user_flags.rs b/crates/delta/src/routes/users/fetch_user_flags.rs index 39c731d0..92377a57 100644 --- a/crates/delta/src/routes/users/fetch_user_flags.rs +++ b/crates/delta/src/routes/users/fetch_user_flags.rs @@ -2,7 +2,6 @@ use revolt_database::{util::reference::Reference, Database}; use revolt_models::v0; use revolt_result::Result; use rocket::{serde::json::Json, State}; -use serde::Serialize; /// # Fetch User Flags /// diff --git a/crates/delta/src/routes/webhooks/webhook_execute_github.rs b/crates/delta/src/routes/webhooks/webhook_execute_github.rs index 6d9c8b60..ae7ff40c 100644 --- a/crates/delta/src/routes/webhooks/webhook_execute_github.rs +++ b/crates/delta/src/routes/webhooks/webhook_execute_github.rs @@ -588,6 +588,7 @@ pub enum PullRequestEvent { #[derive(Debug)] #[allow(clippy::large_enum_variant)] pub enum BaseEvent { + #[allow(dead_code)] Star(StarEvent), Ping, Push(PushEvent), @@ -829,7 +830,7 @@ pub async fn webhook_execute_github( }) .collect::>() .join("\n"), - 1000 + 1000, ); SendableEmbed { From a72134f4ad6ee22afddfbce80d3436479f9a6797 Mon Sep 17 00:00:00 2001 From: izzy Date: Tue, 13 May 2025 10:52:44 +0100 Subject: [PATCH 20/26] chore: bump version to 0.8.6 chore: publish revolt-parser --- Cargo.lock | 28 ++++++++++++++-------------- crates/bonfire/Cargo.toml | 4 ++-- crates/core/config/Cargo.toml | 4 ++-- crates/core/database/Cargo.toml | 14 +++++++------- crates/core/files/Cargo.toml | 6 +++--- crates/core/models/Cargo.toml | 6 +++--- crates/core/parser/Cargo.toml | 6 ++++-- crates/core/permissions/Cargo.toml | 4 ++-- crates/core/presence/Cargo.toml | 2 +- crates/core/result/Cargo.toml | 2 +- crates/daemons/crond/Cargo.toml | 10 +++++----- crates/daemons/pushd/Cargo.toml | 12 ++++++------ crates/delta/Cargo.toml | 2 +- crates/services/autumn/Cargo.toml | 10 +++++----- crates/services/january/Cargo.toml | 10 +++++----- justfile | 1 + 16 files changed, 62 insertions(+), 59 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ae209196..7863ec4c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5954,7 +5954,7 @@ dependencies = [ [[package]] name = "revolt-autumn" -version = "0.8.5" +version = "0.8.6" dependencies = [ "axum", "axum-macros", @@ -5991,7 +5991,7 @@ dependencies = [ [[package]] name = "revolt-bonfire" -version = "0.8.5" +version = "0.8.6" dependencies = [ "async-channel 2.3.1", "async-std", @@ -6021,7 +6021,7 @@ dependencies = [ [[package]] name = "revolt-config" -version = "0.8.5" +version = "0.8.6" dependencies = [ "async-std", "cached", @@ -6038,7 +6038,7 @@ dependencies = [ [[package]] name = "revolt-crond" -version = "0.8.5" +version = "0.8.6" dependencies = [ "log", "revolt-config", @@ -6050,7 +6050,7 @@ dependencies = [ [[package]] name = "revolt-database" -version = "0.8.5" +version = "0.8.6" dependencies = [ "amqprs", "async-lock 2.8.0", @@ -6100,7 +6100,7 @@ dependencies = [ [[package]] name = "revolt-delta" -version = "0.8.5" +version = "0.8.6" dependencies = [ "amqprs", "async-channel 1.9.0", @@ -6147,7 +6147,7 @@ dependencies = [ [[package]] name = "revolt-files" -version = "0.8.5" +version = "0.8.6" dependencies = [ "aes-gcm", "aws-config", @@ -6170,7 +6170,7 @@ dependencies = [ [[package]] name = "revolt-january" -version = "0.8.5" +version = "0.8.6" dependencies = [ "async-recursion", "axum", @@ -6198,7 +6198,7 @@ dependencies = [ [[package]] name = "revolt-models" -version = "0.8.5" +version = "0.8.6" dependencies = [ "indexmap 1.9.3", "iso8601-timestamp", @@ -6217,14 +6217,14 @@ dependencies = [ [[package]] name = "revolt-parser" -version = "0.1.1" +version = "0.8.6" dependencies = [ "logos", ] [[package]] name = "revolt-permissions" -version = "0.8.5" +version = "0.8.6" dependencies = [ "async-std", "async-trait", @@ -6239,7 +6239,7 @@ dependencies = [ [[package]] name = "revolt-presence" -version = "0.8.5" +version = "0.8.6" dependencies = [ "async-std", "log", @@ -6250,7 +6250,7 @@ dependencies = [ [[package]] name = "revolt-pushd" -version = "0.8.5" +version = "0.8.6" dependencies = [ "amqprs", "anyhow", @@ -6278,7 +6278,7 @@ dependencies = [ [[package]] name = "revolt-result" -version = "0.8.5" +version = "0.8.6" dependencies = [ "axum", "revolt_okapi", diff --git a/crates/bonfire/Cargo.toml b/crates/bonfire/Cargo.toml index ac852bae..353469b8 100644 --- a/crates/bonfire/Cargo.toml +++ b/crates/bonfire/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-bonfire" -version = "0.8.5" +version = "0.8.6" license = "AGPL-3.0-or-later" edition = "2021" @@ -41,7 +41,7 @@ revolt-result = { path = "../core/result" } revolt-models = { path = "../core/models" } revolt-config = { path = "../core/config" } revolt-database = { path = "../core/database" } -revolt-permissions = { version = "0.8.5", path = "../core/permissions" } +revolt-permissions = { version = "0.8.6", path = "../core/permissions" } revolt-presence = { path = "../core/presence", features = ["redis-is-patched"] } # redis diff --git a/crates/core/config/Cargo.toml b/crates/core/config/Cargo.toml index a2beff9a..02595ac9 100644 --- a/crates/core/config/Cargo.toml +++ b/crates/core/config/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-config" -version = "0.8.5" +version = "0.8.6" edition = "2021" license = "MIT" authors = ["Paul Makles "] @@ -36,4 +36,4 @@ sentry = "0.31.5" sentry-anyhow = { version = "0.38.1", optional = true } # Core -revolt-result = { version = "0.8.5", path = "../result", optional = true } +revolt-result = { version = "0.8.6", path = "../result", optional = true } diff --git a/crates/core/database/Cargo.toml b/crates/core/database/Cargo.toml index 709cb577..8f7c165a 100644 --- a/crates/core/database/Cargo.toml +++ b/crates/core/database/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-database" -version = "0.8.5" +version = "0.8.6" edition = "2021" license = "AGPL-3.0-or-later" authors = ["Paul Makles "] @@ -24,19 +24,19 @@ default = ["mongodb", "async-std-runtime", "tasks"] [dependencies] # Core -revolt-config = { version = "0.8.5", path = "../config", features = [ +revolt-config = { version = "0.8.6", path = "../config", features = [ "report-macros", ] } -revolt-result = { version = "0.8.5", path = "../result" } -revolt-models = { version = "0.8.5", path = "../models", features = [ +revolt-result = { version = "0.8.6", path = "../result" } +revolt-models = { version = "0.8.6", path = "../models", features = [ "validator", ] } -revolt-presence = { version = "0.8.5", path = "../presence" } -revolt-permissions = { version = "0.8.5", path = "../permissions", features = [ +revolt-presence = { version = "0.8.6", path = "../presence" } +revolt-permissions = { version = "0.8.6", path = "../permissions", features = [ "serde", "bson", ] } -revolt-parser = { version = "0.1.1", path = "../parser" } +revolt-parser = { version = "0.8.6", path = "../parser" } # Utility log = "0.4" diff --git a/crates/core/files/Cargo.toml b/crates/core/files/Cargo.toml index 3d77ba63..29cf897d 100644 --- a/crates/core/files/Cargo.toml +++ b/crates/core/files/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-files" -version = "0.8.5" +version = "0.8.6" edition = "2021" license = "AGPL-3.0-or-later" authors = ["Paul Makles "] @@ -20,10 +20,10 @@ typenum = "1.17.0" aws-config = "1.5.5" aws-sdk-s3 = { version = "1.46.0", features = ["behavior-version-latest"] } -revolt-config = { version = "0.8.5", path = "../config", features = [ +revolt-config = { version = "0.8.6", path = "../config", features = [ "report-macros", ] } -revolt-result = { version = "0.8.5", path = "../result" } +revolt-result = { version = "0.8.6", path = "../result" } # image processing jxl-oxide = "0.8.1" diff --git a/crates/core/models/Cargo.toml b/crates/core/models/Cargo.toml index d1308d39..691d37a5 100644 --- a/crates/core/models/Cargo.toml +++ b/crates/core/models/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-models" -version = "0.8.5" +version = "0.8.6" edition = "2021" license = "MIT" authors = ["Paul Makles "] @@ -20,8 +20,8 @@ default = ["serde", "partials", "rocket"] [dependencies] # Core -revolt-config = { version = "0.8.5", path = "../config" } -revolt-permissions = { version = "0.8.5", path = "../permissions" } +revolt-config = { version = "0.8.6", path = "../config" } +revolt-permissions = { version = "0.8.6", path = "../permissions" } # Utility regex = "1.11" diff --git a/crates/core/parser/Cargo.toml b/crates/core/parser/Cargo.toml index 6a6913ad..558997bf 100644 --- a/crates/core/parser/Cargo.toml +++ b/crates/core/parser/Cargo.toml @@ -1,7 +1,9 @@ [package] name = "revolt-parser" -version = "0.1.1" +version = "0.8.6" edition = "2021" +license = "AGPL-3.0-or-later" +description = "Revolt Backend: Message Parser" [dependencies] -logos = { version = "*" } +logos = { version = "0.15" } diff --git a/crates/core/permissions/Cargo.toml b/crates/core/permissions/Cargo.toml index 3b2f9ac8..886ed973 100644 --- a/crates/core/permissions/Cargo.toml +++ b/crates/core/permissions/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-permissions" -version = "0.8.5" +version = "0.8.6" edition = "2021" license = "MIT" authors = ["Paul Makles "] @@ -21,7 +21,7 @@ async-std = { version = "1.8.0", features = ["attributes"] } [dependencies] # Core -revolt-result = { version = "0.8.5", path = "../result" } +revolt-result = { version = "0.8.6", path = "../result" } # Utility auto_ops = "0.3.0" diff --git a/crates/core/presence/Cargo.toml b/crates/core/presence/Cargo.toml index 874e65c6..5e101db0 100644 --- a/crates/core/presence/Cargo.toml +++ b/crates/core/presence/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-presence" -version = "0.8.5" +version = "0.8.6" edition = "2021" license = "AGPL-3.0-or-later" authors = ["Paul Makles "] diff --git a/crates/core/result/Cargo.toml b/crates/core/result/Cargo.toml index 6add1173..cd314fb5 100644 --- a/crates/core/result/Cargo.toml +++ b/crates/core/result/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-result" -version = "0.8.5" +version = "0.8.6" edition = "2021" license = "MIT" authors = ["Paul Makles "] diff --git a/crates/daemons/crond/Cargo.toml b/crates/daemons/crond/Cargo.toml index 30250745..4c89f8bf 100644 --- a/crates/daemons/crond/Cargo.toml +++ b/crates/daemons/crond/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-crond" -version = "0.8.5" +version = "0.8.6" license = "AGPL-3.0-or-later" authors = ["Paul Makles "] edition = "2021" @@ -16,7 +16,7 @@ log = "0.4" tokio = { version = "1" } # Core -revolt-database = { version = "0.8.5", path = "../../core/database" } -revolt-result = { version = "0.8.5", path = "../../core/result" } -revolt-config = { version = "0.8.5", path = "../../core/config" } -revolt-files = { version = "0.8.5", path = "../../core/files" } +revolt-database = { version = "0.8.6", path = "../../core/database" } +revolt-result = { version = "0.8.6", path = "../../core/result" } +revolt-config = { version = "0.8.6", path = "../../core/config" } +revolt-files = { version = "0.8.6", path = "../../core/files" } diff --git a/crates/daemons/pushd/Cargo.toml b/crates/daemons/pushd/Cargo.toml index 699654de..40a30e87 100644 --- a/crates/daemons/pushd/Cargo.toml +++ b/crates/daemons/pushd/Cargo.toml @@ -1,19 +1,19 @@ [package] name = "revolt-pushd" -version = "0.8.5" +version = "0.8.6" edition = "2021" license = "AGPL-3.0-or-later" [dependencies] -revolt-result = { version = "0.8.5", path = "../../core/result" } -revolt-config = { version = "0.8.5", path = "../../core/config", features = [ +revolt-result = { version = "0.8.6", path = "../../core/result" } +revolt-config = { version = "0.8.6", path = "../../core/config", features = [ "report-macros", ] } -revolt-database = { version = "0.8.5", path = "../../core/database" } -revolt-models = { version = "0.8.5", path = "../../core/models", features = [ +revolt-database = { version = "0.8.6", path = "../../core/database" } +revolt-models = { version = "0.8.6", path = "../../core/models", features = [ "validator", ] } -revolt-presence = { version = "0.8.5", path = "../../core/presence", features = [ +revolt-presence = { version = "0.8.6", path = "../../core/presence", features = [ "redis-is-patched", ] } diff --git a/crates/delta/Cargo.toml b/crates/delta/Cargo.toml index 46ec7c4a..4bb4ff9a 100644 --- a/crates/delta/Cargo.toml +++ b/crates/delta/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-delta" -version = "0.8.5" +version = "0.8.6" license = "AGPL-3.0-or-later" authors = ["Paul Makles "] edition = "2018" diff --git a/crates/services/autumn/Cargo.toml b/crates/services/autumn/Cargo.toml index 395640aa..eea5a707 100644 --- a/crates/services/autumn/Cargo.toml +++ b/crates/services/autumn/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-autumn" -version = "0.8.5" +version = "0.8.6" edition = "2021" license = "AGPL-3.0-or-later" @@ -43,12 +43,12 @@ tracing = "0.1" tracing-subscriber = { version = "0.3", features = ["env-filter"] } # Core crates -revolt-files = { version = "0.8.5", path = "../../core/files" } -revolt-config = { version = "0.8.5", path = "../../core/config" } -revolt-database = { version = "0.8.5", path = "../../core/database", features = [ +revolt-files = { version = "0.8.6", path = "../../core/files" } +revolt-config = { version = "0.8.6", path = "../../core/config" } +revolt-database = { version = "0.8.6", path = "../../core/database", features = [ "axum-impl", ] } -revolt-result = { version = "0.8.5", path = "../../core/result", features = [ +revolt-result = { version = "0.8.6", path = "../../core/result", features = [ "utoipa", "axum", ] } diff --git a/crates/services/january/Cargo.toml b/crates/services/january/Cargo.toml index ce368a6a..fedfae97 100644 --- a/crates/services/january/Cargo.toml +++ b/crates/services/january/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-january" -version = "0.8.5" +version = "0.8.6" edition = "2021" license = "AGPL-3.0-or-later" @@ -32,13 +32,13 @@ tracing = "0.1" tracing-subscriber = { version = "0.3", features = ["env-filter"] } # Core crates -revolt-config = { version = "0.8.5", path = "../../core/config" } -revolt-models = { version = "0.8.5", path = "../../core/models" } -revolt-result = { version = "0.8.5", path = "../../core/result", features = [ +revolt-config = { version = "0.8.6", path = "../../core/config" } +revolt-models = { version = "0.8.6", path = "../../core/models" } +revolt-result = { version = "0.8.6", path = "../../core/result", features = [ "utoipa", "axum", ] } -revolt-files = { version = "0.8.5", path = "../../core/files" } +revolt-files = { version = "0.8.6", path = "../../core/files" } # Axum / web server axum = { version = "0.7.5" } diff --git a/justfile b/justfile index e093afde..e7bd0f00 100644 --- a/justfile +++ b/justfile @@ -1,4 +1,5 @@ publish: + cargo publish --package revolt-parser cargo publish --package revolt-config cargo publish --package revolt-result cargo publish --package revolt-files From be89e62d5411765ddd35c8fce7a5c1ccfaf3c8ce Mon Sep 17 00:00:00 2001 From: izzy Date: Tue, 13 May 2025 11:04:43 +0100 Subject: [PATCH 21/26] fix: include `pushd` key in Revolt.toml --- crates/core/config/Revolt.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/crates/core/config/Revolt.toml b/crates/core/config/Revolt.toml index 08b59713..e3a04f2a 100644 --- a/crates/core/config/Revolt.toml +++ b/crates/core/config/Revolt.toml @@ -275,4 +275,5 @@ api = "" events = "" files = "" proxy = "" +pushd = "" crond = "" From 5362e847304b0d70aa9b23f8316bc225c154546c Mon Sep 17 00:00:00 2001 From: izzy Date: Tue, 13 May 2025 11:16:28 +0100 Subject: [PATCH 22/26] fix: don't try to mount env logger twice --- crates/daemons/pushd/src/main.rs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/crates/daemons/pushd/src/main.rs b/crates/daemons/pushd/src/main.rs index 57be4d89..78845a63 100644 --- a/crates/daemons/pushd/src/main.rs +++ b/crates/daemons/pushd/src/main.rs @@ -24,9 +24,6 @@ use consumers::{ #[tokio::main(flavor = "multi_thread", worker_threads = 2)] async fn main() { - let config = config().await; - pretty_env_logger::init(); - // Configure logging and environment revolt_config::configure!(pushd); @@ -55,6 +52,8 @@ async fn main() { // This'll require some interesting shimming if we need to add more events once this is in prod (different payloads between prod and test), // but that sounds like a problem for future us. + let config = config().await; + // inbound: generic connections.push( make_queue_and_consume( From 4f13f5899ba1f827b5327ccf4ae7be87818bba16 Mon Sep 17 00:00:00 2001 From: izzy Date: Wed, 14 May 2025 11:40:07 +0100 Subject: [PATCH 23/26] fix: authifier should not use transactions for migrations --- Cargo.lock | 9 +++++---- crates/bonfire/Cargo.toml | 2 +- crates/core/database/Cargo.toml | 2 +- .../src/models/admin_migrations/ops/mongodb/scripts.rs | 2 +- crates/daemons/pushd/Cargo.toml | 2 +- crates/delta/Cargo.toml | 4 ++-- 6 files changed, 11 insertions(+), 10 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 7863ec4c..712754c9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -446,9 +446,9 @@ dependencies = [ [[package]] name = "authifier" -version = "1.0.13" +version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca26cb6b5ab776a1de5a8122fe6cc77fadd84fed30704c496f2aca451637877b" +checksum = "b1a03b810b342b4c584cdc1cfc40d1ec763b1d653ef4086f7494740f35d9e1f0" dependencies = [ "async-std", "async-trait", @@ -6478,9 +6478,9 @@ dependencies = [ [[package]] name = "rocket_authifier" -version = "1.0.13" +version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0490f4a6f0a359a9ffff9acbdf4eddf49890ec94941b8ddd88163c16f6159f5a" +checksum = "c1f98a5be96ac4144ee1adc809c1594e8212032b8a08d9bc4cef70735dfd976e" dependencies = [ "authifier", "iso8601-timestamp", @@ -8294,6 +8294,7 @@ checksum = "220b18413e1fe5e85a5580b22f44241f82404a66c792c9f3c9eda74c52d9a22e" dependencies = [ "chrono", "rand 0.8.5", + "serde", ] [[package]] diff --git a/crates/bonfire/Cargo.toml b/crates/bonfire/Cargo.toml index 353469b8..5a55f1aa 100644 --- a/crates/bonfire/Cargo.toml +++ b/crates/bonfire/Cargo.toml @@ -36,7 +36,7 @@ async-std = { version = "1.8.0", features = [ ] } # core -authifier = { version = "1.0.13" } +authifier = { version = "1.0.15" } revolt-result = { path = "../core/result" } revolt-models = { path = "../core/models" } revolt-config = { path = "../core/config" } diff --git a/crates/core/database/Cargo.toml b/crates/core/database/Cargo.toml index 8f7c165a..81b0224e 100644 --- a/crates/core/database/Cargo.toml +++ b/crates/core/database/Cargo.toml @@ -97,7 +97,7 @@ web-push = "0.10.0" revolt_a2 = { version = "0.10", default-features = false, features = ["ring"] } # Authifier -authifier = { version = "1.0.13", features = ["rocket_impl"] } +authifier = { version = "1.0.15", features = ["rocket_impl"] } # RabbitMQ amqprs = { version = "1.7.0" } diff --git a/crates/core/database/src/models/admin_migrations/ops/mongodb/scripts.rs b/crates/core/database/src/models/admin_migrations/ops/mongodb/scripts.rs index a00cfab7..aafee066 100644 --- a/crates/core/database/src/models/admin_migrations/ops/mongodb/scripts.rs +++ b/crates/core/database/src/models/admin_migrations/ops/mongodb/scripts.rs @@ -21,7 +21,7 @@ struct MigrationInfo { revision: i32, } -pub const LATEST_REVISION: i32 = 32; +pub const LATEST_REVISION: i32 = 33; // MUST BE +1 to last migration pub async fn migrate_database(db: &MongoDb) { let migrations = db.col::("migrations"); diff --git a/crates/daemons/pushd/Cargo.toml b/crates/daemons/pushd/Cargo.toml index 40a30e87..6696b213 100644 --- a/crates/daemons/pushd/Cargo.toml +++ b/crates/daemons/pushd/Cargo.toml @@ -28,7 +28,7 @@ tokio = "1.39.2" async-trait = "0.1.81" ulid = "1.0.0" -authifier = "1.0.10" +authifier = "1.0.15" log = "0.4.11" pretty_env_logger = "0.4.0" diff --git a/crates/delta/Cargo.toml b/crates/delta/Cargo.toml index 4bb4ff9a..4b79c107 100644 --- a/crates/delta/Cargo.toml +++ b/crates/delta/Cargo.toml @@ -56,7 +56,7 @@ lettre = "0.10.0-alpha.4" rocket = { version = "0.5.1", default-features = false, features = ["json"] } rocket_cors = { git = "https://github.com/lawliet89/rocket_cors", rev = "072d90359b23e9b291df6b672c07c93de9c46011" } rocket_empty = { version = "0.1.1", features = ["schema"] } -rocket_authifier = { version = "1.0.13" } +rocket_authifier = { version = "1.0.15" } rocket_prometheus = "0.10.0-rc.3" # spec generation @@ -67,7 +67,7 @@ revolt_rocket_okapi = { version = "0.10.0", features = ["swagger"] } amqprs = { version = "1.7.0" } # core -authifier = "1.0.13" +authifier = "1.0.15" revolt-config = { path = "../core/config" } revolt-database = { path = "../core/database", features = [ "rocket-impl", From 99a80f723d71aa1aaeaf2c4d70d273dbb7c00f41 Mon Sep 17 00:00:00 2001 From: izzy Date: Wed, 14 May 2025 11:46:56 +0100 Subject: [PATCH 24/26] chore: increase verbosity for ack logging --- crates/core/database/src/tasks/ack.rs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/crates/core/database/src/tasks/ack.rs b/crates/core/database/src/tasks/ack.rs index 6b036da1..e4023515 100644 --- a/crates/core/database/src/tasks/ack.rs +++ b/crates/core/database/src/tasks/ack.rs @@ -113,7 +113,7 @@ pub async fn handle_ack_event( } AckEvent::ProcessMessage { messages } => { let mut users: HashSet<&String> = HashSet::new(); - debug!( + info!( "Processing {} messages from channel {}", messages.len(), messages[0].1.channel @@ -124,7 +124,7 @@ pub async fn handle_ack_event( users.extend(recipents.iter()); }); - debug!("Found {} users to notify.", users.len()); + info!("Found {} users to notify.", users.len()); for user in users { let message_ids: Vec = messages @@ -142,7 +142,7 @@ pub async fn handle_ack_event( db.add_mention_to_unread(channel, user, &message_ids) .await?; } - debug!("Added {} mentions for user {}", message_ids.len(), &user); + info!("Added {} mentions for user {}", message_ids.len(), &user); } let mut mass_mentions = vec![]; @@ -231,7 +231,7 @@ pub async fn worker(db: Database, amqp: AMQP) { revolt_config::capture_error(&err); error!("{err:?} for {event:?}. ({user:?}, {channel})"); } else { - debug!("User {user:?} ack in {channel} with {event:?}"); + info!("User {user:?} ack in {channel} with {event:?}"); } } } @@ -246,6 +246,8 @@ pub async fn worker(db: Database, amqp: AMQP) { mut event, }) = Q.try_pop() { + info!("Took next ack from queue, now {} remaining", Q.len()); + let key: (Option, String, u8) = ( user, channel, From 8153f5f17a82629b09723008b31736122b844d7d Mon Sep 17 00:00:00 2001 From: IAmTomahawkx Date: Thu, 15 May 2025 03:20:32 -0700 Subject: [PATCH 25/26] Don't panic on empty message list ... even though it shouldn't be possible. --- crates/core/database/src/tasks/ack.rs | 41 ++++++++++++++++----------- 1 file changed, 25 insertions(+), 16 deletions(-) diff --git a/crates/core/database/src/tasks/ack.rs b/crates/core/database/src/tasks/ack.rs index e4023515..c12e41f3 100644 --- a/crates/core/database/src/tasks/ack.rs +++ b/crates/core/database/src/tasks/ack.rs @@ -3,6 +3,7 @@ use crate::{Database, Message, AMQP}; use deadqueue::limited::Queue; use once_cell::sync::Lazy; +use revolt_config::capture_message; use revolt_models::v0::PushNotification; use std::{ collections::{HashMap, HashSet}, @@ -64,6 +65,7 @@ pub async fn queue_ack(channel: String, user: String, event: AckEvent) { ); } +/// Do not add more than one message per event. pub async fn queue_message(channel: String, event: AckEvent) { Q.try_push(Data { channel, @@ -262,24 +264,31 @@ pub async fn worker(db: Database, amqp: AMQP) { if let AckEvent::ProcessMessage { messages: existing } = &mut task.data.event { - // add the new message to the list of messages to be processed. - existing.append(new_data); + if let Some(new_event) = new_data.pop() { + // if the message contains a mass mention, do not delay it any further. + if new_event.1.contains_mass_push_mention() { + // add the new message to the list of messages to be processed. + existing.push(new_event); + task.run_immediately(); + continue; + } - // if the message contains a mass mention, do not delay it any further. - if new_data[0].1.contains_mass_push_mention() { - task.run_immediately(); - continue; - } + existing.push(new_event); - // put a cap on the amount of messages that can be queued, for particularly active channels - if (existing.length() as u16) - < revolt_config::config() - .await - .features - .advanced - .process_message_delay_limit - { - task.delay(); + // put a cap on the amount of messages that can be queued, for particularly active channels + if (existing.length() as u16) + < revolt_config::config() + .await + .features + .advanced + .process_message_delay_limit + { + task.delay(); + } + } else { + let err_msg = format!("Got zero-length message event: {event:?}"); + capture_message(&err_msg, revolt_config::Level::Warning); + info!("{err_msg}") } } else { panic!("Somehow got an ack message in the add mention arm"); From c4728c696d1fd2ea39c41961db751ea9360ed4f9 Mon Sep 17 00:00:00 2001 From: izzy Date: Fri, 30 May 2025 13:12:57 +0100 Subject: [PATCH 26/26] feat: policy changes API chore: bump version to 0.8.7 --- Cargo.lock | 28 +++++------ crates/bonfire/Cargo.toml | 4 +- crates/bonfire/src/events/impl.rs | 15 ++++++ crates/core/config/Cargo.toml | 4 +- crates/core/database/Cargo.toml | 14 +++--- crates/core/database/src/drivers/reference.rs | 5 +- crates/core/database/src/events/client.rs | 4 +- .../admin_migrations/ops/mongodb/init.rs | 4 ++ .../admin_migrations/ops/mongodb/scripts.rs | 32 +++++++++++-- crates/core/database/src/models/mod.rs | 3 ++ .../database/src/models/policy_changes/mod.rs | 5 ++ .../src/models/policy_changes/model.rs | 20 ++++++++ .../database/src/models/policy_changes/ops.rs | 15 ++++++ .../src/models/policy_changes/ops/mongodb.rs | 46 +++++++++++++++++++ .../models/policy_changes/ops/reference.rs | 31 +++++++++++++ .../core/database/src/models/users/model.rs | 4 ++ crates/core/database/src/util/bridge/v0.rs | 13 ++++++ crates/core/files/Cargo.toml | 6 +-- crates/core/models/Cargo.toml | 6 +-- crates/core/models/src/v0/mod.rs | 2 + crates/core/models/src/v0/policy_changes.rs | 16 +++++++ crates/core/parser/Cargo.toml | 2 +- crates/core/permissions/Cargo.toml | 4 +- crates/core/presence/Cargo.toml | 2 +- crates/core/result/Cargo.toml | 2 +- crates/daemons/crond/Cargo.toml | 10 ++-- crates/daemons/pushd/Cargo.toml | 12 ++--- crates/delta/Cargo.toml | 2 +- crates/delta/src/routes/mod.rs | 3 ++ .../policy/acknowledge_policy_changes.rs | 17 +++++++ crates/delta/src/routes/policy/mod.rs | 11 +++++ crates/services/autumn/Cargo.toml | 10 ++-- crates/services/january/Cargo.toml | 10 ++-- 33 files changed, 298 insertions(+), 64 deletions(-) create mode 100644 crates/core/database/src/models/policy_changes/mod.rs create mode 100644 crates/core/database/src/models/policy_changes/model.rs create mode 100644 crates/core/database/src/models/policy_changes/ops.rs create mode 100644 crates/core/database/src/models/policy_changes/ops/mongodb.rs create mode 100644 crates/core/database/src/models/policy_changes/ops/reference.rs create mode 100644 crates/core/models/src/v0/policy_changes.rs create mode 100644 crates/delta/src/routes/policy/acknowledge_policy_changes.rs create mode 100644 crates/delta/src/routes/policy/mod.rs diff --git a/Cargo.lock b/Cargo.lock index 712754c9..f932a03c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5954,7 +5954,7 @@ dependencies = [ [[package]] name = "revolt-autumn" -version = "0.8.6" +version = "0.8.7" dependencies = [ "axum", "axum-macros", @@ -5991,7 +5991,7 @@ dependencies = [ [[package]] name = "revolt-bonfire" -version = "0.8.6" +version = "0.8.7" dependencies = [ "async-channel 2.3.1", "async-std", @@ -6021,7 +6021,7 @@ dependencies = [ [[package]] name = "revolt-config" -version = "0.8.6" +version = "0.8.7" dependencies = [ "async-std", "cached", @@ -6038,7 +6038,7 @@ dependencies = [ [[package]] name = "revolt-crond" -version = "0.8.6" +version = "0.8.7" dependencies = [ "log", "revolt-config", @@ -6050,7 +6050,7 @@ dependencies = [ [[package]] name = "revolt-database" -version = "0.8.6" +version = "0.8.7" dependencies = [ "amqprs", "async-lock 2.8.0", @@ -6100,7 +6100,7 @@ dependencies = [ [[package]] name = "revolt-delta" -version = "0.8.6" +version = "0.8.7" dependencies = [ "amqprs", "async-channel 1.9.0", @@ -6147,7 +6147,7 @@ dependencies = [ [[package]] name = "revolt-files" -version = "0.8.6" +version = "0.8.7" dependencies = [ "aes-gcm", "aws-config", @@ -6170,7 +6170,7 @@ dependencies = [ [[package]] name = "revolt-january" -version = "0.8.6" +version = "0.8.7" dependencies = [ "async-recursion", "axum", @@ -6198,7 +6198,7 @@ dependencies = [ [[package]] name = "revolt-models" -version = "0.8.6" +version = "0.8.7" dependencies = [ "indexmap 1.9.3", "iso8601-timestamp", @@ -6217,14 +6217,14 @@ dependencies = [ [[package]] name = "revolt-parser" -version = "0.8.6" +version = "0.8.7" dependencies = [ "logos", ] [[package]] name = "revolt-permissions" -version = "0.8.6" +version = "0.8.7" dependencies = [ "async-std", "async-trait", @@ -6239,7 +6239,7 @@ dependencies = [ [[package]] name = "revolt-presence" -version = "0.8.6" +version = "0.8.7" dependencies = [ "async-std", "log", @@ -6250,7 +6250,7 @@ dependencies = [ [[package]] name = "revolt-pushd" -version = "0.8.6" +version = "0.8.7" dependencies = [ "amqprs", "anyhow", @@ -6278,7 +6278,7 @@ dependencies = [ [[package]] name = "revolt-result" -version = "0.8.6" +version = "0.8.7" dependencies = [ "axum", "revolt_okapi", diff --git a/crates/bonfire/Cargo.toml b/crates/bonfire/Cargo.toml index 5a55f1aa..1f38becf 100644 --- a/crates/bonfire/Cargo.toml +++ b/crates/bonfire/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-bonfire" -version = "0.8.6" +version = "0.8.7" license = "AGPL-3.0-or-later" edition = "2021" @@ -41,7 +41,7 @@ revolt-result = { path = "../core/result" } revolt-models = { path = "../core/models" } revolt-config = { path = "../core/config" } revolt-database = { path = "../core/database" } -revolt-permissions = { version = "0.8.6", path = "../core/permissions" } +revolt-permissions = { version = "0.8.7", path = "../core/permissions" } revolt-presence = { path = "../core/presence", features = ["redis-is-patched"] } # redis diff --git a/crates/bonfire/src/events/impl.rs b/crates/bonfire/src/events/impl.rs index 62da6108..160e7c6c 100644 --- a/crates/bonfire/src/events/impl.rs +++ b/crates/bonfire/src/events/impl.rs @@ -100,6 +100,18 @@ impl State { let user = self.clone_user(); self.cache.is_bot = user.bot.is_some(); + // Fetch pending policy changes. + let policy_changes = if user.bot.is_some() { + vec![] + } else { + db.fetch_policy_changes() + .await? + .into_iter() + .filter(|policy| policy.created_time > user.last_acknowledged_policy_change) + .map(Into::into) + .collect() + }; + // Find all relationships to the user. let mut user_ids: HashSet = user .relations @@ -227,6 +239,7 @@ impl State { for channel in &channels { self.insert_subscription(channel.id().to_string()).await; } + Ok(EventV1::Ready { users: if fields.contains(&ReadyPayloadFields::Users) { Some(users) @@ -252,6 +265,8 @@ impl State { user_settings, channel_unreads: channel_unreads.map(|vec| vec.into_iter().map(Into::into).collect()), + + policy_changes, }) } diff --git a/crates/core/config/Cargo.toml b/crates/core/config/Cargo.toml index 02595ac9..7254866f 100644 --- a/crates/core/config/Cargo.toml +++ b/crates/core/config/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-config" -version = "0.8.6" +version = "0.8.7" edition = "2021" license = "MIT" authors = ["Paul Makles "] @@ -36,4 +36,4 @@ sentry = "0.31.5" sentry-anyhow = { version = "0.38.1", optional = true } # Core -revolt-result = { version = "0.8.6", path = "../result", optional = true } +revolt-result = { version = "0.8.7", path = "../result", optional = true } diff --git a/crates/core/database/Cargo.toml b/crates/core/database/Cargo.toml index 81b0224e..976d1384 100644 --- a/crates/core/database/Cargo.toml +++ b/crates/core/database/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-database" -version = "0.8.6" +version = "0.8.7" edition = "2021" license = "AGPL-3.0-or-later" authors = ["Paul Makles "] @@ -24,19 +24,19 @@ default = ["mongodb", "async-std-runtime", "tasks"] [dependencies] # Core -revolt-config = { version = "0.8.6", path = "../config", features = [ +revolt-config = { version = "0.8.7", path = "../config", features = [ "report-macros", ] } -revolt-result = { version = "0.8.6", path = "../result" } -revolt-models = { version = "0.8.6", path = "../models", features = [ +revolt-result = { version = "0.8.7", path = "../result" } +revolt-models = { version = "0.8.7", path = "../models", features = [ "validator", ] } -revolt-presence = { version = "0.8.6", path = "../presence" } -revolt-permissions = { version = "0.8.6", path = "../permissions", features = [ +revolt-presence = { version = "0.8.7", path = "../presence" } +revolt-permissions = { version = "0.8.7", path = "../permissions", features = [ "serde", "bson", ] } -revolt-parser = { version = "0.8.6", path = "../parser" } +revolt-parser = { version = "0.8.7", path = "../parser" } # Utility log = "0.4" diff --git a/crates/core/database/src/drivers/reference.rs b/crates/core/database/src/drivers/reference.rs index 9c51d422..ff18f253 100644 --- a/crates/core/database/src/drivers/reference.rs +++ b/crates/core/database/src/drivers/reference.rs @@ -4,8 +4,8 @@ use futures::lock::Mutex; use crate::{ Bot, Channel, ChannelCompositeKey, ChannelUnread, Emoji, File, FileHash, Invite, Member, - MemberCompositeKey, Message, RatelimitEvent, Report, Server, ServerBan, Snapshot, User, - UserSettings, Webhook, + MemberCompositeKey, Message, PolicyChange, RatelimitEvent, Report, Server, ServerBan, Snapshot, + User, UserSettings, Webhook, }; database_derived!( @@ -21,6 +21,7 @@ database_derived!( pub file_hashes: Arc>>, pub files: Arc>>, pub messages: Arc>>, + pub policy_changes: Arc>>, pub ratelimit_events: Arc>>, pub user_settings: Arc>>, pub users: Arc>>, diff --git a/crates/core/database/src/events/client.rs b/crates/core/database/src/events/client.rs index b35007cc..af480d5a 100644 --- a/crates/core/database/src/events/client.rs +++ b/crates/core/database/src/events/client.rs @@ -6,7 +6,7 @@ use revolt_models::v0::{ AppendMessage, Channel, ChannelUnread, Emoji, FieldsChannel, FieldsMember, FieldsMessage, FieldsRole, FieldsServer, FieldsUser, FieldsWebhook, Member, MemberCompositeKey, Message, PartialChannel, PartialMember, PartialMessage, PartialRole, PartialServer, PartialUser, - PartialWebhook, RemovalIntention, Report, Server, User, UserSettings, Webhook, + PartialWebhook, PolicyChange, RemovalIntention, Report, Server, User, UserSettings, Webhook, }; use crate::Database; @@ -62,6 +62,8 @@ pub enum EventV1 { user_settings: Option, #[serde(skip_serializing_if = "Option::is_none")] channel_unreads: Option>, + + policy_changes: Vec, }, /// Ping response diff --git a/crates/core/database/src/models/admin_migrations/ops/mongodb/init.rs b/crates/core/database/src/models/admin_migrations/ops/mongodb/init.rs index 00fe26b8..4a422cbb 100644 --- a/crates/core/database/src/models/admin_migrations/ops/mongodb/init.rs +++ b/crates/core/database/src/models/admin_migrations/ops/mongodb/init.rs @@ -64,6 +64,10 @@ pub async fn create_database(db: &MongoDb) { .await .expect("Failed to create user_settings collection."); + db.create_collection("policy_changes") + .await + .expect("Failed to create policy_changes collection."); + db.create_collection("safety_reports") .await .expect("Failed to create safety_reports collection."); diff --git a/crates/core/database/src/models/admin_migrations/ops/mongodb/scripts.rs b/crates/core/database/src/models/admin_migrations/ops/mongodb/scripts.rs index aafee066..0f58082a 100644 --- a/crates/core/database/src/models/admin_migrations/ops/mongodb/scripts.rs +++ b/crates/core/database/src/models/admin_migrations/ops/mongodb/scripts.rs @@ -5,10 +5,11 @@ use crate::{ bson::{doc, from_bson, from_document, to_document, Bson, DateTime, Document}, options::FindOptions, }, - AbstractChannels, AbstractServers, Channel, Invite, MongoDb, DISCRIMINATOR_SEARCH_SPACE, + AbstractChannels, AbstractServers, Channel, Invite, MongoDb, User, DISCRIMINATOR_SEARCH_SPACE, }; -use bson::oid::ObjectId; +use bson::{oid::ObjectId, to_bson}; use futures::StreamExt; +use iso8601_timestamp::Timestamp; use rand::seq::SliceRandom; use revolt_permissions::DEFAULT_WEBHOOK_PERMISSIONS; use revolt_result::{Error, ErrorType}; @@ -21,7 +22,7 @@ struct MigrationInfo { revision: i32, } -pub const LATEST_REVISION: i32 = 33; // MUST BE +1 to last migration +pub const LATEST_REVISION: i32 = 41; // MUST BE +1 to last migration pub async fn migrate_database(db: &MongoDb) { let migrations = db.col::("migrations"); @@ -1139,6 +1140,31 @@ pub async fn run_migrations(db: &MongoDb, revision: i32) -> i32 { .unwrap(); } + if revision <= 40 { + info!( + "Running migration [revision |> 40 / 30-05-2025]: Set last policy acknowlegement date to now and create policy changes collection." + ); + + db.db() + .create_collection("policy_changes") + .await + .expect("Failed to create policy_changes collection."); + + db.db() + .collection::("users") + .update_many( + doc! {}, + doc! { + "$set": { + "last_acknowledged_policy_change": to_bson(&Timestamp::now_utc()) + .expect("failed to serialise timestamp") + } + }, + ) + .await + .expect("failed to update users"); + } + // Reminder to update LATEST_REVISION when adding new migrations. LATEST_REVISION.max(revision) } diff --git a/crates/core/database/src/models/mod.rs b/crates/core/database/src/models/mod.rs index 671c7abb..181a30c0 100644 --- a/crates/core/database/src/models/mod.rs +++ b/crates/core/database/src/models/mod.rs @@ -8,6 +8,7 @@ mod emojis; mod file_hashes; mod files; mod messages; +mod policy_changes; mod ratelimit_events; mod safety_reports; mod safety_snapshots; @@ -27,6 +28,7 @@ pub use emojis::*; pub use file_hashes::*; pub use files::*; pub use messages::*; +pub use policy_changes::*; pub use ratelimit_events::*; pub use safety_reports::*; pub use safety_snapshots::*; @@ -51,6 +53,7 @@ pub trait AbstractDatabase: + file_hashes::AbstractAttachmentHashes + files::AbstractAttachments + messages::AbstractMessages + + policy_changes::AbstractPolicyChange + ratelimit_events::AbstractRatelimitEvents + safety_reports::AbstractReport + safety_snapshots::AbstractSnapshot diff --git a/crates/core/database/src/models/policy_changes/mod.rs b/crates/core/database/src/models/policy_changes/mod.rs new file mode 100644 index 00000000..4d801b73 --- /dev/null +++ b/crates/core/database/src/models/policy_changes/mod.rs @@ -0,0 +1,5 @@ +mod model; +mod ops; + +pub use model::*; +pub use ops::*; diff --git a/crates/core/database/src/models/policy_changes/model.rs b/crates/core/database/src/models/policy_changes/model.rs new file mode 100644 index 00000000..54109505 --- /dev/null +++ b/crates/core/database/src/models/policy_changes/model.rs @@ -0,0 +1,20 @@ +use iso8601_timestamp::Timestamp; + +auto_derived!( + /// Platform policy change + pub struct PolicyChange { + /// Unique Id + #[serde(rename = "_id")] + pub id: String, + + /// Time at which this policy was created + pub created_time: Timestamp, + /// Time at which this policy is effective + pub effective_time: Timestamp, + + /// Message shown to users + pub description: String, + /// URL with details about changes + pub url: String, + } +); diff --git a/crates/core/database/src/models/policy_changes/ops.rs b/crates/core/database/src/models/policy_changes/ops.rs new file mode 100644 index 00000000..2692a81f --- /dev/null +++ b/crates/core/database/src/models/policy_changes/ops.rs @@ -0,0 +1,15 @@ +use revolt_result::Result; + +use crate::PolicyChange; + +mod mongodb; +mod reference; + +#[async_trait] +pub trait AbstractPolicyChange: Sync + Send { + /// Fetch all policy changes + async fn fetch_policy_changes(&self) -> Result>; + + /// Acknowledge policy changes + async fn acknowledge_policy_changes(&self, user_id: &str) -> Result<()>; +} diff --git a/crates/core/database/src/models/policy_changes/ops/mongodb.rs b/crates/core/database/src/models/policy_changes/ops/mongodb.rs new file mode 100644 index 00000000..fb70646f --- /dev/null +++ b/crates/core/database/src/models/policy_changes/ops/mongodb.rs @@ -0,0 +1,46 @@ +use bson::to_bson; +use iso8601_timestamp::Timestamp; +use revolt_result::Result; + +use crate::MongoDb; +use crate::PolicyChange; +use crate::User; + +use super::AbstractPolicyChange; + +static COL: &str = "policy_changes"; + +#[async_trait] +impl AbstractPolicyChange for MongoDb { + /// Fetch all policy changes + async fn fetch_policy_changes(&self) -> Result> { + query!(self, find, COL, doc! {}) + } + + /// Acknowledge policy changes + async fn acknowledge_policy_changes(&self, user_id: &str) -> Result<()> { + let latest_policy = self + .fetch_policy_changes() + .await? + .into_iter() + .map(|policy| policy.created_time) + .max() + .unwrap_or(Timestamp::UNIX_EPOCH); + + self.col::("users") + .update_one( + doc! { + "_id": user_id + }, + doc! { + "$set": { + "last_acknowledged_policy_change": to_bson(&latest_policy) + .map_err(|_| create_database_error!("to_bson", "timestamp"))? + } + }, + ) + .await + .map(|_| ()) + .map_err(|_| create_database_error!("update_one", COL)) + } +} diff --git a/crates/core/database/src/models/policy_changes/ops/reference.rs b/crates/core/database/src/models/policy_changes/ops/reference.rs new file mode 100644 index 00000000..e9745e44 --- /dev/null +++ b/crates/core/database/src/models/policy_changes/ops/reference.rs @@ -0,0 +1,31 @@ +use iso8601_timestamp::Timestamp; +use revolt_result::Result; + +use crate::PolicyChange; +use crate::ReferenceDb; + +use super::AbstractPolicyChange; + +#[async_trait] +impl AbstractPolicyChange for ReferenceDb { + /// Fetch all policy changes + async fn fetch_policy_changes(&self) -> Result> { + let policy_changes = self.policy_changes.lock().await; + Ok(policy_changes.values().cloned().collect()) + } + + /// Acknowledge policy changes + async fn acknowledge_policy_changes(&self, user_id: &str) -> Result<()> { + let mut users = self.users.lock().await; + let user = users.get_mut(user_id).expect("user doesn't exist"); + user.last_acknowledged_policy_change = self + .fetch_policy_changes() + .await? + .into_iter() + .map(|policy| policy.created_time) + .max() + .unwrap_or(Timestamp::UNIX_EPOCH); + + Ok(()) + } +} diff --git a/crates/core/database/src/models/users/model.rs b/crates/core/database/src/models/users/model.rs index fc2866cf..0c2b6cee 100644 --- a/crates/core/database/src/models/users/model.rs +++ b/crates/core/database/src/models/users/model.rs @@ -57,6 +57,8 @@ auto_derived_partial!( /// Time until user is unsuspended #[serde(skip_serializing_if = "Option::is_none")] pub suspended_until: Option, + /// Last acknowledged policy change + pub last_acknowledged_policy_change: Timestamp, }, "PartialUser" ); @@ -178,6 +180,7 @@ impl Default for User { privileged: Default::default(), bot: Default::default(), suspended_until: Default::default(), + last_acknowledged_policy_change: Timestamp::UNIX_EPOCH, } } } @@ -200,6 +203,7 @@ impl User { id: account_id.into().unwrap_or_else(|| Ulid::new().to_string()), discriminator: User::find_discriminator(db, &username, None).await?, username, + last_acknowledged_policy_change: Timestamp::now_utc(), ..Default::default() }; diff --git a/crates/core/database/src/util/bridge/v0.rs b/crates/core/database/src/util/bridge/v0.rs index 12f7c8fc..f741144b 100644 --- a/crates/core/database/src/util/bridge/v0.rs +++ b/crates/core/database/src/util/bridge/v0.rs @@ -1,3 +1,4 @@ +use iso8601_timestamp::Timestamp; use revolt_models::v0::*; use revolt_permissions::{calculate_user_permissions, UserPermission}; @@ -597,6 +598,17 @@ impl From for crate::Masquerade { } } +impl From for PolicyChange { + fn from(value: crate::PolicyChange) -> Self { + PolicyChange { + created_time: value.created_time, + effective_time: value.effective_time, + description: value.description, + url: value.url, + } + } +} + impl From for Report { fn from(value: crate::Report) -> Self { Report { @@ -1188,6 +1200,7 @@ impl From for crate::User { privileged: value.privileged, bot: value.bot.map(Into::into), suspended_until: None, + last_acknowledged_policy_change: Timestamp::UNIX_EPOCH, } } } diff --git a/crates/core/files/Cargo.toml b/crates/core/files/Cargo.toml index 29cf897d..4dfadeed 100644 --- a/crates/core/files/Cargo.toml +++ b/crates/core/files/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-files" -version = "0.8.6" +version = "0.8.7" edition = "2021" license = "AGPL-3.0-or-later" authors = ["Paul Makles "] @@ -20,10 +20,10 @@ typenum = "1.17.0" aws-config = "1.5.5" aws-sdk-s3 = { version = "1.46.0", features = ["behavior-version-latest"] } -revolt-config = { version = "0.8.6", path = "../config", features = [ +revolt-config = { version = "0.8.7", path = "../config", features = [ "report-macros", ] } -revolt-result = { version = "0.8.6", path = "../result" } +revolt-result = { version = "0.8.7", path = "../result" } # image processing jxl-oxide = "0.8.1" diff --git a/crates/core/models/Cargo.toml b/crates/core/models/Cargo.toml index 691d37a5..6c9dcf80 100644 --- a/crates/core/models/Cargo.toml +++ b/crates/core/models/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-models" -version = "0.8.6" +version = "0.8.7" edition = "2021" license = "MIT" authors = ["Paul Makles "] @@ -20,8 +20,8 @@ default = ["serde", "partials", "rocket"] [dependencies] # Core -revolt-config = { version = "0.8.6", path = "../config" } -revolt-permissions = { version = "0.8.6", path = "../permissions" } +revolt-config = { version = "0.8.7", path = "../config" } +revolt-permissions = { version = "0.8.7", path = "../permissions" } # Utility regex = "1.11" diff --git a/crates/core/models/src/v0/mod.rs b/crates/core/models/src/v0/mod.rs index 78540e32..0468493b 100644 --- a/crates/core/models/src/v0/mod.rs +++ b/crates/core/models/src/v0/mod.rs @@ -7,6 +7,7 @@ mod embeds; mod emojis; mod files; mod messages; +mod policy_changes; mod safety_reports; mod server_bans; mod server_members; @@ -23,6 +24,7 @@ pub use embeds::*; pub use emojis::*; pub use files::*; pub use messages::*; +pub use policy_changes::*; pub use safety_reports::*; pub use server_bans::*; pub use server_members::*; diff --git a/crates/core/models/src/v0/policy_changes.rs b/crates/core/models/src/v0/policy_changes.rs new file mode 100644 index 00000000..267618de --- /dev/null +++ b/crates/core/models/src/v0/policy_changes.rs @@ -0,0 +1,16 @@ +use iso8601_timestamp::Timestamp; + +auto_derived!( + /// Platform policy change + pub struct PolicyChange { + /// Time at which this policy was created + pub created_time: Timestamp, + /// Time at which this policy is effective + pub effective_time: Timestamp, + + /// Message shown to users + pub description: String, + /// URL with details about changes + pub url: String, + } +); diff --git a/crates/core/parser/Cargo.toml b/crates/core/parser/Cargo.toml index 558997bf..3c0a15b5 100644 --- a/crates/core/parser/Cargo.toml +++ b/crates/core/parser/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-parser" -version = "0.8.6" +version = "0.8.7" edition = "2021" license = "AGPL-3.0-or-later" description = "Revolt Backend: Message Parser" diff --git a/crates/core/permissions/Cargo.toml b/crates/core/permissions/Cargo.toml index 886ed973..c4eb7262 100644 --- a/crates/core/permissions/Cargo.toml +++ b/crates/core/permissions/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-permissions" -version = "0.8.6" +version = "0.8.7" edition = "2021" license = "MIT" authors = ["Paul Makles "] @@ -21,7 +21,7 @@ async-std = { version = "1.8.0", features = ["attributes"] } [dependencies] # Core -revolt-result = { version = "0.8.6", path = "../result" } +revolt-result = { version = "0.8.7", path = "../result" } # Utility auto_ops = "0.3.0" diff --git a/crates/core/presence/Cargo.toml b/crates/core/presence/Cargo.toml index 5e101db0..7ecb776a 100644 --- a/crates/core/presence/Cargo.toml +++ b/crates/core/presence/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-presence" -version = "0.8.6" +version = "0.8.7" edition = "2021" license = "AGPL-3.0-or-later" authors = ["Paul Makles "] diff --git a/crates/core/result/Cargo.toml b/crates/core/result/Cargo.toml index cd314fb5..a0de339d 100644 --- a/crates/core/result/Cargo.toml +++ b/crates/core/result/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-result" -version = "0.8.6" +version = "0.8.7" edition = "2021" license = "MIT" authors = ["Paul Makles "] diff --git a/crates/daemons/crond/Cargo.toml b/crates/daemons/crond/Cargo.toml index 4c89f8bf..413a810e 100644 --- a/crates/daemons/crond/Cargo.toml +++ b/crates/daemons/crond/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-crond" -version = "0.8.6" +version = "0.8.7" license = "AGPL-3.0-or-later" authors = ["Paul Makles "] edition = "2021" @@ -16,7 +16,7 @@ log = "0.4" tokio = { version = "1" } # Core -revolt-database = { version = "0.8.6", path = "../../core/database" } -revolt-result = { version = "0.8.6", path = "../../core/result" } -revolt-config = { version = "0.8.6", path = "../../core/config" } -revolt-files = { version = "0.8.6", path = "../../core/files" } +revolt-database = { version = "0.8.7", path = "../../core/database" } +revolt-result = { version = "0.8.7", path = "../../core/result" } +revolt-config = { version = "0.8.7", path = "../../core/config" } +revolt-files = { version = "0.8.7", path = "../../core/files" } diff --git a/crates/daemons/pushd/Cargo.toml b/crates/daemons/pushd/Cargo.toml index 6696b213..7800c4fd 100644 --- a/crates/daemons/pushd/Cargo.toml +++ b/crates/daemons/pushd/Cargo.toml @@ -1,19 +1,19 @@ [package] name = "revolt-pushd" -version = "0.8.6" +version = "0.8.7" edition = "2021" license = "AGPL-3.0-or-later" [dependencies] -revolt-result = { version = "0.8.6", path = "../../core/result" } -revolt-config = { version = "0.8.6", path = "../../core/config", features = [ +revolt-result = { version = "0.8.7", path = "../../core/result" } +revolt-config = { version = "0.8.7", path = "../../core/config", features = [ "report-macros", ] } -revolt-database = { version = "0.8.6", path = "../../core/database" } -revolt-models = { version = "0.8.6", path = "../../core/models", features = [ +revolt-database = { version = "0.8.7", path = "../../core/database" } +revolt-models = { version = "0.8.7", path = "../../core/models", features = [ "validator", ] } -revolt-presence = { version = "0.8.6", path = "../../core/presence", features = [ +revolt-presence = { version = "0.8.7", path = "../../core/presence", features = [ "redis-is-patched", ] } diff --git a/crates/delta/Cargo.toml b/crates/delta/Cargo.toml index 4b79c107..5401223f 100644 --- a/crates/delta/Cargo.toml +++ b/crates/delta/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-delta" -version = "0.8.6" +version = "0.8.7" license = "AGPL-3.0-or-later" authors = ["Paul Makles "] edition = "2018" diff --git a/crates/delta/src/routes/mod.rs b/crates/delta/src/routes/mod.rs index 25ed460d..9643a365 100644 --- a/crates/delta/src/routes/mod.rs +++ b/crates/delta/src/routes/mod.rs @@ -9,6 +9,7 @@ mod channels; mod customisation; mod invites; mod onboard; +mod policy; mod push; mod root; mod safety; @@ -36,6 +37,7 @@ pub fn mount(config: Settings, mut rocket: Rocket) -> Rocket { "/auth/session" => rocket_authifier::routes::session::routes(), "/auth/mfa" => rocket_authifier::routes::mfa::routes(), "/onboard" => onboard::routes(), + "/policy" => policy::routes(), "/push" => push::routes(), "/sync" => sync::routes(), "/webhooks" => webhooks::routes() @@ -56,6 +58,7 @@ pub fn mount(config: Settings, mut rocket: Rocket) -> Rocket { "/auth/session" => rocket_authifier::routes::session::routes(), "/auth/mfa" => rocket_authifier::routes::mfa::routes(), "/onboard" => onboard::routes(), + "/policy" => policy::routes(), "/push" => push::routes(), "/sync" => sync::routes() }; diff --git a/crates/delta/src/routes/policy/acknowledge_policy_changes.rs b/crates/delta/src/routes/policy/acknowledge_policy_changes.rs new file mode 100644 index 00000000..062dc32c --- /dev/null +++ b/crates/delta/src/routes/policy/acknowledge_policy_changes.rs @@ -0,0 +1,17 @@ +use revolt_database::{events::client::EventV1, Database, Report, Snapshot, SnapshotContent, User}; +use revolt_models::v0::{ReportStatus, ReportedContent}; +use revolt_result::{create_error, Result}; +use serde::Deserialize; +use ulid::Ulid; +use validator::Validate; + +use rocket::{serde::json::Json, State}; + +/// # Acknowledge Policy Changes +/// +/// Accept/acknowledge changes to platform policy. +#[openapi(tag = "Policy")] +#[post("/acknowledge")] +pub async fn acknowledge_policy_changes(db: &State, user: User) -> Result<()> { + db.acknowledge_policy_changes(&user.id).await +} diff --git a/crates/delta/src/routes/policy/mod.rs b/crates/delta/src/routes/policy/mod.rs new file mode 100644 index 00000000..77831b1f --- /dev/null +++ b/crates/delta/src/routes/policy/mod.rs @@ -0,0 +1,11 @@ +use revolt_rocket_okapi::revolt_okapi::openapi3::OpenApi; +use rocket::Route; + +mod acknowledge_policy_changes; + +pub fn routes() -> (Vec, OpenApi) { + openapi_get_routes_spec![ + // Policy + acknowledge_policy_changes::acknowledge_policy_changes, + ] +} diff --git a/crates/services/autumn/Cargo.toml b/crates/services/autumn/Cargo.toml index eea5a707..36446c01 100644 --- a/crates/services/autumn/Cargo.toml +++ b/crates/services/autumn/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-autumn" -version = "0.8.6" +version = "0.8.7" edition = "2021" license = "AGPL-3.0-or-later" @@ -43,12 +43,12 @@ tracing = "0.1" tracing-subscriber = { version = "0.3", features = ["env-filter"] } # Core crates -revolt-files = { version = "0.8.6", path = "../../core/files" } -revolt-config = { version = "0.8.6", path = "../../core/config" } -revolt-database = { version = "0.8.6", path = "../../core/database", features = [ +revolt-files = { version = "0.8.7", path = "../../core/files" } +revolt-config = { version = "0.8.7", path = "../../core/config" } +revolt-database = { version = "0.8.7", path = "../../core/database", features = [ "axum-impl", ] } -revolt-result = { version = "0.8.6", path = "../../core/result", features = [ +revolt-result = { version = "0.8.7", path = "../../core/result", features = [ "utoipa", "axum", ] } diff --git a/crates/services/january/Cargo.toml b/crates/services/january/Cargo.toml index fedfae97..3566d2a0 100644 --- a/crates/services/january/Cargo.toml +++ b/crates/services/january/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "revolt-january" -version = "0.8.6" +version = "0.8.7" edition = "2021" license = "AGPL-3.0-or-later" @@ -32,13 +32,13 @@ tracing = "0.1" tracing-subscriber = { version = "0.3", features = ["env-filter"] } # Core crates -revolt-config = { version = "0.8.6", path = "../../core/config" } -revolt-models = { version = "0.8.6", path = "../../core/models" } -revolt-result = { version = "0.8.6", path = "../../core/result", features = [ +revolt-config = { version = "0.8.7", path = "../../core/config" } +revolt-models = { version = "0.8.7", path = "../../core/models" } +revolt-result = { version = "0.8.7", path = "../../core/result", features = [ "utoipa", "axum", ] } -revolt-files = { version = "0.8.6", path = "../../core/files" } +revolt-files = { version = "0.8.7", path = "../../core/files" } # Axum / web server axum = { version = "0.7.5" }