diff --git a/.github/workflows/docker_build.yml b/.github/workflows/docker_build.yml index 76dae163..4a29fd98 100644 --- a/.github/workflows/docker_build.yml +++ b/.github/workflows/docker_build.yml @@ -8,7 +8,7 @@ on: env: REGISTRY_GHCR: ghcr.io - GHCR_REPO: ghcr.io/${{ github.repository }} + GHCR_REPO: ghcr.io/discordanalytics/api jobs: build: @@ -40,6 +40,9 @@ jobs: - feature: none args: "--no-default-features" suffix: "" + permissions: + contents: read + packages: write steps: - name: Checkout repository @@ -58,16 +61,21 @@ jobs: username: ${{ github.actor }} password: ${{ secrets.GITHUB_TOKEN }} + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + - name: Build and Push by Digest id: build uses: docker/build-push-action@v6 with: context: . - file: docker/Dockerfile + file: Dockerfile build-args: BUILD_ARGS=${{ matrix.args }} platforms: ${{ matrix.platform }} labels: ${{ steps.meta.outputs.labels }} outputs: type=image,name=${{ env.GHCR_REPO }},push-by-digest=true,name-canonical=true,push=true + cache-from: type=registry,ref=${{ env.GHCR_REPO }}:cache-${{ matrix.feature }}-${{ matrix.arch }} + cache-to: type=registry,ref=${{ env.GHCR_REPO }}:cache-${{ matrix.feature }}-${{ matrix.arch }},mode=max - name: Export digest run: | @@ -98,6 +106,11 @@ jobs: suffix: "-reports" - feature: none suffix: "" + permissions: + contents: read + packages: write + pull-requests: write + steps: - name: Download digests uses: actions/download-artifact@v4 @@ -116,7 +129,13 @@ jobs: - name: Create manifest and push working-directory: /tmp/digests run: | - TAGS="-t ${{ env.GHCR_REPO }}:latest${{ matrix.suffix }}" + NORMALIZED_BRANCH=$(echo "${{ github.ref_name }}" | tr '/' '-' | tr '_' '-' | tr '[:upper:]' '[:lower:]') + + TAGS="-t ${{ env.GHCR_REPO }}:${NORMALIZED_BRANCH}${{ matrix.suffix }}" + + if [[ "$NORMALIZED_BRANCH" == "master" ]]; then + TAGS="$TAGS -t ${{ env.GHCR_REPO }}:latest${{ matrix.suffix }}" + fi if [[ "${{ github.event_name }}" == "release" ]]; then VERSION="${{ github.event.release.tag_name }}" @@ -128,4 +147,61 @@ jobs: fi docker buildx imagetools create $TAGS \ - $(printf '${{ env.GHCR_REPO }}@sha256:%s ' *) \ No newline at end of file + $(printf '${{ env.GHCR_REPO }}@sha256:%s ' *) + + notify: + runs-on: ubuntu-latest + needs: merge + if: github.event_name == 'workflow_dispatch' + permissions: + pull-requests: write + + steps: + - name: Post or update preview comment + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + REPO: ${{ github.repository }} + MARKER: "" + run: | + NORMALIZED_BRANCH=$(echo "${{ github.ref_name }}" | tr '/' '-' | tr '_' '-' | tr '[:upper:]' '[:lower:]') + BRANCH_DISPLAY="${{ github.ref_name }}" + + # Find the open PR for the current branch, if any + PR_NUMBER=$(gh api "repos/${REPO}/pulls" \ + --jq ".[] | select(.head.ref == \"${{ github.ref_name }}\" and .state == \"open\") | .number" \ + | head -n1) + + if [[ -z "$PR_NUMBER" ]]; then + echo "No open PR found for branch ${{ github.ref_name }}, skipping comment." + exit 0 + fi + BODY="${MARKER} + ## 🐳 Docker preview images are ready! + + Preview images are available for this PR: + + | Variant | Tag | + |---------|-----| + | Default | \`${{ env.GHCR_REPO }}:${NORMALIZED_BRANCH}\` | + | Full | \`${{ env.GHCR_REPO }}:${NORMALIZED_BRANCH}-full\` | + | Mails | \`${{ env.GHCR_REPO }}:${NORMALIZED_BRANCH}-mails\` | + | Reports | \`${{ env.GHCR_REPO }}:${NORMALIZED_BRANCH}-reports\` | + + > You can mention a maintainer to update it." + + # Look for an existing comment with the marker + EXISTING_ID=$(gh api \ + "repos/${REPO}/issues/${PR_NUMBER}/comments" \ + --paginate \ + --jq ".[] | select(.body | startswith(\"${MARKER}\")) | .id" \ + | head -n1) + + if [[ -n "$EXISTING_ID" ]]; then + gh api --method PATCH \ + "repos/${REPO}/issues/comments/${EXISTING_ID}" \ + -f body="$BODY" + else + gh api --method POST \ + "repos/${REPO}/issues/${PR_NUMBER}/comments" \ + -f body="$BODY" + fi \ No newline at end of file diff --git a/Cargo.lock b/Cargo.lock index efa6c75b..1176ffa7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -265,15 +265,6 @@ version = "0.2.21" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" -[[package]] -name = "android_system_properties" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" -dependencies = [ - "libc", -] - [[package]] name = "anyhow" version = "1.0.102" @@ -424,6 +415,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d9a7b350e3bb1767102698302bc37256cbd48422809984b98d292c40e2579aa9" dependencies = [ "aws-lc-sys", + "untrusted 0.7.1", "zeroize", ] @@ -439,24 +431,12 @@ dependencies = [ "fs_extra", ] -[[package]] -name = "base16ct" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" - [[package]] name = "base64" version = "0.22.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" -[[package]] -name = "base64ct" -version = "1.8.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2af50177e190e07a26ab74f8b1efbfe2ef87da2116221318cb1c2e82baf7de06" - [[package]] name = "bitflags" version = "2.11.0" @@ -595,10 +575,8 @@ version = "0.4.44" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c673075a2e0e5f4a1dde27ce9dee1ea4558c7ffe648f576438a20ca1d2acc4b0" dependencies = [ - "iana-time-zone", "num-traits", "serde", - "windows-link", ] [[package]] @@ -764,18 +742,6 @@ version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "460fbee9c2c2f33933d720630a6a0bac33ba7053db5344fac858d4b8952d77d5" -[[package]] -name = "crypto-bigint" -version = "0.5.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0dc92fb57ca44df6db8059111ab3af99a63d5d0f8375d9972e319a379c6bab76" -dependencies = [ - "generic-array", - "rand_core 0.6.4", - "subtle", - "zeroize", -] - [[package]] name = "crypto-common" version = "0.1.6" @@ -786,33 +752,6 @@ dependencies = [ "typenum", ] -[[package]] -name = "curve25519-dalek" -version = "4.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97fb8b7c4503de7d6ae7b42ab72a5a59857b4c937ec27a3d4539dba95b5ab2be" -dependencies = [ - "cfg-if", - "cpufeatures 0.2.17", - "curve25519-dalek-derive", - "digest", - "fiat-crypto", - "rustc_version", - "subtle", - "zeroize", -] - -[[package]] -name = "curve25519-dalek-derive" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.116", -] - [[package]] name = "darling" version = "0.20.11" @@ -889,17 +828,6 @@ version = "2.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d7a1e2f27636f116493b8b860f5546edb47c8d8f8ea73e1d2a20be88e28d1fea" -[[package]] -name = "der" -version = "0.7.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7c1832837b905bbfb5101e07cc24c8deddf52f93225eee6ead5f4d63d53ddcb" -dependencies = [ - "const-oid", - "pem-rfc7468", - "zeroize", -] - [[package]] name = "deranged" version = "0.5.6" @@ -1028,71 +956,12 @@ version = "1.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d0881ea181b1df73ff77ffaaf9c7544ecc11e82fba9b5f27b262a3c73a332555" -[[package]] -name = "ecdsa" -version = "0.16.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee27f32b5c5292967d2d4a9d7f1e0b0aed2c15daded5a60300e4abb9d8020bca" -dependencies = [ - "der", - "digest", - "elliptic-curve", - "rfc6979", - "signature", - "spki", -] - -[[package]] -name = "ed25519" -version = "2.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "115531babc129696a58c64a4fef0a8bf9e9698629fb97e9e40767d235cfbcd53" -dependencies = [ - "pkcs8", - "signature", -] - -[[package]] -name = "ed25519-dalek" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70e796c081cee67dc755e1a36a0a172b897fab85fc3f6bc48307991f64e4eca9" -dependencies = [ - "curve25519-dalek", - "ed25519", - "serde", - "sha2", - "subtle", - "zeroize", -] - [[package]] name = "either" version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" -[[package]] -name = "elliptic-curve" -version = "0.13.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5e6043086bf7973472e0c7dff2142ea0b680d30e18d9cc40f267efbf222bd47" -dependencies = [ - "base16ct", - "crypto-bigint", - "digest", - "ff", - "generic-array", - "group", - "hkdf", - "pem-rfc7468", - "pkcs8", - "rand_core 0.6.4", - "sec1", - "subtle", - "zeroize", -] - [[package]] name = "email-encoding" version = "0.4.1" @@ -1130,18 +999,6 @@ dependencies = [ "syn 2.0.116", ] -[[package]] -name = "enum_dispatch" -version = "0.3.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa18ce2bc66555b3218614519ac839ddb759a7d6720732f979ef8d13be147ecd" -dependencies = [ - "once_cell", - "proc-macro2", - "quote", - "syn 2.0.116", -] - [[package]] name = "equivalent" version = "1.0.2" @@ -1164,22 +1021,6 @@ version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" -[[package]] -name = "ff" -version = "0.13.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0b50bfb653653f9ca9095b427bed08ab8d75a137839d9ad64eb11810d5b6393" -dependencies = [ - "rand_core 0.6.4", - "subtle", -] - -[[package]] -name = "fiat-crypto" -version = "0.2.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28dea519a9695b9977216879a3ebfddf92f1c08c05d984f8996aecd6ecdc811d" - [[package]] name = "find-msvc-tools" version = "0.1.9" @@ -1252,7 +1093,6 @@ checksum = "8b147ee9d1f6d097cef9ce628cd2ee62288d963e16fb287bd9286455b241382d" dependencies = [ "futures-channel", "futures-core", - "futures-executor", "futures-io", "futures-sink", "futures-task", @@ -1321,7 +1161,6 @@ version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "389ca41296e6190b48053de0321d02a77f32f8a5d2461dd38762c0593805c6d6" dependencies = [ - "futures-channel", "futures-core", "futures-io", "futures-macro", @@ -1340,7 +1179,6 @@ checksum = "4bb6743198531e02858aeaea5398fcc883e71851fcbcb5a2f773e2fb6cb1edf2" dependencies = [ "typenum", "version_check", - "zeroize", ] [[package]] @@ -1384,17 +1222,6 @@ dependencies = [ "wasip3", ] -[[package]] -name = "group" -version = "0.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" -dependencies = [ - "ff", - "rand_core 0.6.4", - "subtle", -] - [[package]] name = "h2" version = "0.3.27" @@ -1516,15 +1343,6 @@ dependencies = [ "tracing", ] -[[package]] -name = "hkdf" -version = "0.12.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7b5f8eb2ad728638ea2c7d47a21db23b7b58a72ed6a38256b8a1849f15fbbdf7" -dependencies = [ - "hmac", -] - [[package]] name = "hmac" version = "0.12.1" @@ -1670,30 +1488,6 @@ dependencies = [ "tracing", ] -[[package]] -name = "iana-time-zone" -version = "0.1.65" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e31bc9ad994ba00e440a8aa5c9ef0ec67d5cb5e5cb0cc7f8b744a35b389cc470" -dependencies = [ - "android_system_properties", - "core-foundation-sys", - "iana-time-zone-haiku", - "js-sys", - "log", - "wasm-bindgen", - "windows-core", -] - -[[package]] -name = "iana-time-zone-haiku" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" -dependencies = [ - "cc", -] - [[package]] name = "icu_collections" version = "2.1.1" @@ -1917,15 +1711,11 @@ version = "10.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0529410abe238729a60b108898784df8984c87f6054c9c4fcacc47e4803c1ce1" dependencies = [ + "aws-lc-rs", "base64", - "ed25519-dalek", "getrandom 0.2.17", "hmac", "js-sys", - "p256", - "p384", - "rand 0.8.5", - "rsa", "serde", "serde_json", "sha2", @@ -1943,9 +1733,6 @@ name = "lazy_static" version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" -dependencies = [ - "spin", -] [[package]] name = "leb128fmt" @@ -1987,12 +1774,6 @@ version = "0.2.182" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6800badb6cb2082ffd7b6a67e6125bb39f18782f793520caee8cb8846be06112" -[[package]] -name = "libm" -version = "0.2.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6d2cec3eae94f9f509c767b45932f1ada8350c4bdb85af2fcab4a3c14807981" - [[package]] name = "linux-raw-sys" version = "0.12.1" @@ -2158,9 +1939,9 @@ dependencies = [ [[package]] name = "moka" -version = "0.12.13" +version = "0.12.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b4ac832c50ced444ef6be0767a008b02c106a909ba79d1d830501e94b96f6b7e" +checksum = "85f8024e1c8e71c778968af91d43700ce1d11b219d127d79fb2934153b82b42b" dependencies = [ "crossbeam-channel", "crossbeam-epoch", @@ -2193,9 +1974,9 @@ checksum = "224484c5d09285a7b8cb0a0c117e847ebd14cb6e4470ecf68cdb89c503b0edb9" [[package]] name = "mongodb" -version = "3.5.1" +version = "3.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "803dd859e8afa084c255a8effd8000ff86f7c8076a50cd6d8c99e8f3496f75c2" +checksum = "2c5941683db2ab2697f71e58dc0319024e808d3b28e7cf20f4bfb445fe54a30b" dependencies = [ "base64", "bitflags", @@ -2239,9 +2020,9 @@ dependencies = [ [[package]] name = "mongodb-internal-macros" -version = "3.5.1" +version = "3.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a973ef3dd3dbc6f6e65bbdecfd9ec5e781b9e7493b0f369a7c62e35d8e5ae2c8" +checksum = "47021a12bbf0dffde9c890fa2d36ff6ae342c532016226b04a42301b2b912660" dependencies = [ "macro_magic", "proc-macro2", @@ -2256,13 +2037,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8f2d4de127b05e0abf5bfe406ca8c766bb16e9150b040ff1525bccc20ee7c132" dependencies = [ "enum-as-inner", - "enum_dispatch", "htmlparser", "indexmap", "itertools", "rustc-hash", - "serde", - "serde_json", "thiserror 2.0.18", ] @@ -2307,48 +2085,12 @@ dependencies = [ "windows-sys 0.61.2", ] -[[package]] -name = "num-bigint-dig" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e661dda6640fad38e827a6d4a310ff4763082116fe217f279885c97f511bb0b7" -dependencies = [ - "lazy_static", - "libm", - "num-integer", - "num-iter", - "num-traits", - "rand 0.8.5", - "smallvec", - "zeroize", -] - [[package]] name = "num-conv" version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cf97ec579c3c42f953ef76dbf8d55ac91fb219dde70e49aa4a6b7d74e9919050" -[[package]] -name = "num-integer" -version = "0.1.46" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" -dependencies = [ - "num-traits", -] - -[[package]] -name = "num-iter" -version = "0.1.45" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1429034a0490724d0075ebb2bc9e875d6503c3cf69e235a8941aa757d83ef5bf" -dependencies = [ - "autocfg", - "num-integer", - "num-traits", -] - [[package]] name = "num-traits" version = "0.2.19" @@ -2356,7 +2098,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", - "libm", ] [[package]] @@ -2504,30 +2245,6 @@ dependencies = [ "thiserror 2.0.18", ] -[[package]] -name = "p256" -version = "0.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c9863ad85fa8f4460f9c48cb909d38a0d689dba1f6f6988a5e3e0d31071bcd4b" -dependencies = [ - "ecdsa", - "elliptic-curve", - "primeorder", - "sha2", -] - -[[package]] -name = "p384" -version = "0.13.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe42f1670a52a47d448f14b6a5c61dd78fce51856e68edaa38f7ae3a46b8d6b6" -dependencies = [ - "ecdsa", - "elliptic-curve", - "primeorder", - "sha2", -] - [[package]] name = "parking_lot" version = "0.12.5" @@ -2560,15 +2277,6 @@ dependencies = [ "digest", ] -[[package]] -name = "pem-rfc7468" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88b39c9bfcfc231068454382784bb460aae594343fb030d46e9f50a645418412" -dependencies = [ - "base64ct", -] - [[package]] name = "percent-encoding" version = "2.3.2" @@ -2607,27 +2315,6 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" -[[package]] -name = "pkcs1" -version = "0.7.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8ffb9f10fa047879315e6625af03c164b16962a5368d724ed16323b68ace47f" -dependencies = [ - "der", - "pkcs8", - "spki", -] - -[[package]] -name = "pkcs8" -version = "0.10.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" -dependencies = [ - "der", - "spki", -] - [[package]] name = "pkg-config" version = "0.3.32" @@ -2674,15 +2361,6 @@ dependencies = [ "syn 2.0.116", ] -[[package]] -name = "primeorder" -version = "0.13.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "353e1ca18966c16d9deb1c69278edbc5f194139612772bd9537af60ac231e1e6" -dependencies = [ - "elliptic-curve", -] - [[package]] name = "proc-macro-error" version = "1.0.4" @@ -2842,24 +2520,13 @@ version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" -[[package]] -name = "rand" -version = "0.8.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" -dependencies = [ - "libc", - "rand_chacha 0.3.1", - "rand_core 0.6.4", -] - [[package]] name = "rand" version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6db2770f06117d490610c7488547d543617b21bfa07796d7a12f6f1bd53850d1" dependencies = [ - "rand_chacha 0.9.0", + "rand_chacha", "rand_core 0.9.5", ] @@ -2874,16 +2541,6 @@ dependencies = [ "rand_core 0.10.0", ] -[[package]] -name = "rand_chacha" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" -dependencies = [ - "ppv-lite86", - "rand_core 0.6.4", -] - [[package]] name = "rand_chacha" version = "0.9.0" @@ -3083,16 +2740,6 @@ version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e061d1b48cb8d38042de4ae0a7a6401009d6143dc80d2e2d6f31f0bdd6470c7" -[[package]] -name = "rfc6979" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8dd2a808d456c4a54e300a23e9f5a67e122c3024119acbfd73e3bf664491cb2" -dependencies = [ - "hmac", - "subtle", -] - [[package]] name = "ring" version = "0.17.14" @@ -3103,30 +2750,10 @@ dependencies = [ "cfg-if", "getrandom 0.2.17", "libc", - "untrusted", + "untrusted 0.9.0", "windows-sys 0.52.0", ] -[[package]] -name = "rsa" -version = "0.9.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8573f03f5883dcaebdfcf4725caa1ecb9c15b2ef50c43a07b816e06799bb12d" -dependencies = [ - "const-oid", - "digest", - "num-bigint-dig", - "num-integer", - "num-traits", - "pkcs1", - "pkcs8", - "rand_core 0.6.4", - "signature", - "spki", - "subtle", - "zeroize", -] - [[package]] name = "rust_decimal" version = "1.40.0" @@ -3249,7 +2876,7 @@ dependencies = [ "aws-lc-rs", "ring", "rustls-pki-types", - "untrusted", + "untrusted 0.9.0", ] [[package]] @@ -3314,20 +2941,6 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" -[[package]] -name = "sec1" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc" -dependencies = [ - "base16ct", - "der", - "generic-array", - "pkcs8", - "subtle", - "zeroize", -] - [[package]] name = "security-framework" version = "3.6.0" @@ -3508,7 +3121,6 @@ version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" dependencies = [ - "digest", "rand_core 0.6.4", ] @@ -3556,22 +3168,6 @@ dependencies = [ "windows-sys 0.60.2", ] -[[package]] -name = "spin" -version = "0.9.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" - -[[package]] -name = "spki" -version = "0.7.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d" -dependencies = [ - "base64ct", - "der", -] - [[package]] name = "stable_deref_trait" version = "1.2.1" @@ -4083,6 +3679,12 @@ version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" +[[package]] +name = "untrusted" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" + [[package]] name = "untrusted" version = "0.9.0" @@ -4355,65 +3957,12 @@ dependencies = [ "windows-sys 0.61.2", ] -[[package]] -name = "windows-core" -version = "0.62.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8e83a14d34d0623b51dce9581199302a221863196a1dde71a7663a4c2be9deb" -dependencies = [ - "windows-implement", - "windows-interface", - "windows-link", - "windows-result", - "windows-strings", -] - -[[package]] -name = "windows-implement" -version = "0.60.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.116", -] - -[[package]] -name = "windows-interface" -version = "0.59.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.116", -] - [[package]] name = "windows-link" version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" -[[package]] -name = "windows-result" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7781fa89eaf60850ac3d2da7af8e5242a5ea78d1a11c49bf2910bb5a73853eb5" -dependencies = [ - "windows-link", -] - -[[package]] -name = "windows-strings" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7837d08f69c77cf6b07689544538e017c1bfcf57e34b4c0ff58e6c2cd3b37091" -dependencies = [ - "windows-link", -] - [[package]] name = "windows-sys" version = "0.45.0" diff --git a/Cargo.toml b/Cargo.toml index 8175e9ac..4db96901 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -29,24 +29,21 @@ path = "src/main.rs" [dependencies] actix-cors = { version = "0.7.1", default-features = false } -actix-web = { version = "4.13.0", default-features = false, features = [ - "macros", -] } +actix-web = { version = "4.13.0", default-features = false } actix-ws = { version = "0.4.0", default-features = false } -anyhow = { version = "1.0.102", default-features = false, features = ["std"] } -apistos = { version = "0.6.0", default-features = false, features = ["query"] } +anyhow = { version = "1.0.102", default-features = false } +apistos = { version = "0.6.0", default-features = false } chrono = { version = "0.4.44", default-features = false, features = [ - "clock", + "now", "serde", ] } dotenvy = { version = "0.15.7", default-features = false } -futures = { version = "0.3.32", default-features = false, features = [ - "alloc", - "executor", -] } -hex = { version = "0.4.3", default-features = false, features = ["alloc"] } +futures = { version = "0.3.32", default-features = false } +hex = { version = "0.4.3", default-features = false } jsonwebtoken = { version = "10.3.0", default-features = false, features = [ - "rust_crypto", + "aws_lc_rs", + "hmac", + "sha2", ] } lettre = { version = "0.11.19", optional = true, default-features = false, features = [ "builder", @@ -55,7 +52,7 @@ lettre = { version = "0.11.19", optional = true, default-features = false, featu "tokio1-native-tls", "pool", ] } -mongodb = { version = "3.5.1", default-features = false, features = [ +mongodb = { version = "3.5.2", default-features = false, features = [ "bson-3", "compat-3-3-0", "dns-resolver", @@ -64,19 +61,15 @@ mongodb = { version = "3.5.1", default-features = false, features = [ mrml = { version = "5.1.0", optional = true, default-features = false, features = [ "parse", "render", - "json", - "print", ] } opentelemetry-appender-tracing = { version = "0.31.1", optional = true, default-features = false } opentelemetry-otlp = { version = "0.31.0", optional = true, default-features = false, features = [ - "logs", "http-proto", + "logs", "reqwest-blocking-client", "reqwest-rustls", ] } -opentelemetry_sdk = { version = "0.31.0", optional = true, default-features = false, features = [ - "logs", -] } +opentelemetry_sdk = { version = "0.31.0", optional = true, default-features = false } regex = { version = "1.12.3", default-features = false, features = ["std"] } reqwest = { version = "0.13.2", default-features = false, features = [ "form", @@ -84,23 +77,13 @@ reqwest = { version = "0.13.2", default-features = false, features = [ "json", "rustls", ] } -ring = { version = "0.17.14", default-features = false, features = ["alloc"] } -s3 = { version = "0.1.22", optional = true, default-features = false, features = [ - "async", - "rustls", - "providers", -] } -schemars = { package = "apistos-schemars", version = "0.8.22", default-features = false, features = [ - "derive", - "schemars_derive", -] } -serde = { version = "1.0.228", default-features = false, features = ["derive"] } +ring = { version = "0.17.14", default-features = false } +s3 = { version = "0.1.22", optional = true, features = ["providers"] } +schemars = { package = "apistos-schemars", version = "0.8.22", default-features = false } +serde = { version = "1.0.228", default-features = false } serde_json = { version = "1.0.149", default-features = false } -tokio = { version = "1.50.0", default-features = false, features = [ - "rt-multi-thread", - "macros", -] } -tracing = { version = "0.1.44", default-features = false, features = ["std"] } +tokio = "1.50.0" +tracing = { version = "0.1.44", default-features = false } tracing-actix-web = { version = "0.7.21", default-features = false, features = [ "emit_event_on_error", ] } @@ -108,7 +91,6 @@ tracing-subscriber = { version = "0.3.23", default-features = false, features = "ansi", "env-filter", "fmt", - "std", ] } [profile.dev] diff --git a/Dockerfile b/Dockerfile index 6120526e..e6854363 100644 --- a/Dockerfile +++ b/Dockerfile @@ -29,14 +29,16 @@ FROM chef AS builder COPY --from=planner /app/recipe.json recipe.json -RUN cargo chef cook --release --recipe-path recipe.json +RUN cargo chef cook --release --all-features --recipe-path recipe.json COPY .cargo ./.cargo COPY Cargo.toml Cargo.lock ./ COPY src ./src -ARG BUILD_ARGS="--features=full" +# ── Final Build Stage ───── +FROM builder AS final-build +ARG BUILD_ARGS="--features=full" RUN cargo build --release ${BUILD_ARGS} --bin discord-analytics-api # ── Runtime Stage ───────── @@ -53,7 +55,7 @@ RUN apk add --no-cache libssl3 ca-certificates curl WORKDIR /app -COPY --from=builder /app/target/release/discord-analytics-api /usr/local/bin +COPY --from=final-build /app/target/release/discord-analytics-api /usr/local/bin EXPOSE 3001 diff --git a/src/api/routes/bots/bot/achievements/mod.rs b/src/api/routes/bots/bot/achievements/mod.rs index 902e63cb..2dba6b76 100644 --- a/src/api/routes/bots/bot/achievements/mod.rs +++ b/src/api/routes/bots/bot/achievements/mod.rs @@ -180,7 +180,6 @@ async fn create_achievement( &bot_id, &payload.description, &payload.title, - payload.editable, payload.objective, ); if let Some(description_i18n) = payload.description_i18n { @@ -438,7 +437,7 @@ async fn delete_achievement( ApiError::NotFound(format!("Achievement with ID {} not found", query.id)) })?; - if !achievement.editable { + if achievement.from.is_some() || achievement.shared { warn!( code = %LogCode::Forbidden, bot_id = %bot_id, diff --git a/src/api/routes/bots/bot/events/event/mod.rs b/src/api/routes/bots/bot/events/event/mod.rs index 8dafa846..52c21661 100644 --- a/src/api/routes/bots/bot/events/event/mod.rs +++ b/src/api/routes/bots/bot/events/event/mod.rs @@ -3,12 +3,12 @@ use apistos::{ api_operation, web::{ServiceConfig, delete, get, patch, resource, scope}, }; -use tracing::{info, warn}; +use tracing::{error, info, warn}; use crate::{ api::middleware::{Authenticated, Snowflake}, domain::error::{ApiError, ApiResult}, - openapi::schemas::{CustomEventBody, CustomEventResponse, MessageResponse}, + openapi::schemas::{CustomEventResponse, CustomEventUpdatePayload, MessageResponse}, repository::{CustomEventUpdate, Repositories}, services::Services, utils::logger::LogCode, @@ -114,7 +114,7 @@ async fn update_event( auth: Authenticated, services: Data, repos: Data, - body: Json, + body: Json, path: Path<(String, String)>, ) -> ApiResult> { let (bot_id, event_key) = path.into_inner(); @@ -196,9 +196,7 @@ async fn update_event( let body = body.into_inner(); - let updates = CustomEventUpdate::new() - .with_event_key(&body.event_key) - .with_graph_name(&body.graph_name); + let updates = CustomEventUpdate::new().with_graph_name(&body.graph_name); let update_result = repos .custom_events @@ -316,6 +314,20 @@ async fn delete_event( ))); } + if let Err(e) = repos + .bot_stats + .remove_event_from_stats(&bot_id, &event_key) + .await + { + error!( + code = %LogCode::System, + bot_id = %bot_id, + event_key = %event_key, + "Failed to remove event from bot stats: {}", + e, + ); + } + info!( code = %LogCode::Request, bot_id = %bot_id, diff --git a/src/domain/models/achievement.rs b/src/domain/models/achievement.rs index 4b895325..cd973b0c 100644 --- a/src/domain/models/achievement.rs +++ b/src/domain/models/achievement.rs @@ -13,7 +13,6 @@ pub struct Achievement { pub current: Option, pub description: String, pub description_i18n: Option, - pub editable: bool, pub from: Option, pub lang: Option, pub objective: AchievementObjective, @@ -28,7 +27,6 @@ impl Achievement { bot_id: &str, description: &str, title: &str, - editable: bool, objective: AchievementObjective, ) -> Self { Self { @@ -38,7 +36,6 @@ impl Achievement { current: None, description: description.to_owned(), description_i18n: None, - editable, from: None, lang: None, objective, @@ -83,7 +80,6 @@ impl Achievement { "pages.dashboard.bots.achievements.default_achievements.1.description" .to_owned(), ), - editable: false, from: Some("DiscordAnalytics".to_owned()), lang: None, objective: AchievementObjective { @@ -108,7 +104,6 @@ impl Achievement { "pages.dashboard.bots.achievements.default_achievements.2.description" .to_owned(), ), - editable: true, from: Some("DiscordAnalytics".to_owned()), lang: None, objective: AchievementObjective { @@ -132,7 +127,6 @@ impl Achievement { "pages.dashboard.bots.achievements.default_achievements.3.description" .to_owned(), ), - editable: false, from: Some("DiscordAnalytics".to_owned()), lang: None, objective: AchievementObjective { @@ -156,7 +150,6 @@ impl Achievement { "pages.dashboard.bots.achievements.default_achievements.4.description" .to_owned(), ), - editable: true, from: Some("DiscordAnalytics".to_owned()), lang: None, objective: AchievementObjective { @@ -180,7 +173,6 @@ impl Achievement { "pages.dashboard.bots.achievements.default_achievements.5.description" .to_owned(), ), - editable: false, from: Some("DiscordAnalytics".to_owned()), lang: None, objective: AchievementObjective { @@ -204,7 +196,6 @@ impl Achievement { "pages.dashboard.bots.achievements.default_achievements.6.description" .to_owned(), ), - editable: true, from: Some("DiscordAnalytics".to_owned()), lang: None, objective: AchievementObjective { @@ -228,7 +219,6 @@ impl Achievement { "pages.dashboard.bots.achievements.default_achievements.7.description" .to_owned(), ), - editable: true, from: Some("DiscordAnalytics".to_owned()), lang: None, objective: AchievementObjective { @@ -253,7 +243,6 @@ impl Achievement { "pages.dashboard.bots.achievements.default_achievements.8.description" .to_owned(), ), - editable: true, from: Some("DiscordAnalytics".to_owned()), lang: None, objective: AchievementObjective { @@ -277,7 +266,6 @@ impl Achievement { "pages.dashboard.bots.achievements.default_achievements.9.description" .to_owned(), ), - editable: true, from: Some("DiscordAnalytics".to_owned()), lang: None, objective: AchievementObjective { @@ -303,7 +291,6 @@ impl Achievement { ), from: Some("DiscordAnalytics".to_owned()), lang: None, - editable: true, objective: AchievementObjective { achievement_type: AchievementType::UserCount, value: 1000000, @@ -325,7 +312,6 @@ impl Achievement { "pages.dashboard.bots.achievements.default_achievements.11.description" .to_owned(), ), - editable: true, from: Some("DiscordAnalytics".to_owned()), lang: None, objective: AchievementObjective { @@ -350,7 +336,6 @@ impl Achievement { "pages.dashboard.bots.achievements.default_achievements.12.description" .to_owned(), ), - editable: true, from: Some("DiscordAnalytics".to_owned()), lang: None, objective: AchievementObjective { @@ -375,7 +360,6 @@ impl Achievement { "pages.dashboard.bots.achievements.default_achievements.13.description" .to_owned(), ), - editable: true, from: Some("DiscordAnalytics".to_owned()), lang: None, objective: AchievementObjective { @@ -399,7 +383,6 @@ impl Achievement { "pages.dashboard.bots.achievements.default_achievements.14.description" .to_owned(), ), - editable: true, from: Some("DiscordAnalytics".to_owned()), lang: None, objective: AchievementObjective { @@ -423,7 +406,6 @@ impl Achievement { "pages.dashboard.bots.achievements.default_achievements.15.description" .to_owned(), ), - editable: false, from: Some("DiscordAnalytics".to_owned()), lang: None, objective: AchievementObjective { @@ -458,7 +440,6 @@ impl Achievement { title_i18n: Some( "pages.dashboard.bots.achievements.default_achievements.16.title".to_owned(), ), - editable: true, used_by: 0, }, Self { @@ -471,7 +452,6 @@ impl Achievement { "pages.dashboard.bots.achievements.default_achievements.17.description" .to_owned(), ), - editable: true, from: Some("DiscordAnalytics".to_owned()), lang: None, objective: AchievementObjective { @@ -495,7 +475,6 @@ impl Achievement { "pages.dashboard.bots.achievements.default_achievements.18.description" .to_owned(), ), - editable: true, from: Some("DiscordAnalytics".to_owned()), lang: None, objective: AchievementObjective { diff --git a/src/openapi/schemas/achievement.rs b/src/openapi/schemas/achievement.rs index 55990856..98950cf2 100644 --- a/src/openapi/schemas/achievement.rs +++ b/src/openapi/schemas/achievement.rs @@ -12,7 +12,6 @@ pub struct AchievementResponse { pub current: Option, pub description: String, pub description_i18n: Option, - pub editable: bool, pub lang: Option, pub objective: AchievementObjective, pub shared: bool, @@ -37,7 +36,6 @@ impl TryFrom for AchievementResponse { current: achievement.current, description: achievement.description, description_i18n: achievement.description_i18n, - editable: achievement.editable, lang: achievement.lang, objective: achievement.objective, shared: achievement.shared, @@ -53,7 +51,6 @@ impl TryFrom for AchievementResponse { pub struct AchievementCreationPayload { pub description: String, pub description_i18n: Option, - pub editable: bool, pub from: Option, pub objective: AchievementObjective, pub shared: Option, diff --git a/src/openapi/schemas/custom_event.rs b/src/openapi/schemas/custom_event.rs index 74dc6e33..21b2032a 100644 --- a/src/openapi/schemas/custom_event.rs +++ b/src/openapi/schemas/custom_event.rs @@ -29,3 +29,9 @@ pub struct CustomEventBody { pub event_key: String, pub graph_name: String, } + +#[derive(Deserialize, Serialize, Clone, ApiComponent, JsonSchema)] +#[serde(rename_all = "camelCase")] +pub struct CustomEventUpdatePayload { + pub graph_name: String, +} diff --git a/src/openapi/schemas/mod.rs b/src/openapi/schemas/mod.rs index 5496ef95..3a45204c 100644 --- a/src/openapi/schemas/mod.rs +++ b/src/openapi/schemas/mod.rs @@ -34,7 +34,7 @@ pub use bot::{ pub use bot_stat::{ BotStatsBody, BotStatsContent, BotStatsQuery, BotStatsResponse, NormalizedStatsBody, }; -pub use custom_event::{CustomEventBody, CustomEventResponse}; +pub use custom_event::{CustomEventBody, CustomEventResponse, CustomEventUpdatePayload}; pub use health::HealthResponse; pub use integrations::TopGGIntegrationPayload; pub use invitation::{ diff --git a/src/repository/bot_stats.rs b/src/repository/bot_stats.rs index 6378b99d..2605dbb1 100644 --- a/src/repository/bot_stats.rs +++ b/src/repository/bot_stats.rs @@ -382,6 +382,16 @@ impl BotStatsRepository { .await } + pub async fn remove_event_from_stats(&self, bot_id: &str, event_key: &str) -> Result<()> { + let field = format!("customEvents.{}", event_key); + + self.collection + .update_many(doc! { "botId": bot_id }, doc! { "$unset": { field: "" } }) + .await?; + + Ok(()) + } + pub async fn delete_by_bot_id(&self, bot_id: &str) -> Result { self.collection.delete_many(doc! { "botId": bot_id }).await } diff --git a/src/utils/mail/templates/bot_token_regen.mjml b/src/utils/mail/templates/bot_token_regen.mjml index b0eca4b7..382da13f 100644 --- a/src/utils/mail/templates/bot_token_regen.mjml +++ b/src/utils/mail/templates/bot_token_regen.mjml @@ -7,7 +7,7 @@ Dear {{user_username}},
- The token of your bot {{bot_username}} ({{bot_id}}) has been regenerated. Please make sure to update your bot's token in your code to continue using our services without interruption.
+ The token of your bot {{bot_username}} ({{bot_id}}) has been regenerated. Please make sure to update your bot's token in your code to continue using our services. You can access the new token in your bot's dashboard. If you have any problems with the new token, please refer to our documentation or contact us!