mirror of
https://forgejo.ellis.link/continuwuation/continuwuity.git
synced 2026-05-26 20:49:55 +00:00
Compare commits
50 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 2325e8fa4c | |||
| 6906d63013 | |||
| 16de2a2cc0 | |||
| 108a4fe336 | |||
| 83396db5de | |||
| 839138c02e | |||
| e03c90c2ac | |||
| 379ef5014c | |||
| 2ab177f100 | |||
| a818f51396 | |||
| 09bfe79a44 | |||
| d041adadc8 | |||
| 189ed1c394 | |||
| 36c32938ae | |||
| 915643c965 | |||
| 4063b2c7da | |||
| 943bd81ce9 | |||
| 2942d9133e | |||
| 18a7a85fe4 | |||
| 0fdb1be938 | |||
| 867a3ac376 | |||
| 7a6eff091a | |||
| c278663f65 | |||
| c822c945e7 | |||
| 6eb3dc1f9d | |||
| 789ec71b75 | |||
| 1cfa3ff10b | |||
| 02cf6b5695 | |||
| 4cc4893376 | |||
| 7643b64f60 | |||
| 3d9fd34012 | |||
| 630963d6e1 | |||
| 36da6f5bf3 | |||
| 462ef63945 | |||
| 46bcfe5605 | |||
| 16321cf467 | |||
| 4d59e07006 | |||
| ec5f50c68e | |||
| db1b08532e | |||
| d8f67e3b46 | |||
| 2124fcf325 | |||
| 38b4065270 | |||
| 2e62ca93a8 | |||
| b7a6c819b7 | |||
| eccc878ee9 | |||
| 8b762cf2e6 | |||
| 1ce9ae2cbf | |||
| 6a3370005e | |||
| 675cfb964a | |||
| 09312791a7 |
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
dotenv_if_exists
|
dotenv_if_exists
|
||||||
|
|
||||||
if [ -f /etc/os-release ] && grep -q '^ID=nixos' /etc/os-release; then
|
if command -v nix >/dev/null 2>&1; then
|
||||||
use flake ".#${DIRENV_DEVSHELL:-default}"
|
use flake ".#${DIRENV_DEVSHELL:-default}"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|||||||
@@ -149,37 +149,6 @@ runs:
|
|||||||
- name: Setup sccache
|
- name: Setup sccache
|
||||||
uses: https://git.tomfos.tr/tom/sccache-action@v1
|
uses: https://git.tomfos.tr/tom/sccache-action@v1
|
||||||
|
|
||||||
- name: Cache dependencies
|
|
||||||
id: deps-cache
|
|
||||||
uses: actions/cache@v4
|
|
||||||
with:
|
|
||||||
path: |
|
|
||||||
target/**/.fingerprint
|
|
||||||
target/**/deps
|
|
||||||
target/**/*.d
|
|
||||||
target/**/.cargo-lock
|
|
||||||
target/**/CACHEDIR.TAG
|
|
||||||
target/**/.rustc_info.json
|
|
||||||
/timelord/
|
|
||||||
# Dependencies cache - based on Cargo.lock, survives source code changes
|
|
||||||
key: >-
|
|
||||||
continuwuity-deps-${{ steps.runner-os.outputs.slug }}-${{ steps.runner-os.outputs.arch }}-${{ steps.rust-setup.outputs.version }}${{ inputs.cache-key-suffix && format('-{0}', inputs.cache-key-suffix) || '' }}-${{ hashFiles('rust-toolchain.toml', '**/Cargo.lock') }}
|
|
||||||
restore-keys: |
|
|
||||||
continuwuity-deps-${{ steps.runner-os.outputs.slug }}-${{ steps.runner-os.outputs.arch }}-${{ steps.rust-setup.outputs.version }}${{ inputs.cache-key-suffix && format('-{0}', inputs.cache-key-suffix) || '' }}-
|
|
||||||
|
|
||||||
- name: Cache incremental compilation
|
|
||||||
id: incremental-cache
|
|
||||||
uses: actions/cache@v4
|
|
||||||
with:
|
|
||||||
path: |
|
|
||||||
target/**/incremental
|
|
||||||
# Incremental cache - based on source code changes
|
|
||||||
key: >-
|
|
||||||
continuwuity-incremental-${{ steps.runner-os.outputs.slug }}-${{ steps.runner-os.outputs.arch }}-${{ steps.rust-setup.outputs.version }}${{ inputs.cache-key-suffix && format('-{0}', inputs.cache-key-suffix) || '' }}-${{ hashFiles('rust-toolchain.toml', '**/Cargo.lock') }}-${{ hashFiles('**/*.rs', '**/Cargo.toml') }}
|
|
||||||
restore-keys: |
|
|
||||||
continuwuity-incremental-${{ steps.runner-os.outputs.slug }}-${{ steps.runner-os.outputs.arch }}-${{ steps.rust-setup.outputs.version }}${{ inputs.cache-key-suffix && format('-{0}', inputs.cache-key-suffix) || '' }}-${{ hashFiles('rust-toolchain.toml', '**/Cargo.lock') }}-
|
|
||||||
continuwuity-incremental-${{ steps.runner-os.outputs.slug }}-${{ steps.runner-os.outputs.arch }}-${{ steps.rust-setup.outputs.version }}${{ inputs.cache-key-suffix && format('-{0}', inputs.cache-key-suffix) || '' }}-
|
|
||||||
|
|
||||||
- name: End build cache restore group
|
- name: End build cache restore group
|
||||||
shell: bash
|
shell: bash
|
||||||
run: echo "::endgroup::"
|
run: echo "::endgroup::"
|
||||||
|
|||||||
@@ -16,48 +16,19 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v6
|
- uses: actions/checkout@v6
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
|
||||||
fetch-tags: false
|
|
||||||
fetch-single-branch: true
|
|
||||||
submodules: false
|
|
||||||
persist-credentials: true
|
persist-credentials: true
|
||||||
token: ${{ secrets.FORGEJO_TOKEN }}
|
token: ${{ secrets.FORGEJO_TOKEN }}
|
||||||
|
|
||||||
- uses: https://github.com/cachix/install-nix-action@19effe9fe722874e6d46dd7182e4b8b7a43c4a99 # v31.10.0
|
- name: Install Lix
|
||||||
|
uses: https://github.com/samueldr/lix-gha-installer-action@f5e94192f565f53d84f41a056956dc0d3183b343
|
||||||
with:
|
with:
|
||||||
nix_path: nixpkgs=channel:nixos-unstable
|
extra_nix_config: experimental-features = nix-command flakes flake-self-attrs
|
||||||
|
|
||||||
# We can skip getting a toolchain hash if this was ran as a dispatch with the intent
|
|
||||||
# to update just the rocksdb hash. If this was ran as a dispatch and the toolchain
|
|
||||||
# files are changed, we still update them, as well as the rocksdb import.
|
|
||||||
- name: Detect changed files
|
|
||||||
id: changes
|
|
||||||
run: |
|
|
||||||
git fetch origin ${{ github.base_ref }} --depth=1 || true
|
|
||||||
if [ -n "${{ github.event.pull_request.base.sha }}" ]; then
|
|
||||||
base=${{ github.event.pull_request.base.sha }}
|
|
||||||
else
|
|
||||||
base=$(git rev-parse HEAD~1)
|
|
||||||
fi
|
|
||||||
echo "Base: $base"
|
|
||||||
echo "HEAD: $(git rev-parse HEAD)"
|
|
||||||
git diff --name-only $base HEAD > changed_files.txt
|
|
||||||
echo "detected changes in $(cat changed_files.txt)"
|
|
||||||
# Join files with commas
|
|
||||||
files=$(paste -sd, changed_files.txt)
|
|
||||||
echo "files=$files" >> $FORGEJO_OUTPUT
|
|
||||||
|
|
||||||
- name: Debug output
|
|
||||||
run: |
|
|
||||||
echo "State of output"
|
|
||||||
echo "Changed files: ${{ steps.changes.outputs.files }}"
|
|
||||||
|
|
||||||
- name: Get new toolchain hash
|
- name: Get new toolchain hash
|
||||||
if: contains(steps.changes.outputs.files, 'Cargo.toml') || contains(steps.changes.outputs.files, 'Cargo.lock') || contains(steps.changes.outputs.files, 'rust-toolchain.toml')
|
|
||||||
run: |
|
run: |
|
||||||
# Set the current sha256 to an empty hash to make `nix build` calculate a new one
|
# Set the current sha256 to an empty hash to make `nix build` calculate a new one
|
||||||
awk '/fromToolchainFile *\{/{found=1; print; next} found && /sha256 =/{sub(/sha256 = .*/, "sha256 = lib.fakeSha256;"); found=0} 1' nix/packages/rust.nix > temp.nix
|
awk '/fromToolchainFile *\{/{found=1; print; next} found && /sha256 =/{sub(/sha256 = .*/, "sha256 = lib.fakeSha256;"); found=0} 1' nix/rust.nix > temp.nix
|
||||||
mv temp.nix nix/packages/rust.nix
|
mv temp.nix nix/rust.nix
|
||||||
|
|
||||||
# Build continuwuity and filter for the new hash
|
# Build continuwuity and filter for the new hash
|
||||||
# We do `|| true` because we want this to fail without stopping the workflow
|
# We do `|| true` because we want this to fail without stopping the workflow
|
||||||
@@ -65,36 +36,17 @@ jobs:
|
|||||||
|
|
||||||
# Place the new hash in place of the empty hash
|
# Place the new hash in place of the empty hash
|
||||||
new_hash=$(cat new_toolchain_hash.txt)
|
new_hash=$(cat new_toolchain_hash.txt)
|
||||||
sed -i "s|lib.fakeSha256|\"$new_hash\"|" nix/packages/rust.nix
|
sed -i "s|lib.fakeSha256|\"$new_hash\"|" nix/rust.nix
|
||||||
|
|
||||||
echo "New hash:"
|
echo "New hash:"
|
||||||
awk -F'"' '/fromToolchainFile/{found=1; next} found && /sha256 =/{print $2; found=0}' nix/packages/rust.nix
|
awk -F'"' '/fromToolchainFile/{found=1; next} found && /sha256 =/{print $2; found=0}' nix/rust.nix
|
||||||
echo "Expected new hash:"
|
echo "Expected new hash:"
|
||||||
cat new_toolchain_hash.txt
|
cat new_toolchain_hash.txt
|
||||||
|
|
||||||
rm new_toolchain_hash.txt
|
rm new_toolchain_hash.txt
|
||||||
|
|
||||||
- name: Get new rocksdb hash
|
- name: Update rocksdb
|
||||||
if: contains(steps.changes.outputs.files, '.nix') || contains(steps.changes.outputs.files, 'flake.lock')
|
run: nix run .#update-rocksdb
|
||||||
run: |
|
|
||||||
# Set the current sha256 to an empty hash to make `nix build` calculate a new one
|
|
||||||
awk '/repo = "rocksdb";/{found=1; print; next} found && /sha256 =/{sub(/sha256 = .*/, "sha256 = lib.fakeSha256;"); found=0} 1' nix/packages/rocksdb/package.nix > temp.nix
|
|
||||||
mv temp.nix nix/packages/rocksdb/package.nix
|
|
||||||
|
|
||||||
# Build continuwuity and filter for the new hash
|
|
||||||
# We do `|| true` because we want this to fail without stopping the workflow
|
|
||||||
nix build .#default 2>&1 | tee >(grep 'got:' | awk '{print $2}' > new_rocksdb_hash.txt) || true
|
|
||||||
|
|
||||||
# Place the new hash in place of the empty hash
|
|
||||||
new_hash=$(cat new_rocksdb_hash.txt)
|
|
||||||
sed -i "s|lib.fakeSha256|\"$new_hash\"|" nix/packages/rocksdb/package.nix
|
|
||||||
|
|
||||||
echo "New hash:"
|
|
||||||
awk -F'"' '/repo = "rocksdb";/{found=1; next} found && /sha256 =/{print $2; found=0}' nix/packages/rocksdb/package.nix
|
|
||||||
echo "Expected new hash:"
|
|
||||||
cat new_rocksdb_hash.txt
|
|
||||||
|
|
||||||
rm new_rocksdb_hash.txt
|
|
||||||
|
|
||||||
- name: Show diff
|
- name: Show diff
|
||||||
run: git diff flake.nix nix
|
run: git diff flake.nix nix
|
||||||
|
|||||||
Generated
+27
-14
@@ -948,10 +948,12 @@ dependencies = [
|
|||||||
"conduwuit_build_metadata",
|
"conduwuit_build_metadata",
|
||||||
"conduwuit_core",
|
"conduwuit_core",
|
||||||
"conduwuit_database",
|
"conduwuit_database",
|
||||||
|
"conduwuit_macros",
|
||||||
"conduwuit_router",
|
"conduwuit_router",
|
||||||
"conduwuit_service",
|
"conduwuit_service",
|
||||||
"console-subscriber",
|
"console-subscriber",
|
||||||
"const-str",
|
"const-str",
|
||||||
|
"ctor",
|
||||||
"hardened_malloc-rs",
|
"hardened_malloc-rs",
|
||||||
"log",
|
"log",
|
||||||
"opentelemetry",
|
"opentelemetry",
|
||||||
@@ -981,6 +983,7 @@ dependencies = [
|
|||||||
"conduwuit_macros",
|
"conduwuit_macros",
|
||||||
"conduwuit_service",
|
"conduwuit_service",
|
||||||
"const-str",
|
"const-str",
|
||||||
|
"ctor",
|
||||||
"futures",
|
"futures",
|
||||||
"lettre",
|
"lettre",
|
||||||
"log",
|
"log",
|
||||||
@@ -1003,8 +1006,10 @@ dependencies = [
|
|||||||
"base64 0.22.1",
|
"base64 0.22.1",
|
||||||
"bytes",
|
"bytes",
|
||||||
"conduwuit_core",
|
"conduwuit_core",
|
||||||
|
"conduwuit_macros",
|
||||||
"conduwuit_service",
|
"conduwuit_service",
|
||||||
"const-str",
|
"const-str",
|
||||||
|
"ctor",
|
||||||
"futures",
|
"futures",
|
||||||
"hmac",
|
"hmac",
|
||||||
"http",
|
"http",
|
||||||
@@ -1030,6 +1035,7 @@ name = "conduwuit_build_metadata"
|
|||||||
version = "0.5.7-alpha.1"
|
version = "0.5.7-alpha.1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"built",
|
"built",
|
||||||
|
"cargo_metadata",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@@ -1102,7 +1108,9 @@ version = "0.5.7-alpha.1"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"async-channel",
|
"async-channel",
|
||||||
"conduwuit_core",
|
"conduwuit_core",
|
||||||
|
"conduwuit_macros",
|
||||||
"const-str",
|
"const-str",
|
||||||
|
"ctor",
|
||||||
"futures",
|
"futures",
|
||||||
"log",
|
"log",
|
||||||
"minicbor",
|
"minicbor",
|
||||||
@@ -1118,6 +1126,7 @@ dependencies = [
|
|||||||
name = "conduwuit_macros"
|
name = "conduwuit_macros"
|
||||||
version = "0.5.7-alpha.1"
|
version = "0.5.7-alpha.1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"cargo_toml",
|
||||||
"itertools 0.14.0",
|
"itertools 0.14.0",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
@@ -1136,9 +1145,11 @@ dependencies = [
|
|||||||
"conduwuit_admin",
|
"conduwuit_admin",
|
||||||
"conduwuit_api",
|
"conduwuit_api",
|
||||||
"conduwuit_core",
|
"conduwuit_core",
|
||||||
|
"conduwuit_macros",
|
||||||
"conduwuit_service",
|
"conduwuit_service",
|
||||||
"conduwuit_web",
|
"conduwuit_web",
|
||||||
"const-str",
|
"const-str",
|
||||||
|
"ctor",
|
||||||
"futures",
|
"futures",
|
||||||
"http",
|
"http",
|
||||||
"http-body-util",
|
"http-body-util",
|
||||||
@@ -1169,7 +1180,9 @@ dependencies = [
|
|||||||
"bytes",
|
"bytes",
|
||||||
"conduwuit_core",
|
"conduwuit_core",
|
||||||
"conduwuit_database",
|
"conduwuit_database",
|
||||||
|
"conduwuit_macros",
|
||||||
"const-str",
|
"const-str",
|
||||||
|
"ctor",
|
||||||
"either",
|
"either",
|
||||||
"futures",
|
"futures",
|
||||||
"governor",
|
"governor",
|
||||||
@@ -1291,7 +1304,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "continuwuity-admin-api"
|
name = "continuwuity-admin-api"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://forgejo.ellis.link/continuwuation/ruwuma?rev=a97b91adcc012ef04991d823b8b5a79c6686ae48#a97b91adcc012ef04991d823b8b5a79c6686ae48"
|
source = "git+https://forgejo.ellis.link/continuwuation/ruwuma?rev=1415caf8a32af4d943580c5ea4e12be1974593c2#1415caf8a32af4d943580c5ea4e12be1974593c2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ruma-common",
|
"ruma-common",
|
||||||
"serde",
|
"serde",
|
||||||
@@ -1726,7 +1739,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "draupnir-antispam"
|
name = "draupnir-antispam"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://forgejo.ellis.link/continuwuation/ruwuma?rev=a97b91adcc012ef04991d823b8b5a79c6686ae48#a97b91adcc012ef04991d823b8b5a79c6686ae48"
|
source = "git+https://forgejo.ellis.link/continuwuation/ruwuma?rev=1415caf8a32af4d943580c5ea4e12be1974593c2#1415caf8a32af4d943580c5ea4e12be1974593c2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ruma-common",
|
"ruma-common",
|
||||||
"serde",
|
"serde",
|
||||||
@@ -3241,7 +3254,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "meowlnir-antispam"
|
name = "meowlnir-antispam"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://forgejo.ellis.link/continuwuation/ruwuma?rev=a97b91adcc012ef04991d823b8b5a79c6686ae48#a97b91adcc012ef04991d823b8b5a79c6686ae48"
|
source = "git+https://forgejo.ellis.link/continuwuation/ruwuma?rev=1415caf8a32af4d943580c5ea4e12be1974593c2#1415caf8a32af4d943580c5ea4e12be1974593c2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ruma-common",
|
"ruma-common",
|
||||||
"serde",
|
"serde",
|
||||||
@@ -4545,7 +4558,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "ruma"
|
name = "ruma"
|
||||||
version = "0.10.1"
|
version = "0.10.1"
|
||||||
source = "git+https://forgejo.ellis.link/continuwuation/ruwuma?rev=a97b91adcc012ef04991d823b8b5a79c6686ae48#a97b91adcc012ef04991d823b8b5a79c6686ae48"
|
source = "git+https://forgejo.ellis.link/continuwuation/ruwuma?rev=1415caf8a32af4d943580c5ea4e12be1974593c2#1415caf8a32af4d943580c5ea4e12be1974593c2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"assign",
|
"assign",
|
||||||
"continuwuity-admin-api",
|
"continuwuity-admin-api",
|
||||||
@@ -4568,7 +4581,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "ruma-appservice-api"
|
name = "ruma-appservice-api"
|
||||||
version = "0.10.0"
|
version = "0.10.0"
|
||||||
source = "git+https://forgejo.ellis.link/continuwuation/ruwuma?rev=a97b91adcc012ef04991d823b8b5a79c6686ae48#a97b91adcc012ef04991d823b8b5a79c6686ae48"
|
source = "git+https://forgejo.ellis.link/continuwuation/ruwuma?rev=1415caf8a32af4d943580c5ea4e12be1974593c2#1415caf8a32af4d943580c5ea4e12be1974593c2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"js_int",
|
"js_int",
|
||||||
"ruma-common",
|
"ruma-common",
|
||||||
@@ -4580,7 +4593,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "ruma-client-api"
|
name = "ruma-client-api"
|
||||||
version = "0.18.0"
|
version = "0.18.0"
|
||||||
source = "git+https://forgejo.ellis.link/continuwuation/ruwuma?rev=a97b91adcc012ef04991d823b8b5a79c6686ae48#a97b91adcc012ef04991d823b8b5a79c6686ae48"
|
source = "git+https://forgejo.ellis.link/continuwuation/ruwuma?rev=1415caf8a32af4d943580c5ea4e12be1974593c2#1415caf8a32af4d943580c5ea4e12be1974593c2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"as_variant",
|
"as_variant",
|
||||||
"assign",
|
"assign",
|
||||||
@@ -4603,7 +4616,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "ruma-common"
|
name = "ruma-common"
|
||||||
version = "0.13.0"
|
version = "0.13.0"
|
||||||
source = "git+https://forgejo.ellis.link/continuwuation/ruwuma?rev=a97b91adcc012ef04991d823b8b5a79c6686ae48#a97b91adcc012ef04991d823b8b5a79c6686ae48"
|
source = "git+https://forgejo.ellis.link/continuwuation/ruwuma?rev=1415caf8a32af4d943580c5ea4e12be1974593c2#1415caf8a32af4d943580c5ea4e12be1974593c2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"as_variant",
|
"as_variant",
|
||||||
"base64 0.22.1",
|
"base64 0.22.1",
|
||||||
@@ -4635,7 +4648,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "ruma-events"
|
name = "ruma-events"
|
||||||
version = "0.28.1"
|
version = "0.28.1"
|
||||||
source = "git+https://forgejo.ellis.link/continuwuation/ruwuma?rev=a97b91adcc012ef04991d823b8b5a79c6686ae48#a97b91adcc012ef04991d823b8b5a79c6686ae48"
|
source = "git+https://forgejo.ellis.link/continuwuation/ruwuma?rev=1415caf8a32af4d943580c5ea4e12be1974593c2#1415caf8a32af4d943580c5ea4e12be1974593c2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"as_variant",
|
"as_variant",
|
||||||
"indexmap",
|
"indexmap",
|
||||||
@@ -4660,7 +4673,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "ruma-federation-api"
|
name = "ruma-federation-api"
|
||||||
version = "0.9.0"
|
version = "0.9.0"
|
||||||
source = "git+https://forgejo.ellis.link/continuwuation/ruwuma?rev=a97b91adcc012ef04991d823b8b5a79c6686ae48#a97b91adcc012ef04991d823b8b5a79c6686ae48"
|
source = "git+https://forgejo.ellis.link/continuwuation/ruwuma?rev=1415caf8a32af4d943580c5ea4e12be1974593c2#1415caf8a32af4d943580c5ea4e12be1974593c2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bytes",
|
"bytes",
|
||||||
"headers",
|
"headers",
|
||||||
@@ -4682,7 +4695,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "ruma-identifiers-validation"
|
name = "ruma-identifiers-validation"
|
||||||
version = "0.9.5"
|
version = "0.9.5"
|
||||||
source = "git+https://forgejo.ellis.link/continuwuation/ruwuma?rev=a97b91adcc012ef04991d823b8b5a79c6686ae48#a97b91adcc012ef04991d823b8b5a79c6686ae48"
|
source = "git+https://forgejo.ellis.link/continuwuation/ruwuma?rev=1415caf8a32af4d943580c5ea4e12be1974593c2#1415caf8a32af4d943580c5ea4e12be1974593c2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"js_int",
|
"js_int",
|
||||||
"thiserror 2.0.18",
|
"thiserror 2.0.18",
|
||||||
@@ -4691,7 +4704,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "ruma-identity-service-api"
|
name = "ruma-identity-service-api"
|
||||||
version = "0.9.0"
|
version = "0.9.0"
|
||||||
source = "git+https://forgejo.ellis.link/continuwuation/ruwuma?rev=a97b91adcc012ef04991d823b8b5a79c6686ae48#a97b91adcc012ef04991d823b8b5a79c6686ae48"
|
source = "git+https://forgejo.ellis.link/continuwuation/ruwuma?rev=1415caf8a32af4d943580c5ea4e12be1974593c2#1415caf8a32af4d943580c5ea4e12be1974593c2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"js_int",
|
"js_int",
|
||||||
"ruma-common",
|
"ruma-common",
|
||||||
@@ -4701,7 +4714,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "ruma-macros"
|
name = "ruma-macros"
|
||||||
version = "0.13.0"
|
version = "0.13.0"
|
||||||
source = "git+https://forgejo.ellis.link/continuwuation/ruwuma?rev=a97b91adcc012ef04991d823b8b5a79c6686ae48#a97b91adcc012ef04991d823b8b5a79c6686ae48"
|
source = "git+https://forgejo.ellis.link/continuwuation/ruwuma?rev=1415caf8a32af4d943580c5ea4e12be1974593c2#1415caf8a32af4d943580c5ea4e12be1974593c2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
"proc-macro-crate",
|
"proc-macro-crate",
|
||||||
@@ -4716,7 +4729,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "ruma-push-gateway-api"
|
name = "ruma-push-gateway-api"
|
||||||
version = "0.9.0"
|
version = "0.9.0"
|
||||||
source = "git+https://forgejo.ellis.link/continuwuation/ruwuma?rev=a97b91adcc012ef04991d823b8b5a79c6686ae48#a97b91adcc012ef04991d823b8b5a79c6686ae48"
|
source = "git+https://forgejo.ellis.link/continuwuation/ruwuma?rev=1415caf8a32af4d943580c5ea4e12be1974593c2#1415caf8a32af4d943580c5ea4e12be1974593c2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"js_int",
|
"js_int",
|
||||||
"ruma-common",
|
"ruma-common",
|
||||||
@@ -4728,7 +4741,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "ruma-signatures"
|
name = "ruma-signatures"
|
||||||
version = "0.15.0"
|
version = "0.15.0"
|
||||||
source = "git+https://forgejo.ellis.link/continuwuation/ruwuma?rev=a97b91adcc012ef04991d823b8b5a79c6686ae48#a97b91adcc012ef04991d823b8b5a79c6686ae48"
|
source = "git+https://forgejo.ellis.link/continuwuation/ruwuma?rev=1415caf8a32af4d943580c5ea4e12be1974593c2#1415caf8a32af4d943580c5ea4e12be1974593c2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"base64 0.22.1",
|
"base64 0.22.1",
|
||||||
"ed25519-dalek",
|
"ed25519-dalek",
|
||||||
|
|||||||
+3
-2
@@ -344,7 +344,7 @@ version = "0.1.2"
|
|||||||
[workspace.dependencies.ruma]
|
[workspace.dependencies.ruma]
|
||||||
git = "https://forgejo.ellis.link/continuwuation/ruwuma"
|
git = "https://forgejo.ellis.link/continuwuation/ruwuma"
|
||||||
#branch = "conduwuit-changes"
|
#branch = "conduwuit-changes"
|
||||||
rev = "a97b91adcc012ef04991d823b8b5a79c6686ae48"
|
rev = "1415caf8a32af4d943580c5ea4e12be1974593c2"
|
||||||
features = [
|
features = [
|
||||||
"compat",
|
"compat",
|
||||||
"rand",
|
"rand",
|
||||||
@@ -383,7 +383,8 @@ features = [
|
|||||||
"unstable-pdu",
|
"unstable-pdu",
|
||||||
"unstable-msc4155",
|
"unstable-msc4155",
|
||||||
"unstable-msc4143", # livekit well_known response
|
"unstable-msc4143", # livekit well_known response
|
||||||
"unstable-msc4284"
|
"unstable-msc4284",
|
||||||
|
"unstable-msc4439", # pgp_key in .well_known/matrix/support
|
||||||
]
|
]
|
||||||
|
|
||||||
[workspace.dependencies.rust-rocksdb]
|
[workspace.dependencies.rust-rocksdb]
|
||||||
|
|||||||
@@ -0,0 +1 @@
|
|||||||
|
Added support for requiring users to accept terms and conditions when registering.
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
Refactored nix package. Breaking, since `all-features` package no longer exists. Continuwuity is now built with jemalloc and liburing by default. Contributed by @Henry-Hiles (QuadRadical).
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
Add new config option for [MSC4439](https://github.com/matrix-org/matrix-spec-proposals/pull/4439)
|
||||||
|
PGP key URIs. Contributed by LogN.
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
Fixed resolving IP of servers that only use SRV delegation. Contributed by @tulir.
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
Fixed compiler warning in cf_opts.rs when building in release. Contributed by @ezera.
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
Fixed "Sender must be a local user" error for make_join, make_knock, and make_leave federation routes. Contributed by @nex.
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
Added admin commands to get build information and features. Contributed by @Jade
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
Fixed restricted joins not being signed when we are being used as an authorising server. Contributed by @nex, reported by [vel](matrix:u/vel:nhjkl.com?action=chat).
|
||||||
@@ -523,6 +523,18 @@
|
|||||||
#
|
#
|
||||||
#recaptcha_private_site_key =
|
#recaptcha_private_site_key =
|
||||||
|
|
||||||
|
# Policy documents, such as terms and conditions or a privacy policy,
|
||||||
|
# which users must agree to when registering an account.
|
||||||
|
#
|
||||||
|
# Example:
|
||||||
|
# ```ignore
|
||||||
|
# [global.registration_terms.privacy_policy]
|
||||||
|
# en = { name = "Privacy Policy", url = "https://homeserver.example/en/privacy_policy.html" }
|
||||||
|
# es = { name = "Política de Privacidad", url = "https://homeserver.example/es/privacy_policy.html" }
|
||||||
|
# ```
|
||||||
|
#
|
||||||
|
#registration_terms = {}
|
||||||
|
|
||||||
# Controls whether encrypted rooms and events are allowed.
|
# Controls whether encrypted rooms and events are allowed.
|
||||||
#
|
#
|
||||||
#allow_encryption = true
|
#allow_encryption = true
|
||||||
@@ -1869,6 +1881,11 @@
|
|||||||
#
|
#
|
||||||
#support_mxid =
|
#support_mxid =
|
||||||
|
|
||||||
|
# PGP key URI for server support contacts, to be served as part of the
|
||||||
|
# MSC1929 server support endpoint.
|
||||||
|
#
|
||||||
|
#support_pgp_key =
|
||||||
|
|
||||||
# **DEPRECATED**: Use `[global.matrix_rtc].foci` instead.
|
# **DEPRECATED**: Use `[global.matrix_rtc].foci` instead.
|
||||||
#
|
#
|
||||||
# A list of MatrixRTC foci URLs which will be served as part of the
|
# A list of MatrixRTC foci URLs which will be served as part of the
|
||||||
|
|||||||
+2
-2
@@ -15,13 +15,13 @@ ARG LLVM_VERSION=21
|
|||||||
|
|
||||||
# Install repo tools
|
# Install repo tools
|
||||||
# Line one: compiler tools
|
# Line one: compiler tools
|
||||||
# Line two: curl, for downloading binaries
|
# Line two: curl, for downloading binaries and wget because llvm.sh is broken with curl
|
||||||
# Line three: for xx-verify
|
# Line three: for xx-verify
|
||||||
RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \
|
RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \
|
||||||
--mount=type=cache,target=/var/lib/apt,sharing=locked \
|
--mount=type=cache,target=/var/lib/apt,sharing=locked \
|
||||||
apt-get update && apt-get install -y \
|
apt-get update && apt-get install -y \
|
||||||
pkg-config make jq \
|
pkg-config make jq \
|
||||||
curl git software-properties-common \
|
wget curl git software-properties-common \
|
||||||
file
|
file
|
||||||
|
|
||||||
# LLVM packages
|
# LLVM packages
|
||||||
|
|||||||
@@ -133,6 +133,18 @@ pusher service
|
|||||||
|
|
||||||
Returns all the pushers for the user
|
Returns all the pushers for the user
|
||||||
|
|
||||||
|
### `!admin query pusher delete-pusher`
|
||||||
|
|
||||||
|
Deletes a specific pusher by ID
|
||||||
|
|
||||||
|
### `!admin query pusher delete-all-user`
|
||||||
|
|
||||||
|
Deletes all pushers for a user
|
||||||
|
|
||||||
|
### `!admin query pusher delete-all-device`
|
||||||
|
|
||||||
|
Deletes all pushers associated with a device ID
|
||||||
|
|
||||||
## `!admin query short`
|
## `!admin query short`
|
||||||
|
|
||||||
short service
|
short service
|
||||||
|
|||||||
@@ -47,3 +47,11 @@ Restart the server
|
|||||||
## `!admin server shutdown`
|
## `!admin server shutdown`
|
||||||
|
|
||||||
Shutdown the server
|
Shutdown the server
|
||||||
|
|
||||||
|
## `!admin server list-features`
|
||||||
|
|
||||||
|
List features built into the server
|
||||||
|
|
||||||
|
## `!admin server build-info`
|
||||||
|
|
||||||
|
Build information
|
||||||
|
|||||||
@@ -157,3 +157,7 @@ Force joins all local users to the specified room.
|
|||||||
At least 1 server admin must be in the room to reduce abuse.
|
At least 1 server admin must be in the room to reduce abuse.
|
||||||
|
|
||||||
Requires the `--yes-i-want-to-do-this` flag.
|
Requires the `--yes-i-want-to-do-this` flag.
|
||||||
|
|
||||||
|
## `!admin users reset-push-rules`
|
||||||
|
|
||||||
|
Resets the push-rules (notification settings) of the target user to the server defaults
|
||||||
|
|||||||
@@ -29,7 +29,6 @@
|
|||||||
url = "github:edolstra/flake-compat?ref=master";
|
url = "github:edolstra/flake-compat?ref=master";
|
||||||
flake = false;
|
flake = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
outputs =
|
outputs =
|
||||||
@@ -37,10 +36,10 @@
|
|||||||
flake-parts.lib.mkFlake { inherit inputs; } {
|
flake-parts.lib.mkFlake { inherit inputs; } {
|
||||||
imports = [ ./nix ];
|
imports = [ ./nix ];
|
||||||
systems = [
|
systems = [
|
||||||
# good support
|
|
||||||
"x86_64-linux"
|
"x86_64-linux"
|
||||||
# support untested but theoretically there
|
|
||||||
"aarch64-linux"
|
"aarch64-linux"
|
||||||
|
# support untested but theoretically there
|
||||||
|
"aarch64-darwin"
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,107 +0,0 @@
|
|||||||
{ inputs, ... }:
|
|
||||||
{
|
|
||||||
perSystem =
|
|
||||||
{
|
|
||||||
self',
|
|
||||||
lib,
|
|
||||||
pkgs,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
let
|
|
||||||
uwulib = inputs.self.uwulib.init pkgs;
|
|
||||||
|
|
||||||
rocksdbAllFeatures = self'.packages.rocksdb.override {
|
|
||||||
enableJemalloc = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
commonAttrs = (uwulib.build.commonAttrs { }) // {
|
|
||||||
buildInputs = [
|
|
||||||
pkgs.liburing
|
|
||||||
pkgs.rust-jemalloc-sys-unprefixed
|
|
||||||
rocksdbAllFeatures
|
|
||||||
];
|
|
||||||
nativeBuildInputs = [
|
|
||||||
pkgs.pkg-config
|
|
||||||
# bindgen needs the build platform's libclang. Apparently due to "splicing
|
|
||||||
# weirdness", pkgs.rustPlatform.bindgenHook on its own doesn't quite do the
|
|
||||||
# right thing here.
|
|
||||||
pkgs.rustPlatform.bindgenHook
|
|
||||||
];
|
|
||||||
env = {
|
|
||||||
LIBCLANG_PATH = lib.makeLibraryPath [ pkgs.llvmPackages.libclang.lib ];
|
|
||||||
LD_LIBRARY_PATH = lib.makeLibraryPath [
|
|
||||||
pkgs.liburing
|
|
||||||
pkgs.rust-jemalloc-sys-unprefixed
|
|
||||||
rocksdbAllFeatures
|
|
||||||
];
|
|
||||||
}
|
|
||||||
// uwulib.environment.buildPackageEnv
|
|
||||||
// {
|
|
||||||
ROCKSDB_INCLUDE_DIR = "${rocksdbAllFeatures}/include";
|
|
||||||
ROCKSDB_LIB_DIR = "${rocksdbAllFeatures}/lib";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
cargoArtifacts = self'.packages.continuwuity-all-features-deps;
|
|
||||||
in
|
|
||||||
{
|
|
||||||
# taken from
|
|
||||||
#
|
|
||||||
# https://crane.dev/examples/quick-start.html
|
|
||||||
checks = {
|
|
||||||
continuwuity-all-features-build = self'.packages.continuwuity-all-features-bin;
|
|
||||||
|
|
||||||
continuwuity-all-features-clippy = uwulib.build.craneLibForChecks.cargoClippy (
|
|
||||||
commonAttrs
|
|
||||||
// {
|
|
||||||
inherit cargoArtifacts;
|
|
||||||
cargoClippyExtraArgs = "-- --deny warnings";
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
continuwuity-all-features-docs = uwulib.build.craneLibForChecks.cargoDoc (
|
|
||||||
commonAttrs
|
|
||||||
// {
|
|
||||||
inherit cargoArtifacts;
|
|
||||||
# This can be commented out or tweaked as necessary, e.g. set to
|
|
||||||
# `--deny rustdoc::broken-intra-doc-links` to only enforce that lint
|
|
||||||
env.RUSTDOCFLAGS = "--deny warnings";
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
# Check formatting
|
|
||||||
continuwuity-all-features-fmt = uwulib.build.craneLibForChecks.cargoFmt {
|
|
||||||
src = uwulib.build.src;
|
|
||||||
};
|
|
||||||
|
|
||||||
continuwuity-all-features-toml-fmt = uwulib.build.craneLibForChecks.taploFmt {
|
|
||||||
src = pkgs.lib.sources.sourceFilesBySuffices uwulib.build.src [ ".toml" ];
|
|
||||||
# taplo arguments can be further customized below as needed
|
|
||||||
taploExtraArgs = "--config ${inputs.self}/taplo.toml";
|
|
||||||
};
|
|
||||||
|
|
||||||
# Audit dependencies
|
|
||||||
continuwuity-all-features-audit = uwulib.build.craneLibForChecks.cargoAudit {
|
|
||||||
inherit (inputs) advisory-db;
|
|
||||||
src = uwulib.build.src;
|
|
||||||
};
|
|
||||||
|
|
||||||
# Audit licenses
|
|
||||||
continuwuity-all-features-deny = uwulib.build.craneLibForChecks.cargoDeny {
|
|
||||||
src = uwulib.build.src;
|
|
||||||
};
|
|
||||||
|
|
||||||
# Run tests with cargo-nextest
|
|
||||||
# Consider setting `doCheck = false` on `continuwuity-all-features` if you do not want
|
|
||||||
# the tests to run twice
|
|
||||||
continuwuity-all-features-nextest = uwulib.build.craneLibForChecks.cargoNextest (
|
|
||||||
commonAttrs
|
|
||||||
// {
|
|
||||||
inherit cargoArtifacts;
|
|
||||||
partitions = 1;
|
|
||||||
partitionType = "count";
|
|
||||||
cargoNextestPartitionsExtraArgs = "--no-tests=pass";
|
|
||||||
}
|
|
||||||
);
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
{ inputs, ... }:
|
||||||
|
{
|
||||||
|
perSystem =
|
||||||
|
{
|
||||||
|
pkgs,
|
||||||
|
self',
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
{
|
||||||
|
_module.args.craneLib = (inputs.crane.mkLib pkgs).overrideToolchain (
|
||||||
|
pkgs: self'.packages.stable-toolchain
|
||||||
|
);
|
||||||
|
};
|
||||||
|
}
|
||||||
+4
-5
@@ -1,11 +1,10 @@
|
|||||||
{
|
{
|
||||||
imports = [
|
imports = [
|
||||||
./checks
|
./rust.nix
|
||||||
|
./crane.nix
|
||||||
./packages
|
./packages
|
||||||
./shells
|
./devshell.nix
|
||||||
./tests
|
|
||||||
|
|
||||||
./hydra.nix
|
|
||||||
./fmt.nix
|
./fmt.nix
|
||||||
|
./rocksdb-updater.nix
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,42 @@
|
|||||||
|
{
|
||||||
|
perSystem =
|
||||||
|
{
|
||||||
|
craneLib,
|
||||||
|
self',
|
||||||
|
lib,
|
||||||
|
pkgs,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
{
|
||||||
|
# basic nix shell containing all things necessary to build continuwuity in all flavors manually (on x86_64-linux)
|
||||||
|
devShells.default = craneLib.devShell {
|
||||||
|
packages = [
|
||||||
|
self'.packages.rocksdb
|
||||||
|
pkgs.nodejs
|
||||||
|
pkgs.pkg-config
|
||||||
|
]
|
||||||
|
++ lib.optionals pkgs.stdenv.isLinux [
|
||||||
|
pkgs.liburing
|
||||||
|
pkgs.rust-jemalloc-sys-unprefixed
|
||||||
|
];
|
||||||
|
|
||||||
|
env = {
|
||||||
|
LIBCLANG_PATH = lib.makeLibraryPath [ pkgs.llvmPackages.libclang.lib ];
|
||||||
|
LD_LIBRARY_PATH = lib.makeLibraryPath (
|
||||||
|
[
|
||||||
|
pkgs.stdenv.cc.cc.lib
|
||||||
|
]
|
||||||
|
++ lib.optionals pkgs.stdenv.isLinux [
|
||||||
|
pkgs.liburing
|
||||||
|
pkgs.jemalloc
|
||||||
|
]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
// lib.optionalAttrs pkgs.stdenv.isLinux {
|
||||||
|
PKG_CONFIG_PATH = lib.makeSearchPath "lib/pkgconfig" [
|
||||||
|
pkgs.liburing.dev
|
||||||
|
];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
{ inputs, ... }:
|
|
||||||
let
|
|
||||||
lib = inputs.nixpkgs.lib;
|
|
||||||
in
|
|
||||||
{
|
|
||||||
flake.hydraJobs.packages = builtins.mapAttrs (
|
|
||||||
_name: lib.hydraJob
|
|
||||||
) inputs.self.packages.x86_64-linux;
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,65 @@
|
|||||||
|
{
|
||||||
|
lib,
|
||||||
|
self,
|
||||||
|
stdenv,
|
||||||
|
liburing,
|
||||||
|
craneLib,
|
||||||
|
pkg-config,
|
||||||
|
callPackage,
|
||||||
|
rustPlatform,
|
||||||
|
cargoExtraArgs ? "",
|
||||||
|
rocksdb ? callPackage ./rocksdb.nix { },
|
||||||
|
}:
|
||||||
|
let
|
||||||
|
# see https://crane.dev/API.html#cranelibfiltercargosources
|
||||||
|
# we need to keep the `web` directory which would be filtered out by the regular source filtering function
|
||||||
|
# https://crane.dev/API.html#cranelibcleancargosource
|
||||||
|
isWebTemplate = path: _type: builtins.match ".*(src/(web|service)|docs).*" path != null;
|
||||||
|
isRust = craneLib.filterCargoSources;
|
||||||
|
isNix = path: _type: builtins.match ".+/nix.*" path != null;
|
||||||
|
webOrRustNotNix = p: t: !(isNix p t) && (isWebTemplate p t || isRust p t);
|
||||||
|
|
||||||
|
src = lib.cleanSourceWith {
|
||||||
|
src = self;
|
||||||
|
filter = webOrRustNotNix;
|
||||||
|
name = "source";
|
||||||
|
};
|
||||||
|
|
||||||
|
attrs = {
|
||||||
|
inherit src;
|
||||||
|
nativeBuildInputs = [
|
||||||
|
pkg-config
|
||||||
|
rustPlatform.bindgenHook
|
||||||
|
];
|
||||||
|
buildInputs = lib.optionals stdenv.hostPlatform.isLinux [ liburing ];
|
||||||
|
env = {
|
||||||
|
ROCKSDB_INCLUDE_DIR = "${rocksdb}/include";
|
||||||
|
ROCKSDB_LIB_DIR = "${rocksdb}/lib";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
in
|
||||||
|
craneLib.buildPackage (
|
||||||
|
lib.recursiveUpdate attrs {
|
||||||
|
inherit cargoExtraArgs;
|
||||||
|
cargoArtifacts = craneLib.buildDepsOnly attrs;
|
||||||
|
|
||||||
|
# Needed to make continuwuity link to rocksdb
|
||||||
|
postFixup = lib.optionalString stdenv.hostPlatform.isLinux ''
|
||||||
|
old_rpath="$(patchelf --print-rpath $out/bin/conduwuit)"
|
||||||
|
extra_rpath="${
|
||||||
|
lib.makeLibraryPath [
|
||||||
|
rocksdb
|
||||||
|
]
|
||||||
|
}"
|
||||||
|
|
||||||
|
patchelf --set-rpath "$old_rpath:$extra_rpath" $out/bin/conduwuit
|
||||||
|
'';
|
||||||
|
|
||||||
|
meta = {
|
||||||
|
description = "A community-driven Matrix homeserver in Rust";
|
||||||
|
mainProgram = "conduwuit";
|
||||||
|
platforms = lib.platforms.all;
|
||||||
|
maintainers = with lib.maintainers; [ quadradical ];
|
||||||
|
};
|
||||||
|
}
|
||||||
|
)
|
||||||
@@ -1,59 +0,0 @@
|
|||||||
{ inputs, ... }:
|
|
||||||
{
|
|
||||||
perSystem =
|
|
||||||
{
|
|
||||||
self',
|
|
||||||
lib,
|
|
||||||
pkgs,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
let
|
|
||||||
uwulib = inputs.self.uwulib.init pkgs;
|
|
||||||
in
|
|
||||||
{
|
|
||||||
packages =
|
|
||||||
lib.pipe
|
|
||||||
[
|
|
||||||
# this is the default variant
|
|
||||||
{
|
|
||||||
variantName = "default";
|
|
||||||
commonAttrsArgs.profile = "release";
|
|
||||||
rocksdb = self'.packages.rocksdb;
|
|
||||||
features = { };
|
|
||||||
}
|
|
||||||
# this is the variant with all features enabled (liburing + jemalloc)
|
|
||||||
{
|
|
||||||
variantName = "all-features";
|
|
||||||
commonAttrsArgs.profile = "release";
|
|
||||||
rocksdb = self'.packages.rocksdb.override {
|
|
||||||
enableJemalloc = true;
|
|
||||||
};
|
|
||||||
features = {
|
|
||||||
enabledFeatures = "all";
|
|
||||||
disabledFeatures = uwulib.features.defaultDisabledFeatures ++ [ "bindgen-static" ];
|
|
||||||
};
|
|
||||||
}
|
|
||||||
]
|
|
||||||
[
|
|
||||||
(builtins.map (cfg: rec {
|
|
||||||
deps = {
|
|
||||||
name = "continuwuity-${cfg.variantName}-deps";
|
|
||||||
value = uwulib.build.buildDeps {
|
|
||||||
features = uwulib.features.calcFeatures cfg.features;
|
|
||||||
inherit (cfg) commonAttrsArgs rocksdb;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
bin = {
|
|
||||||
name = "continuwuity-${cfg.variantName}-bin";
|
|
||||||
value = uwulib.build.buildPackage {
|
|
||||||
deps = self'.packages.${deps.name};
|
|
||||||
features = uwulib.features.calcFeatures cfg.features;
|
|
||||||
inherit (cfg) commonAttrsArgs rocksdb;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}))
|
|
||||||
(builtins.concatMap builtins.attrValues)
|
|
||||||
builtins.listToAttrs
|
|
||||||
];
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,14 +1,18 @@
|
|||||||
{
|
{
|
||||||
imports = [
|
self,
|
||||||
./continuwuity
|
...
|
||||||
./rocksdb
|
}:
|
||||||
./rust.nix
|
{
|
||||||
./uwulib
|
|
||||||
];
|
|
||||||
|
|
||||||
perSystem =
|
perSystem =
|
||||||
{ self', ... }:
|
|
||||||
{
|
{
|
||||||
packages.default = self'.packages.continuwuity-default-bin;
|
pkgs,
|
||||||
|
craneLib,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
{
|
||||||
|
packages = {
|
||||||
|
rocksdb = pkgs.callPackage ./rocksdb.nix { };
|
||||||
|
default = pkgs.callPackage ./continuwuity.nix { inherit self craneLib; };
|
||||||
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,34 @@
|
|||||||
|
{
|
||||||
|
stdenv,
|
||||||
|
rocksdb,
|
||||||
|
fetchFromGitea,
|
||||||
|
rust-jemalloc-sys-unprefixed,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
(rocksdb.override {
|
||||||
|
# rocksdb fails to build with prefixed jemalloc, which is required on
|
||||||
|
# darwin due to [1]. In this case, fall back to building rocksdb with
|
||||||
|
# libc malloc. This should not cause conflicts, because all of the
|
||||||
|
# jemalloc symbols are prefixed.
|
||||||
|
#
|
||||||
|
# [1]: https://github.com/tikv/jemallocator/blob/ab0676d77e81268cd09b059260c75b38dbef2d51/jemalloc-sys/src/env.rs#L17
|
||||||
|
jemalloc = rust-jemalloc-sys-unprefixed;
|
||||||
|
enableJemalloc = stdenv.hostPlatform.isLinux;
|
||||||
|
}).overrideAttrs
|
||||||
|
({
|
||||||
|
version = "continuwuity-v0.5.0-unstable-2026-03-27";
|
||||||
|
src = fetchFromGitea {
|
||||||
|
domain = "forgejo.ellis.link";
|
||||||
|
owner = "continuwuation";
|
||||||
|
repo = "rocksdb";
|
||||||
|
rev = "463f47afceebfe088f6922420265546bd237f249";
|
||||||
|
hash = "sha256-1ef75IDMs5Hba4VWEyXPJb02JyShy5k4gJfzGDhopRk=";
|
||||||
|
};
|
||||||
|
|
||||||
|
# We have this already at https://forgejo.ellis.link/continuwuation/rocksdb/commit/a935c0273e1ba44eacf88ce3685a9b9831486155
|
||||||
|
# Unsetting `patches` so we don't have to revert it and make this nix exclusive
|
||||||
|
patches = [ ];
|
||||||
|
|
||||||
|
# Unset postPatch, as our version override breaks version-specific sed calls in the original package
|
||||||
|
postPatch = "";
|
||||||
|
})
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
{
|
|
||||||
perSystem =
|
|
||||||
{
|
|
||||||
pkgs,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
{
|
|
||||||
packages = {
|
|
||||||
rocksdb = pkgs.callPackage ./package.nix { };
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,87 +0,0 @@
|
|||||||
{
|
|
||||||
lib,
|
|
||||||
stdenv,
|
|
||||||
|
|
||||||
rocksdb,
|
|
||||||
liburing,
|
|
||||||
rust-jemalloc-sys-unprefixed,
|
|
||||||
|
|
||||||
enableJemalloc ? false,
|
|
||||||
|
|
||||||
fetchFromGitea,
|
|
||||||
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
let
|
|
||||||
notDarwin = !stdenv.hostPlatform.isDarwin;
|
|
||||||
in
|
|
||||||
(rocksdb.override {
|
|
||||||
# Override the liburing input for the build with our own so
|
|
||||||
# we have it built with the library flag
|
|
||||||
inherit liburing;
|
|
||||||
jemalloc = rust-jemalloc-sys-unprefixed;
|
|
||||||
|
|
||||||
# rocksdb fails to build with prefixed jemalloc, which is required on
|
|
||||||
# darwin due to [1]. In this case, fall back to building rocksdb with
|
|
||||||
# libc malloc. This should not cause conflicts, because all of the
|
|
||||||
# jemalloc symbols are prefixed.
|
|
||||||
#
|
|
||||||
# [1]: https://github.com/tikv/jemallocator/blob/ab0676d77e81268cd09b059260c75b38dbef2d51/jemalloc-sys/src/env.rs#L17
|
|
||||||
enableJemalloc = enableJemalloc && notDarwin;
|
|
||||||
|
|
||||||
# for some reason enableLiburing in nixpkgs rocksdb is default true
|
|
||||||
# which breaks Darwin entirely
|
|
||||||
enableLiburing = notDarwin;
|
|
||||||
}).overrideAttrs
|
|
||||||
(old: {
|
|
||||||
src = fetchFromGitea {
|
|
||||||
domain = "forgejo.ellis.link";
|
|
||||||
owner = "continuwuation";
|
|
||||||
repo = "rocksdb";
|
|
||||||
rev = "10.5.fb";
|
|
||||||
sha256 = "sha256-X4ApGLkHF9ceBtBg77dimEpu720I79ffLoyPa8JMHaU=";
|
|
||||||
};
|
|
||||||
version = "10.5.fb";
|
|
||||||
cmakeFlags =
|
|
||||||
lib.subtractLists (builtins.map (flag: lib.cmakeBool flag true) [
|
|
||||||
# No real reason to have snappy or zlib, no one uses this
|
|
||||||
"WITH_SNAPPY"
|
|
||||||
"ZLIB"
|
|
||||||
"WITH_ZLIB"
|
|
||||||
# We don't need to use ldb or sst_dump (core_tools)
|
|
||||||
"WITH_CORE_TOOLS"
|
|
||||||
# We don't need to build rocksdb tests
|
|
||||||
"WITH_TESTS"
|
|
||||||
# We use rust-rocksdb via C interface and don't need C++ RTTI
|
|
||||||
"USE_RTTI"
|
|
||||||
# This doesn't exist in RocksDB, and USE_SSE is deprecated for
|
|
||||||
# PORTABLE=$(march)
|
|
||||||
"FORCE_SSE42"
|
|
||||||
]) old.cmakeFlags
|
|
||||||
++ (builtins.map (flag: lib.cmakeBool flag false) [
|
|
||||||
# No real reason to have snappy, no one uses this
|
|
||||||
"WITH_SNAPPY"
|
|
||||||
"ZLIB"
|
|
||||||
"WITH_ZLIB"
|
|
||||||
# We don't need to use ldb or sst_dump (core_tools)
|
|
||||||
"WITH_CORE_TOOLS"
|
|
||||||
# We don't need trace tools
|
|
||||||
"WITH_TRACE_TOOLS"
|
|
||||||
# We don't need to build rocksdb tests
|
|
||||||
"WITH_TESTS"
|
|
||||||
# We use rust-rocksdb via C interface and don't need C++ RTTI
|
|
||||||
"USE_RTTI"
|
|
||||||
]);
|
|
||||||
|
|
||||||
enableLiburing = notDarwin;
|
|
||||||
|
|
||||||
# outputs has "tools" which we don't need or use
|
|
||||||
outputs = [ "out" ];
|
|
||||||
|
|
||||||
# preInstall hooks has stuff for messing with ldb/sst_dump which we don't need or use
|
|
||||||
preInstall = "";
|
|
||||||
|
|
||||||
# We have this already at https://forgejo.ellis.link/continuwuation/rocksdb/commit/a935c0273e1ba44eacf88ce3685a9b9831486155
|
|
||||||
# Unsetting `patches` so we don't have to revert it and make this nix exclusive
|
|
||||||
patches = [ ];
|
|
||||||
})
|
|
||||||
@@ -1,122 +0,0 @@
|
|||||||
args@{ pkgs, inputs, ... }:
|
|
||||||
let
|
|
||||||
inherit (pkgs) lib;
|
|
||||||
uwuenv = import ./environment.nix args;
|
|
||||||
selfpkgs = inputs.self.packages.${pkgs.stdenv.system};
|
|
||||||
in
|
|
||||||
rec {
|
|
||||||
# basic, very minimal instance of the crane library with a minimal rust toolchain
|
|
||||||
craneLib = (inputs.crane.mkLib pkgs).overrideToolchain (_: selfpkgs.build-toolchain);
|
|
||||||
# the checks require more rust toolchain components, hence we have this separate instance of the crane library
|
|
||||||
craneLibForChecks = (inputs.crane.mkLib pkgs).overrideToolchain (_: selfpkgs.dev-toolchain);
|
|
||||||
|
|
||||||
# meta information (name, version, etc) of the rust crate based on the Cargo.toml
|
|
||||||
crateInfo = craneLib.crateNameFromCargoToml { cargoToml = "${inputs.self}/Cargo.toml"; };
|
|
||||||
|
|
||||||
src =
|
|
||||||
let
|
|
||||||
# see https://crane.dev/API.html#cranelibfiltercargosources
|
|
||||||
#
|
|
||||||
# we need to keep the `web` directory which would be filtered out by the regular source filtering function
|
|
||||||
#
|
|
||||||
# https://crane.dev/API.html#cranelibcleancargosource
|
|
||||||
isWebTemplate = path: _type: builtins.match ".*(src/(web|service)|docs).*" path != null;
|
|
||||||
isRust = craneLib.filterCargoSources;
|
|
||||||
isNix = path: _type: builtins.match ".+/nix.*" path != null;
|
|
||||||
webOrRustNotNix = p: t: !(isNix p t) && (isWebTemplate p t || isRust p t);
|
|
||||||
in
|
|
||||||
lib.cleanSourceWith {
|
|
||||||
src = inputs.self;
|
|
||||||
filter = webOrRustNotNix;
|
|
||||||
name = "source";
|
|
||||||
};
|
|
||||||
|
|
||||||
# common attrs that are shared between building continuwuity's deps and the package itself
|
|
||||||
commonAttrs =
|
|
||||||
{
|
|
||||||
profile ? "dev",
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
{
|
|
||||||
inherit (crateInfo)
|
|
||||||
pname
|
|
||||||
version
|
|
||||||
;
|
|
||||||
inherit src;
|
|
||||||
|
|
||||||
# this prevents unnecessary rebuilds
|
|
||||||
strictDeps = true;
|
|
||||||
|
|
||||||
dontStrip = profile == "dev" || profile == "test";
|
|
||||||
dontPatchELF = profile == "dev" || profile == "test";
|
|
||||||
|
|
||||||
doCheck = true;
|
|
||||||
|
|
||||||
nativeBuildInputs = [
|
|
||||||
# bindgen needs the build platform's libclang. Apparently due to "splicing
|
|
||||||
# weirdness", pkgs.rustPlatform.bindgenHook on its own doesn't quite do the
|
|
||||||
# right thing here.
|
|
||||||
pkgs.rustPlatform.bindgenHook
|
|
||||||
];
|
|
||||||
};
|
|
||||||
|
|
||||||
makeRocksDBEnv =
|
|
||||||
{ rocksdb }:
|
|
||||||
{
|
|
||||||
ROCKSDB_INCLUDE_DIR = "${rocksdb}/include";
|
|
||||||
ROCKSDB_LIB_DIR = "${rocksdb}/lib";
|
|
||||||
};
|
|
||||||
|
|
||||||
# function that builds the continuwuity dependencies derivation
|
|
||||||
buildDeps =
|
|
||||||
{
|
|
||||||
rocksdb,
|
|
||||||
features,
|
|
||||||
commonAttrsArgs,
|
|
||||||
}:
|
|
||||||
craneLib.buildDepsOnly (
|
|
||||||
(commonAttrs commonAttrsArgs)
|
|
||||||
// {
|
|
||||||
env = uwuenv.buildDepsOnlyEnv
|
|
||||||
// (makeRocksDBEnv { inherit rocksdb; })
|
|
||||||
// {
|
|
||||||
# required since we started using unstable reqwest apparently ... otherwise the all-features build will fail
|
|
||||||
RUSTFLAGS = "--cfg reqwest_unstable";
|
|
||||||
};
|
|
||||||
inherit (features) cargoExtraArgs;
|
|
||||||
}
|
|
||||||
|
|
||||||
);
|
|
||||||
|
|
||||||
# function that builds the continuwuity package
|
|
||||||
buildPackage =
|
|
||||||
{
|
|
||||||
deps,
|
|
||||||
rocksdb,
|
|
||||||
features,
|
|
||||||
commonAttrsArgs,
|
|
||||||
}:
|
|
||||||
let
|
|
||||||
rocksdbEnv = makeRocksDBEnv { inherit rocksdb; };
|
|
||||||
in
|
|
||||||
craneLib.buildPackage (
|
|
||||||
(commonAttrs commonAttrsArgs)
|
|
||||||
// {
|
|
||||||
postFixup = ''
|
|
||||||
patchelf --set-rpath "$(${pkgs.patchelf}/bin/patchelf --print-rpath $out/bin/${crateInfo.pname}):${rocksdb}/lib" $out/bin/${crateInfo.pname}
|
|
||||||
'';
|
|
||||||
cargoArtifacts = deps;
|
|
||||||
doCheck = true;
|
|
||||||
env =
|
|
||||||
uwuenv.buildPackageEnv
|
|
||||||
// rocksdbEnv
|
|
||||||
// {
|
|
||||||
# required since we started using unstable reqwest apparently ... otherwise the all-features build will fail
|
|
||||||
RUSTFLAGS = "--cfg reqwest_unstable";
|
|
||||||
};
|
|
||||||
passthru.env = uwuenv.buildPackageEnv // rocksdbEnv;
|
|
||||||
meta.mainProgram = crateInfo.pname;
|
|
||||||
inherit (features) cargoExtraArgs;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
{ inputs, ... }:
|
|
||||||
{
|
|
||||||
flake.uwulib = {
|
|
||||||
init = pkgs: {
|
|
||||||
features = import ./features.nix { inherit pkgs inputs; };
|
|
||||||
environment = import ./environment.nix { inherit pkgs inputs; };
|
|
||||||
build = import ./build.nix { inherit pkgs inputs; };
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
args@{ pkgs, inputs, ... }:
|
|
||||||
let
|
|
||||||
uwubuild = import ./build.nix args;
|
|
||||||
in
|
|
||||||
rec {
|
|
||||||
buildDepsOnlyEnv = {
|
|
||||||
# https://crane.dev/faq/rebuilds-bindgen.html
|
|
||||||
NIX_OUTPATH_USED_AS_RANDOM_SEED = "aaaaaaaaaa";
|
|
||||||
CARGO_PROFILE = "release";
|
|
||||||
}
|
|
||||||
// uwubuild.craneLib.mkCrossToolchainEnv (p: pkgs.clangStdenv);
|
|
||||||
|
|
||||||
buildPackageEnv = {
|
|
||||||
GIT_COMMIT_HASH = inputs.self.rev or inputs.self.dirtyRev or "";
|
|
||||||
GIT_COMMIT_HASH_SHORT = inputs.self.shortRev or inputs.self.dirtyShortRev or "";
|
|
||||||
}
|
|
||||||
// buildDepsOnlyEnv;
|
|
||||||
}
|
|
||||||
@@ -1,77 +0,0 @@
|
|||||||
{ pkgs, inputs, ... }:
|
|
||||||
let
|
|
||||||
inherit (pkgs) lib;
|
|
||||||
in
|
|
||||||
rec {
|
|
||||||
defaultDisabledFeatures = [
|
|
||||||
# dont include experimental features
|
|
||||||
"experimental"
|
|
||||||
# jemalloc profiling/stats features are expensive and shouldn't
|
|
||||||
# be expected on non-debug builds.
|
|
||||||
"jemalloc_prof"
|
|
||||||
"jemalloc_stats"
|
|
||||||
# this is non-functional on nix for some reason
|
|
||||||
"hardened_malloc"
|
|
||||||
# conduwuit_mods is a development-only hot reload feature
|
|
||||||
"conduwuit_mods"
|
|
||||||
# we don't want to enable this feature set by default but be more specific about it
|
|
||||||
"full"
|
|
||||||
];
|
|
||||||
# We perform default-feature unification in nix, because some of the dependencies
|
|
||||||
# on the nix side depend on feature values.
|
|
||||||
calcFeatures =
|
|
||||||
{
|
|
||||||
tomlPath ? "${inputs.self}/src/main",
|
|
||||||
# either a list of feature names or a string "all" which enables all non-default features
|
|
||||||
enabledFeatures ? [ ],
|
|
||||||
disabledFeatures ? defaultDisabledFeatures,
|
|
||||||
default_features ? true,
|
|
||||||
disable_release_max_log_level ? false,
|
|
||||||
}:
|
|
||||||
let
|
|
||||||
# simple helper to get the contents of a Cargo.toml file in a nix format
|
|
||||||
getToml = path: lib.importTOML "${path}/Cargo.toml";
|
|
||||||
|
|
||||||
# get all the features except for the default features
|
|
||||||
allFeatures = lib.pipe tomlPath [
|
|
||||||
getToml
|
|
||||||
(manifest: manifest.features)
|
|
||||||
lib.attrNames
|
|
||||||
(lib.remove "default")
|
|
||||||
];
|
|
||||||
|
|
||||||
# get just the default enabled features
|
|
||||||
allDefaultFeatures = lib.pipe tomlPath [
|
|
||||||
getToml
|
|
||||||
(manifest: manifest.features.default)
|
|
||||||
];
|
|
||||||
|
|
||||||
# depending on the value of enabledFeatures choose just a set or all non-default features
|
|
||||||
#
|
|
||||||
# - [ list of features ] -> choose exactly the features listed
|
|
||||||
# - "all" -> choose all non-default features
|
|
||||||
additionalFeatures = if enabledFeatures == "all" then allFeatures else enabledFeatures;
|
|
||||||
|
|
||||||
# unification with default features (if enabled)
|
|
||||||
features = lib.unique (additionalFeatures ++ lib.optionals default_features allDefaultFeatures);
|
|
||||||
|
|
||||||
# prepare the features that are subtracted from the set
|
|
||||||
disabledFeatures' =
|
|
||||||
disabledFeatures ++ lib.optionals disable_release_max_log_level [ "release_max_log_level" ];
|
|
||||||
|
|
||||||
# construct the final feature set
|
|
||||||
finalFeatures = lib.subtractLists disabledFeatures' features;
|
|
||||||
in
|
|
||||||
{
|
|
||||||
# final feature set, useful for querying it
|
|
||||||
features = finalFeatures;
|
|
||||||
|
|
||||||
# crane flag with the relevant features
|
|
||||||
cargoExtraArgs = builtins.concatStringsSep " " [
|
|
||||||
"--no-default-features"
|
|
||||||
"--locked"
|
|
||||||
(lib.optionalString (finalFeatures != [ ]) "--features")
|
|
||||||
(builtins.concatStringsSep "," finalFeatures)
|
|
||||||
];
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
{
|
||||||
|
perSystem =
|
||||||
|
{ pkgs, ... }:
|
||||||
|
{
|
||||||
|
apps.update-rocksdb = {
|
||||||
|
type = "app";
|
||||||
|
program = pkgs.writeShellApplication {
|
||||||
|
name = "update-rocksdb";
|
||||||
|
runtimeInputs = [ pkgs.nix-update ];
|
||||||
|
text = "nix-update rocksdb -F --version branch";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -4,6 +4,7 @@
|
|||||||
{
|
{
|
||||||
system,
|
system,
|
||||||
lib,
|
lib,
|
||||||
|
pkgs,
|
||||||
...
|
...
|
||||||
}:
|
}:
|
||||||
{
|
{
|
||||||
@@ -11,7 +12,7 @@
|
|||||||
let
|
let
|
||||||
fnx = inputs.fenix.packages.${system};
|
fnx = inputs.fenix.packages.${system};
|
||||||
|
|
||||||
stable = fnx.fromToolchainFile {
|
stable-toolchain = fnx.fromToolchainFile {
|
||||||
file = inputs.self + "/rust-toolchain.toml";
|
file = inputs.self + "/rust-toolchain.toml";
|
||||||
|
|
||||||
# See also `rust-toolchain.toml`
|
# See also `rust-toolchain.toml`
|
||||||
@@ -19,11 +20,10 @@
|
|||||||
};
|
};
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
# used for building nix stuff (doesn't include rustfmt overhead)
|
inherit stable-toolchain;
|
||||||
build-toolchain = stable;
|
|
||||||
# used for dev shells
|
|
||||||
dev-toolchain = fnx.combine [
|
dev-toolchain = fnx.combine [
|
||||||
stable
|
stable-toolchain
|
||||||
# use the nightly rustfmt because we use nightly features
|
# use the nightly rustfmt because we use nightly features
|
||||||
fnx.complete.rustfmt
|
fnx.complete.rustfmt
|
||||||
];
|
];
|
||||||
@@ -1,29 +0,0 @@
|
|||||||
{ inputs, ... }:
|
|
||||||
{
|
|
||||||
perSystem =
|
|
||||||
{
|
|
||||||
self',
|
|
||||||
lib,
|
|
||||||
pkgs,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
let
|
|
||||||
uwulib = inputs.self.uwulib.init pkgs;
|
|
||||||
rocksdbAllFeatures = self'.packages.rocksdb.override {
|
|
||||||
enableJemalloc = true;
|
|
||||||
};
|
|
||||||
in
|
|
||||||
{
|
|
||||||
# basic nix shell containing all things necessary to build continuwuity in all flavors manually (on x86_64-linux)
|
|
||||||
devShells.default = uwulib.build.craneLib.devShell {
|
|
||||||
packages = [
|
|
||||||
pkgs.nodejs
|
|
||||||
pkgs.pkg-config
|
|
||||||
pkgs.liburing
|
|
||||||
pkgs.rust-jemalloc-sys-unprefixed
|
|
||||||
rocksdbAllFeatures
|
|
||||||
];
|
|
||||||
env.LIBCLANG_PATH = lib.makeLibraryPath [ pkgs.llvmPackages.libclang.lib ];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,150 +0,0 @@
|
|||||||
{
|
|
||||||
perSystem =
|
|
||||||
{
|
|
||||||
self',
|
|
||||||
lib,
|
|
||||||
pkgs,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
let
|
|
||||||
baseTestScript =
|
|
||||||
pkgs.writers.writePython3Bin "do_test" { libraries = [ pkgs.python3Packages.matrix-nio ]; }
|
|
||||||
''
|
|
||||||
import asyncio
|
|
||||||
import nio
|
|
||||||
|
|
||||||
|
|
||||||
async def main() -> None:
|
|
||||||
# Connect to continuwuity
|
|
||||||
client = nio.AsyncClient("http://continuwuity:6167", "alice")
|
|
||||||
|
|
||||||
# Register as user alice
|
|
||||||
response = await client.register("alice", "my-secret-password")
|
|
||||||
|
|
||||||
# Log in as user alice
|
|
||||||
response = await client.login("my-secret-password")
|
|
||||||
|
|
||||||
# Create a new room
|
|
||||||
response = await client.room_create(federate=False)
|
|
||||||
print("Matrix room create response:", response)
|
|
||||||
assert isinstance(response, nio.RoomCreateResponse)
|
|
||||||
room_id = response.room_id
|
|
||||||
|
|
||||||
# Join the room
|
|
||||||
response = await client.join(room_id)
|
|
||||||
print("Matrix join response:", response)
|
|
||||||
assert isinstance(response, nio.JoinResponse)
|
|
||||||
|
|
||||||
# Send a message to the room
|
|
||||||
response = await client.room_send(
|
|
||||||
room_id=room_id,
|
|
||||||
message_type="m.room.message",
|
|
||||||
content={
|
|
||||||
"msgtype": "m.text",
|
|
||||||
"body": "Hello continuwuity!"
|
|
||||||
}
|
|
||||||
)
|
|
||||||
print("Matrix room send response:", response)
|
|
||||||
assert isinstance(response, nio.RoomSendResponse)
|
|
||||||
|
|
||||||
# Sync responses
|
|
||||||
response = await client.sync(timeout=30000)
|
|
||||||
print("Matrix sync response:", response)
|
|
||||||
assert isinstance(response, nio.SyncResponse)
|
|
||||||
|
|
||||||
# Check the message was received by continuwuity
|
|
||||||
last_message = response.rooms.join[room_id].timeline.events[-1].body
|
|
||||||
assert last_message == "Hello continuwuity!"
|
|
||||||
|
|
||||||
# Leave the room
|
|
||||||
response = await client.room_leave(room_id)
|
|
||||||
print("Matrix room leave response:", response)
|
|
||||||
assert isinstance(response, nio.RoomLeaveResponse)
|
|
||||||
|
|
||||||
# Close the client
|
|
||||||
await client.close()
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
asyncio.run(main())
|
|
||||||
'';
|
|
||||||
in
|
|
||||||
{
|
|
||||||
# run some nixos tests as checks
|
|
||||||
checks = lib.pipe self'.packages [
|
|
||||||
# we take all packages (names)
|
|
||||||
builtins.attrNames
|
|
||||||
# we filter out all packages that end with `-bin` (which we are interested in for testing)
|
|
||||||
(builtins.filter (lib.hasSuffix "-bin"))
|
|
||||||
# for each of these binaries we built the basic nixos test
|
|
||||||
#
|
|
||||||
# this test was initially yoinked from
|
|
||||||
#
|
|
||||||
# https://github.com/NixOS/nixpkgs/blob/960ce26339661b1b69c6f12b9063ca51b688615f/nixos/tests/matrix/continuwuity.nix
|
|
||||||
(builtins.concatMap (
|
|
||||||
name:
|
|
||||||
builtins.map
|
|
||||||
(
|
|
||||||
{ config, suffix }:
|
|
||||||
{
|
|
||||||
name = "test-${name}-${suffix}";
|
|
||||||
value = pkgs.testers.runNixOSTest {
|
|
||||||
inherit name;
|
|
||||||
|
|
||||||
nodes = {
|
|
||||||
continuwuity = {
|
|
||||||
services.matrix-continuwuity = {
|
|
||||||
enable = true;
|
|
||||||
package = self'.packages.${name};
|
|
||||||
settings = config;
|
|
||||||
extraEnvironment.RUST_BACKTRACE = "yes";
|
|
||||||
};
|
|
||||||
networking.firewall.allowedTCPPorts = [ 6167 ];
|
|
||||||
};
|
|
||||||
client.environment.systemPackages = [ baseTestScript ];
|
|
||||||
};
|
|
||||||
|
|
||||||
testScript = ''
|
|
||||||
start_all()
|
|
||||||
|
|
||||||
with subtest("start continuwuity"):
|
|
||||||
continuwuity.wait_for_unit("continuwuity.service")
|
|
||||||
continuwuity.wait_for_open_port(6167)
|
|
||||||
|
|
||||||
with subtest("ensure messages can be exchanged"):
|
|
||||||
client.succeed("${lib.getExe baseTestScript} >&2")
|
|
||||||
'';
|
|
||||||
|
|
||||||
};
|
|
||||||
}
|
|
||||||
)
|
|
||||||
[
|
|
||||||
{
|
|
||||||
suffix = "base";
|
|
||||||
config = {
|
|
||||||
global = {
|
|
||||||
server_name = name;
|
|
||||||
address = [ "0.0.0.0" ];
|
|
||||||
allow_registration = true;
|
|
||||||
yes_i_am_very_very_sure_i_want_an_open_registration_server_prone_to_abuse = true;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
{
|
|
||||||
suffix = "with-room-version";
|
|
||||||
config = {
|
|
||||||
global = {
|
|
||||||
server_name = name;
|
|
||||||
address = [ "0.0.0.0" ];
|
|
||||||
allow_registration = true;
|
|
||||||
yes_i_am_very_very_sure_i_want_an_open_registration_server_prone_to_abuse = true;
|
|
||||||
default_room_version = "12";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
]
|
|
||||||
))
|
|
||||||
builtins.listToAttrs
|
|
||||||
];
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -2,6 +2,7 @@
|
|||||||
name = "conduwuit_admin"
|
name = "conduwuit_admin"
|
||||||
description.workspace = true
|
description.workspace = true
|
||||||
edition.workspace = true
|
edition.workspace = true
|
||||||
|
homepage.workspace = true
|
||||||
license.workspace = true
|
license.workspace = true
|
||||||
readme.workspace = true
|
readme.workspace = true
|
||||||
repository.workspace = true
|
repository.workspace = true
|
||||||
@@ -79,6 +80,7 @@ conduwuit-database.workspace = true
|
|||||||
conduwuit-macros.workspace = true
|
conduwuit-macros.workspace = true
|
||||||
conduwuit-service.workspace = true
|
conduwuit-service.workspace = true
|
||||||
const-str.workspace = true
|
const-str.workspace = true
|
||||||
|
ctor.workspace = true
|
||||||
futures.workspace = true
|
futures.workspace = true
|
||||||
lettre.workspace = true
|
lettre.workspace = true
|
||||||
log.workspace = true
|
log.workspace = true
|
||||||
|
|||||||
@@ -3,6 +3,8 @@
|
|||||||
#![allow(clippy::enum_glob_use)]
|
#![allow(clippy::enum_glob_use)]
|
||||||
#![allow(clippy::too_many_arguments)]
|
#![allow(clippy::too_many_arguments)]
|
||||||
|
|
||||||
|
conduwuit_macros::introspect_crate! {}
|
||||||
|
|
||||||
pub(crate) mod admin;
|
pub(crate) mod admin;
|
||||||
pub(crate) mod context;
|
pub(crate) mod context;
|
||||||
pub(crate) mod processor;
|
pub(crate) mod processor;
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
use std::{path::PathBuf, sync::Arc};
|
use std::{fmt::Write, path::PathBuf, sync::Arc};
|
||||||
|
|
||||||
use conduwuit::{
|
use conduwuit::{
|
||||||
Err, Result,
|
Err, Result,
|
||||||
@@ -153,3 +153,97 @@ pub(super) async fn shutdown(&self) -> Result {
|
|||||||
|
|
||||||
self.write_str("Shutting down server...").await
|
self.write_str("Shutting down server...").await
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[admin_command]
|
||||||
|
pub(super) async fn list_features(&self) -> Result {
|
||||||
|
let mut enabled_features = conduwuit::info::introspection::ENABLED_FEATURES
|
||||||
|
.lock()
|
||||||
|
.expect("locked")
|
||||||
|
.iter()
|
||||||
|
.flat_map(|(_, f)| f.iter())
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
|
enabled_features.sort_unstable();
|
||||||
|
enabled_features.dedup();
|
||||||
|
|
||||||
|
let mut available_features = conduwuit::build_metadata::WORKSPACE_FEATURES
|
||||||
|
.iter()
|
||||||
|
.flat_map(|(_, f)| f.iter())
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
|
available_features.sort_unstable();
|
||||||
|
available_features.dedup();
|
||||||
|
|
||||||
|
let mut features = String::new();
|
||||||
|
|
||||||
|
for feature in available_features {
|
||||||
|
let active = enabled_features.contains(&feature);
|
||||||
|
let emoji = if active { "✅" } else { "❌" };
|
||||||
|
let remark = if active { "[enabled]" } else { "" };
|
||||||
|
writeln!(features, "{emoji} {feature} {remark}")?;
|
||||||
|
}
|
||||||
|
|
||||||
|
self.write_str(&features).await
|
||||||
|
}
|
||||||
|
|
||||||
|
#[admin_command]
|
||||||
|
pub(super) async fn build_info(&self) -> Result {
|
||||||
|
use conduwuit::build_metadata::built;
|
||||||
|
|
||||||
|
let mut info = String::new();
|
||||||
|
|
||||||
|
// Version information
|
||||||
|
writeln!(info, "# Build Information\n")?;
|
||||||
|
writeln!(info, "**Version:** {}", built::PKG_VERSION)?;
|
||||||
|
writeln!(info, "**Package:** {}", built::PKG_NAME)?;
|
||||||
|
writeln!(info, "**Description:** {}", built::PKG_DESCRIPTION)?;
|
||||||
|
|
||||||
|
// Git information
|
||||||
|
writeln!(info, "\n## Git Information\n")?;
|
||||||
|
if let Some(hash) = conduwuit::build_metadata::GIT_COMMIT_HASH {
|
||||||
|
writeln!(info, "**Commit Hash:** {hash}")?;
|
||||||
|
}
|
||||||
|
if let Some(hash) = conduwuit::build_metadata::GIT_COMMIT_HASH_SHORT {
|
||||||
|
writeln!(info, "**Commit Hash (short):** {hash}")?;
|
||||||
|
}
|
||||||
|
if let Some(url) = conduwuit::build_metadata::GIT_REMOTE_WEB_URL {
|
||||||
|
writeln!(info, "**Repository:** {url}")?;
|
||||||
|
}
|
||||||
|
if let Some(url) = conduwuit::build_metadata::GIT_REMOTE_COMMIT_URL {
|
||||||
|
writeln!(info, "**Commit URL:** {url}")?;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Build environment
|
||||||
|
writeln!(info, "\n## Build Environment\n")?;
|
||||||
|
writeln!(info, "**Profile:** {}", built::PROFILE)?;
|
||||||
|
writeln!(info, "**Optimization Level:** {}", built::OPT_LEVEL)?;
|
||||||
|
writeln!(info, "**Debug:** {}", built::DEBUG)?;
|
||||||
|
writeln!(info, "**Target:** {}", built::TARGET)?;
|
||||||
|
writeln!(info, "**Host:** {}", built::HOST)?;
|
||||||
|
|
||||||
|
// Rust compiler information
|
||||||
|
writeln!(info, "\n## Compiler Information\n")?;
|
||||||
|
writeln!(info, "**Rustc Version:** {}", built::RUSTC_VERSION)?;
|
||||||
|
if !built::RUSTDOC_VERSION.is_empty() {
|
||||||
|
writeln!(info, "**Rustdoc Version:** {}", built::RUSTDOC_VERSION)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Target configuration
|
||||||
|
writeln!(info, "\n## Target Configuration\n")?;
|
||||||
|
writeln!(info, "**Architecture:** {}", built::CFG_TARGET_ARCH)?;
|
||||||
|
writeln!(info, "**OS:** {}", built::CFG_OS)?;
|
||||||
|
writeln!(info, "**Family:** {}", built::CFG_FAMILY)?;
|
||||||
|
writeln!(info, "**Endianness:** {}", built::CFG_ENDIAN)?;
|
||||||
|
writeln!(info, "**Pointer Width:** {} bits", built::CFG_POINTER_WIDTH)?;
|
||||||
|
if !built::CFG_ENV.is_empty() {
|
||||||
|
writeln!(info, "**Environment:** {}", built::CFG_ENV)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
// CI information
|
||||||
|
if let Some(ci) = built::CI_PLATFORM {
|
||||||
|
writeln!(info, "\n## CI Platform\n")?;
|
||||||
|
writeln!(info, "**Platform:** {ci}")?;
|
||||||
|
}
|
||||||
|
|
||||||
|
self.write_str(&info).await
|
||||||
|
}
|
||||||
|
|||||||
@@ -52,4 +52,10 @@ pub enum ServerCommand {
|
|||||||
|
|
||||||
/// Shutdown the server
|
/// Shutdown the server
|
||||||
Shutdown,
|
Shutdown,
|
||||||
|
|
||||||
|
/// List features built into the server
|
||||||
|
ListFeatures,
|
||||||
|
|
||||||
|
/// Build information
|
||||||
|
BuildInfo,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
name = "conduwuit_api"
|
name = "conduwuit_api"
|
||||||
description.workspace = true
|
description.workspace = true
|
||||||
edition.workspace = true
|
edition.workspace = true
|
||||||
|
homepage.workspace = true
|
||||||
license.workspace = true
|
license.workspace = true
|
||||||
readme.workspace = true
|
readme.workspace = true
|
||||||
repository.workspace = true
|
repository.workspace = true
|
||||||
@@ -76,8 +77,10 @@ axum.workspace = true
|
|||||||
base64.workspace = true
|
base64.workspace = true
|
||||||
bytes.workspace = true
|
bytes.workspace = true
|
||||||
conduwuit-core.workspace = true
|
conduwuit-core.workspace = true
|
||||||
|
conduwuit-macros.workspace = true
|
||||||
conduwuit-service.workspace = true
|
conduwuit-service.workspace = true
|
||||||
const-str.workspace = true
|
const-str.workspace = true
|
||||||
|
ctor.workspace = true
|
||||||
futures.workspace = true
|
futures.workspace = true
|
||||||
hmac.workspace = true
|
hmac.workspace = true
|
||||||
http.workspace = true
|
http.workspace = true
|
||||||
|
|||||||
@@ -425,7 +425,9 @@ pub async fn full_user_deactivate(
|
|||||||
// TODO: Redact all messages sent by the user in the room
|
// TODO: Redact all messages sent by the user in the room
|
||||||
}
|
}
|
||||||
|
|
||||||
super::update_all_rooms(services, pdu_queue, user_id).await;
|
super::update_all_rooms(services, pdu_queue, user_id)
|
||||||
|
.boxed()
|
||||||
|
.await;
|
||||||
for room_id in all_joined_rooms {
|
for room_id in all_joined_rooms {
|
||||||
services.rooms.state_cache.forget(room_id, user_id);
|
services.rooms.state_cache.forget(room_id, user_id);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -462,6 +462,31 @@ async fn create_registration_uiaa_session(
|
|||||||
flows.push(untrusted_flow);
|
flows.push(untrusted_flow);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Require all users to agree to the terms and conditions, if configured
|
||||||
|
let terms = &services.config.registration_terms;
|
||||||
|
if !terms.is_empty() {
|
||||||
|
let mut terms =
|
||||||
|
serde_json::to_value(terms.clone()).expect("failed to serialize terms");
|
||||||
|
|
||||||
|
// Insert a dummy `version` field
|
||||||
|
for (_, documents) in terms.as_object_mut().unwrap() {
|
||||||
|
let documents = documents.as_object_mut().unwrap();
|
||||||
|
|
||||||
|
documents.insert("version".to_owned(), "latest".into());
|
||||||
|
}
|
||||||
|
|
||||||
|
params.insert(
|
||||||
|
AuthType::Terms.as_str().to_owned(),
|
||||||
|
serde_json::json!({
|
||||||
|
"policies": terms,
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
for flow in &mut flows {
|
||||||
|
flow.stages.insert(0, AuthType::Terms);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if flows.is_empty() {
|
if flows.is_empty() {
|
||||||
// No flows are configured. Bail out by default
|
// No flows are configured. Bail out by default
|
||||||
// unless open registration was explicitly enabled.
|
// unless open registration was explicitly enabled.
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ use conduwuit::{
|
|||||||
};
|
};
|
||||||
use conduwuit_service::Services;
|
use conduwuit_service::Services;
|
||||||
use futures::{
|
use futures::{
|
||||||
StreamExt, TryStreamExt,
|
FutureExt, StreamExt, TryStreamExt,
|
||||||
future::{join, join3, join4},
|
future::{join, join3, join4},
|
||||||
};
|
};
|
||||||
use ruma::{
|
use ruma::{
|
||||||
@@ -51,6 +51,7 @@ pub(crate) async fn set_displayname_route(
|
|||||||
.await;
|
.await;
|
||||||
|
|
||||||
update_displayname(&services, &body.user_id, body.displayname.clone(), &all_joined_rooms)
|
update_displayname(&services, &body.user_id, body.displayname.clone(), &all_joined_rooms)
|
||||||
|
.boxed()
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
if services.config.allow_local_presence {
|
if services.config.allow_local_presence {
|
||||||
@@ -149,6 +150,7 @@ pub(crate) async fn set_avatar_url_route(
|
|||||||
body.blurhash.clone(),
|
body.blurhash.clone(),
|
||||||
&all_joined_rooms,
|
&all_joined_rooms,
|
||||||
)
|
)
|
||||||
|
.boxed()
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
if services.config.allow_local_presence {
|
if services.config.allow_local_presence {
|
||||||
@@ -344,7 +346,9 @@ pub async fn update_displayname(
|
|||||||
.collect()
|
.collect()
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
update_all_rooms(services, all_joined_rooms, user_id).await;
|
update_all_rooms(services, all_joined_rooms, user_id)
|
||||||
|
.boxed()
|
||||||
|
.await;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn update_avatar_url(
|
pub async fn update_avatar_url(
|
||||||
@@ -394,7 +398,9 @@ pub async fn update_avatar_url(
|
|||||||
.collect()
|
.collect()
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
update_all_rooms(services, all_joined_rooms, user_id).await;
|
update_all_rooms(services, all_joined_rooms, user_id)
|
||||||
|
.boxed()
|
||||||
|
.await;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn update_all_rooms(
|
pub async fn update_all_rooms(
|
||||||
|
|||||||
@@ -137,6 +137,7 @@ pub(crate) async fn upgrade_room_route(
|
|||||||
Some(&body.room_id),
|
Some(&body.room_id),
|
||||||
&state_lock,
|
&state_lock,
|
||||||
)
|
)
|
||||||
|
.boxed()
|
||||||
.await?;
|
.await?;
|
||||||
// Change lock to replacement room
|
// Change lock to replacement room
|
||||||
drop(state_lock);
|
drop(state_lock);
|
||||||
|
|||||||
@@ -60,6 +60,7 @@ pub(crate) async fn send_state_event_for_key_route(
|
|||||||
None
|
None
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
.boxed()
|
||||||
.await?,
|
.await?,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ use std::collections::BTreeMap;
|
|||||||
use axum::extract::State;
|
use axum::extract::State;
|
||||||
use axum_client_ip::InsecureClientIp;
|
use axum_client_ip::InsecureClientIp;
|
||||||
use conduwuit::{Err, Result};
|
use conduwuit::{Err, Result};
|
||||||
use futures::StreamExt;
|
use futures::{FutureExt, StreamExt};
|
||||||
use ruma::{
|
use ruma::{
|
||||||
OwnedRoomId,
|
OwnedRoomId,
|
||||||
api::{
|
api::{
|
||||||
@@ -112,6 +112,7 @@ pub(crate) async fn set_profile_key_route(
|
|||||||
Some(display_name.to_owned()),
|
Some(display_name.to_owned()),
|
||||||
&all_joined_rooms,
|
&all_joined_rooms,
|
||||||
)
|
)
|
||||||
|
.boxed()
|
||||||
.await;
|
.await;
|
||||||
} else if body.key_name == "avatar_url" {
|
} else if body.key_name == "avatar_url" {
|
||||||
let Some(avatar_url) = profile_key_value.as_str() else {
|
let Some(avatar_url) = profile_key_value.as_str() else {
|
||||||
@@ -127,7 +128,9 @@ pub(crate) async fn set_profile_key_route(
|
|||||||
.collect()
|
.collect()
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
update_avatar_url(&services, &body.user_id, Some(mxc), None, &all_joined_rooms).await;
|
update_avatar_url(&services, &body.user_id, Some(mxc), None, &all_joined_rooms)
|
||||||
|
.boxed()
|
||||||
|
.await;
|
||||||
} else {
|
} else {
|
||||||
services.users.set_profile_key(
|
services.users.set_profile_key(
|
||||||
&body.user_id,
|
&body.user_id,
|
||||||
@@ -178,7 +181,9 @@ pub(crate) async fn delete_profile_key_route(
|
|||||||
.collect()
|
.collect()
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
update_displayname(&services, &body.user_id, None, &all_joined_rooms).await;
|
update_displayname(&services, &body.user_id, None, &all_joined_rooms)
|
||||||
|
.boxed()
|
||||||
|
.await;
|
||||||
} else if body.key_name == "avatar_url" {
|
} else if body.key_name == "avatar_url" {
|
||||||
let all_joined_rooms: Vec<OwnedRoomId> = services
|
let all_joined_rooms: Vec<OwnedRoomId> = services
|
||||||
.rooms
|
.rooms
|
||||||
@@ -188,7 +193,9 @@ pub(crate) async fn delete_profile_key_route(
|
|||||||
.collect()
|
.collect()
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
update_avatar_url(&services, &body.user_id, None, None, &all_joined_rooms).await;
|
update_avatar_url(&services, &body.user_id, None, None, &all_joined_rooms)
|
||||||
|
.boxed()
|
||||||
|
.await;
|
||||||
} else {
|
} else {
|
||||||
services
|
services
|
||||||
.users
|
.users
|
||||||
|
|||||||
@@ -71,6 +71,7 @@ pub(crate) async fn well_known_support(
|
|||||||
|
|
||||||
let email_address = services.config.well_known.support_email.clone();
|
let email_address = services.config.well_known.support_email.clone();
|
||||||
let matrix_id = services.config.well_known.support_mxid.clone();
|
let matrix_id = services.config.well_known.support_mxid.clone();
|
||||||
|
let pgp_key = services.config.well_known.support_pgp_key.clone();
|
||||||
|
|
||||||
// TODO: support defining multiple contacts in the config
|
// TODO: support defining multiple contacts in the config
|
||||||
let mut contacts: Vec<Contact> = vec![];
|
let mut contacts: Vec<Contact> = vec![];
|
||||||
@@ -88,6 +89,7 @@ pub(crate) async fn well_known_support(
|
|||||||
role: role_value.clone(),
|
role: role_value.clone(),
|
||||||
email_address: email_address.clone(),
|
email_address: email_address.clone(),
|
||||||
matrix_id: matrix_id.clone(),
|
matrix_id: matrix_id.clone(),
|
||||||
|
pgp_key: pgp_key.clone(),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -104,6 +106,7 @@ pub(crate) async fn well_known_support(
|
|||||||
role: role_value.clone(),
|
role: role_value.clone(),
|
||||||
email_address: None,
|
email_address: None,
|
||||||
matrix_id: Some(user_id.to_owned()),
|
matrix_id: Some(user_id.to_owned()),
|
||||||
|
pgp_key: None,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,9 @@
|
|||||||
|
|
||||||
extern crate conduwuit_core as conduwuit;
|
extern crate conduwuit_core as conduwuit;
|
||||||
extern crate conduwuit_service as service;
|
extern crate conduwuit_service as service;
|
||||||
|
|
||||||
|
conduwuit_macros::introspect_crate! {}
|
||||||
|
|
||||||
pub mod client;
|
pub mod client;
|
||||||
pub mod router;
|
pub mod router;
|
||||||
pub mod server;
|
pub mod server;
|
||||||
|
|||||||
@@ -1,11 +1,13 @@
|
|||||||
use std::borrow::ToOwned;
|
use std::borrow::ToOwned;
|
||||||
|
|
||||||
use axum::extract::State;
|
use axum::extract::State;
|
||||||
use conduwuit::{Err, Error, Result, debug, debug_info, info, matrix::pdu::PduBuilder, warn};
|
use conduwuit::{
|
||||||
|
Err, Error, Result, debug, debug_info, info, matrix::pdu::PduBuilder, utils, warn,
|
||||||
|
};
|
||||||
use conduwuit_service::Services;
|
use conduwuit_service::Services;
|
||||||
use futures::StreamExt;
|
use futures::StreamExt;
|
||||||
use ruma::{
|
use ruma::{
|
||||||
CanonicalJsonObject, OwnedUserId, RoomId, RoomVersionId, UserId,
|
OwnedUserId, RoomId, RoomVersionId, UserId,
|
||||||
api::{client::error::ErrorKind, federation::membership::prepare_join_event},
|
api::{client::error::ErrorKind, federation::membership::prepare_join_event},
|
||||||
events::{
|
events::{
|
||||||
StateEventType,
|
StateEventType,
|
||||||
@@ -40,6 +42,7 @@ pub(crate) async fn create_join_event_template_route(
|
|||||||
{
|
{
|
||||||
info!(
|
info!(
|
||||||
origin = body.origin().as_str(),
|
origin = body.origin().as_str(),
|
||||||
|
room_id = %body.room_id,
|
||||||
"Refusing to serve make_join for room we aren't participating in"
|
"Refusing to serve make_join for room we aren't participating in"
|
||||||
);
|
);
|
||||||
return Err!(Request(NotFound("This server is not participating in that room.")));
|
return Err!(Request(NotFound("This server is not participating in that room.")));
|
||||||
@@ -133,10 +136,10 @@ pub(crate) async fn create_join_event_template_route(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let (_pdu, mut pdu_json) = services
|
let (pdu, _) = services
|
||||||
.rooms
|
.rooms
|
||||||
.timeline
|
.timeline
|
||||||
.create_hash_and_sign_event(
|
.create_event(
|
||||||
PduBuilder::state(body.user_id.to_string(), &RoomMemberEventContent {
|
PduBuilder::state(body.user_id.to_string(), &RoomMemberEventContent {
|
||||||
join_authorized_via_users_server,
|
join_authorized_via_users_server,
|
||||||
..RoomMemberEventContent::new(MembershipState::Join)
|
..RoomMemberEventContent::new(MembershipState::Join)
|
||||||
@@ -147,6 +150,8 @@ pub(crate) async fn create_join_event_template_route(
|
|||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
drop(state_lock);
|
drop(state_lock);
|
||||||
|
let mut pdu_json = utils::to_canonical_object(&pdu)
|
||||||
|
.expect("Barebones PDU should be convertible to canonical JSON");
|
||||||
pdu_json.remove("event_id");
|
pdu_json.remove("event_id");
|
||||||
|
|
||||||
Ok(prepare_join_event::v1::Response {
|
Ok(prepare_join_event::v1::Response {
|
||||||
@@ -297,18 +302,3 @@ pub(crate) async fn user_can_perform_restricted_join(
|
|||||||
)))
|
)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn maybe_strip_event_id(
|
|
||||||
pdu_json: &mut CanonicalJsonObject,
|
|
||||||
room_version_id: &RoomVersionId,
|
|
||||||
) -> Result {
|
|
||||||
use RoomVersionId::*;
|
|
||||||
|
|
||||||
match room_version_id {
|
|
||||||
| V1 | V2 => Ok(()),
|
|
||||||
| _ => {
|
|
||||||
pdu_json.remove("event_id");
|
|
||||||
Ok(())
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
use RoomVersionId::*;
|
use RoomVersionId::*;
|
||||||
use axum::extract::State;
|
use axum::extract::State;
|
||||||
use conduwuit::{Err, Error, Result, debug_warn, info, matrix::pdu::PduBuilder, warn};
|
use conduwuit::{Err, Error, Result, debug_warn, info, matrix::pdu::PduBuilder, utils, warn};
|
||||||
use ruma::{
|
use ruma::{
|
||||||
RoomVersionId,
|
RoomVersionId,
|
||||||
api::{client::error::ErrorKind, federation::knock::create_knock_event_template},
|
api::{client::error::ErrorKind, federation::knock::create_knock_event_template},
|
||||||
@@ -28,6 +28,7 @@ pub(crate) async fn create_knock_event_template_route(
|
|||||||
{
|
{
|
||||||
info!(
|
info!(
|
||||||
origin = body.origin().as_str(),
|
origin = body.origin().as_str(),
|
||||||
|
room_id = %body.room_id,
|
||||||
"Refusing to serve make_knock for room we aren't participating in"
|
"Refusing to serve make_knock for room we aren't participating in"
|
||||||
);
|
);
|
||||||
return Err!(Request(NotFound("This server is not participating in that room.")));
|
return Err!(Request(NotFound("This server is not participating in that room.")));
|
||||||
@@ -98,10 +99,10 @@ pub(crate) async fn create_knock_event_template_route(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let (_pdu, mut pdu_json) = services
|
let (pdu, _) = services
|
||||||
.rooms
|
.rooms
|
||||||
.timeline
|
.timeline
|
||||||
.create_hash_and_sign_event(
|
.create_event(
|
||||||
PduBuilder::state(
|
PduBuilder::state(
|
||||||
body.user_id.to_string(),
|
body.user_id.to_string(),
|
||||||
&RoomMemberEventContent::new(MembershipState::Knock),
|
&RoomMemberEventContent::new(MembershipState::Knock),
|
||||||
@@ -113,9 +114,9 @@ pub(crate) async fn create_knock_event_template_route(
|
|||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
drop(state_lock);
|
drop(state_lock);
|
||||||
|
let mut pdu_json = utils::to_canonical_object(&pdu)
|
||||||
// room v3 and above removed the "event_id" field from remote PDU format
|
.expect("Barebones PDU should be convertible to canonical JSON");
|
||||||
super::maybe_strip_event_id(&mut pdu_json, &room_version_id)?;
|
pdu_json.remove("event_id");
|
||||||
|
|
||||||
Ok(create_knock_event_template::v1::Response {
|
Ok(create_knock_event_template::v1::Response {
|
||||||
room_version: room_version_id,
|
room_version: room_version_id,
|
||||||
|
|||||||
@@ -1,12 +1,11 @@
|
|||||||
use axum::extract::State;
|
use axum::extract::State;
|
||||||
use conduwuit::{Err, Result, info, matrix::pdu::PduBuilder};
|
use conduwuit::{Err, Result, info, matrix::pdu::PduBuilder, utils};
|
||||||
use ruma::{
|
use ruma::{
|
||||||
api::federation::membership::prepare_leave_event,
|
api::federation::membership::prepare_leave_event,
|
||||||
events::room::member::{MembershipState, RoomMemberEventContent},
|
events::room::member::{MembershipState, RoomMemberEventContent},
|
||||||
};
|
};
|
||||||
use serde_json::value::to_raw_value;
|
use serde_json::value::to_raw_value;
|
||||||
|
|
||||||
use super::make_join::maybe_strip_event_id;
|
|
||||||
use crate::Ruma;
|
use crate::Ruma;
|
||||||
|
|
||||||
/// # `GET /_matrix/federation/v1/make_leave/{roomId}/{eventId}`
|
/// # `GET /_matrix/federation/v1/make_leave/{roomId}/{eventId}`
|
||||||
@@ -49,10 +48,10 @@ pub(crate) async fn create_leave_event_template_route(
|
|||||||
let room_version_id = services.rooms.state.get_room_version(&body.room_id).await?;
|
let room_version_id = services.rooms.state.get_room_version(&body.room_id).await?;
|
||||||
let state_lock = services.rooms.state.mutex.lock(&body.room_id).await;
|
let state_lock = services.rooms.state.mutex.lock(&body.room_id).await;
|
||||||
|
|
||||||
let (_pdu, mut pdu_json) = services
|
let (pdu, _) = services
|
||||||
.rooms
|
.rooms
|
||||||
.timeline
|
.timeline
|
||||||
.create_hash_and_sign_event(
|
.create_event(
|
||||||
PduBuilder::state(
|
PduBuilder::state(
|
||||||
body.user_id.to_string(),
|
body.user_id.to_string(),
|
||||||
&RoomMemberEventContent::new(MembershipState::Leave),
|
&RoomMemberEventContent::new(MembershipState::Leave),
|
||||||
@@ -64,9 +63,9 @@ pub(crate) async fn create_leave_event_template_route(
|
|||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
drop(state_lock);
|
drop(state_lock);
|
||||||
|
let mut pdu_json = utils::to_canonical_object(&pdu)
|
||||||
// room v3 and above removed the "event_id" field from remote PDU format
|
.expect("Barebones PDU should be convertible to canonical JSON");
|
||||||
maybe_strip_event_id(&mut pdu_json, &room_version_id)?;
|
pdu_json.remove("event_id");
|
||||||
|
|
||||||
Ok(prepare_leave_event::v1::Response {
|
Ok(prepare_leave_event::v1::Response {
|
||||||
room_version: Some(room_version_id),
|
room_version: Some(room_version_id),
|
||||||
|
|||||||
@@ -187,13 +187,14 @@ async fn create_join_event(
|
|||||||
"Joining user did not pass restricted room's rules."
|
"Joining user did not pass restricted room's rules."
|
||||||
)));
|
)));
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
trace!("Signing send_join event");
|
services
|
||||||
services
|
.server_keys
|
||||||
.server_keys
|
.hash_and_sign_event(&mut value, &room_version_id)
|
||||||
.hash_and_sign_event(&mut value, &room_version_id)
|
.map_err(|e| {
|
||||||
.map_err(|e| err!(Request(InvalidParam(warn!("Failed to sign send_join event: {e}")))))?;
|
err!(Request(InvalidParam(warn!("Failed to sign send_join event: {e}"))))
|
||||||
|
})?;
|
||||||
|
}
|
||||||
|
|
||||||
let mutex_lock = services
|
let mutex_lock = services
|
||||||
.rooms
|
.rooms
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
name = "conduwuit_build_metadata"
|
name = "conduwuit_build_metadata"
|
||||||
description.workspace = true
|
description.workspace = true
|
||||||
edition.workspace = true
|
edition.workspace = true
|
||||||
|
homepage.workspace = true
|
||||||
license.workspace = true
|
license.workspace = true
|
||||||
readme.workspace = true
|
readme.workspace = true
|
||||||
repository.workspace = true
|
repository.workspace = true
|
||||||
@@ -27,6 +28,6 @@ crate-type = [
|
|||||||
|
|
||||||
[build-dependencies]
|
[build-dependencies]
|
||||||
built = { version = "0.8", features = [] }
|
built = { version = "0.8", features = [] }
|
||||||
|
cargo_metadata = { version = "0.23.1" }
|
||||||
[lints]
|
[lints]
|
||||||
workspace = true
|
workspace = true
|
||||||
|
|||||||
@@ -1,5 +1,9 @@
|
|||||||
use std::process::Command;
|
use std::{
|
||||||
|
collections::BTreeMap, env, fmt::Write as FmtWrite, fs, io::Write, path::Path,
|
||||||
|
process::Command,
|
||||||
|
};
|
||||||
|
|
||||||
|
use cargo_metadata::MetadataCommand;
|
||||||
fn run_git_command(args: &[&str]) -> Option<String> {
|
fn run_git_command(args: &[&str]) -> Option<String> {
|
||||||
Command::new("git")
|
Command::new("git")
|
||||||
.args(args)
|
.args(args)
|
||||||
@@ -11,12 +15,60 @@ fn run_git_command(args: &[&str]) -> Option<String> {
|
|||||||
.filter(|s| !s.is_empty())
|
.filter(|s| !s.is_empty())
|
||||||
}
|
}
|
||||||
fn get_env(env_var: &str) -> Option<String> {
|
fn get_env(env_var: &str) -> Option<String> {
|
||||||
match std::env::var(env_var) {
|
match env::var(env_var) {
|
||||||
| Ok(val) if !val.is_empty() => Some(val),
|
| Ok(val) if !val.is_empty() => Some(val),
|
||||||
| _ => None,
|
| _ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn main() {
|
fn main() {
|
||||||
|
println!("cargo:rerun-if-changed=Cargo.toml");
|
||||||
|
|
||||||
|
let manifest_dir = env::var("CARGO_MANIFEST_DIR").unwrap(); // Cargo.toml path
|
||||||
|
let manifest_path = Path::new(&manifest_dir).join("Cargo.toml");
|
||||||
|
|
||||||
|
let metadata = MetadataCommand::new()
|
||||||
|
.manifest_path(&manifest_path)
|
||||||
|
.no_deps()
|
||||||
|
.exec()
|
||||||
|
.expect("failed to parse `cargo metadata`");
|
||||||
|
|
||||||
|
let workspace_packages = metadata
|
||||||
|
.workspace_members
|
||||||
|
.iter()
|
||||||
|
.map(|package| {
|
||||||
|
let package = metadata.packages.iter().find(|p| p.id == *package).unwrap();
|
||||||
|
println!("cargo:rerun-if-changed={}", package.manifest_path.as_str());
|
||||||
|
package
|
||||||
|
})
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
|
// Extract available features from workspace packages
|
||||||
|
let mut available_features: BTreeMap<String, Vec<String>> = BTreeMap::new();
|
||||||
|
for package in &workspace_packages {
|
||||||
|
let crate_name = package
|
||||||
|
.name
|
||||||
|
.trim_start_matches("conduwuit-")
|
||||||
|
.replace('-', "_");
|
||||||
|
let features: Vec<String> = package.features.keys().cloned().collect();
|
||||||
|
if !features.is_empty() {
|
||||||
|
available_features.insert(crate_name, features);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generate Rust code for available features
|
||||||
|
let features_code = generate_features_code(&available_features);
|
||||||
|
let features_dst =
|
||||||
|
Path::new(&env::var("OUT_DIR").expect("OUT_DIR not set")).join("available_features.rs");
|
||||||
|
let mut features_file = fs::File::create(features_dst).unwrap();
|
||||||
|
features_file.write_all(features_code.as_bytes()).unwrap();
|
||||||
|
|
||||||
|
let dst = Path::new(&env::var("OUT_DIR").expect("OUT_DIR not set")).join("pkg.json");
|
||||||
|
|
||||||
|
let mut out_file = fs::File::create(dst).unwrap();
|
||||||
|
out_file
|
||||||
|
.write_all(format!("{workspace_packages:?}").as_bytes())
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
// built gets the default crate from the workspace. Not sure if this is intended
|
// built gets the default crate from the workspace. Not sure if this is intended
|
||||||
// behavior, but it's what we want.
|
// behavior, but it's what we want.
|
||||||
built::write_built_file().expect("Failed to acquire build-time information");
|
built::write_built_file().expect("Failed to acquire build-time information");
|
||||||
@@ -91,3 +143,30 @@ fn main() {
|
|||||||
println!("cargo:rerun-if-env-changed=GIT_REMOTE_URL");
|
println!("cargo:rerun-if-env-changed=GIT_REMOTE_URL");
|
||||||
println!("cargo:rerun-if-env-changed=GIT_REMOTE_COMMIT_URL");
|
println!("cargo:rerun-if-env-changed=GIT_REMOTE_COMMIT_URL");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn generate_features_code(features: &BTreeMap<String, Vec<String>>) -> String {
|
||||||
|
let mut code = String::from(
|
||||||
|
r#"
|
||||||
|
/// All available features for workspace crates
|
||||||
|
pub const WORKSPACE_FEATURES: &[(&str, &[&str])] = &[
|
||||||
|
"#,
|
||||||
|
);
|
||||||
|
|
||||||
|
for (crate_name, feature_list) in features {
|
||||||
|
write!(code, " (\"{crate_name}\", &[").unwrap();
|
||||||
|
for (i, feature) in feature_list.iter().enumerate() {
|
||||||
|
if i > 0 {
|
||||||
|
code.push_str(", ");
|
||||||
|
}
|
||||||
|
write!(code, "\"{feature}\"").unwrap();
|
||||||
|
}
|
||||||
|
code.push_str("]),\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
code.push_str(
|
||||||
|
r#"];
|
||||||
|
"#,
|
||||||
|
);
|
||||||
|
|
||||||
|
code
|
||||||
|
}
|
||||||
|
|||||||
@@ -2,6 +2,10 @@ pub mod built {
|
|||||||
include!(concat!(env!("OUT_DIR"), "/built.rs"));
|
include!(concat!(env!("OUT_DIR"), "/built.rs"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Include generated available features
|
||||||
|
// This provides: pub const WORKSPACE_FEATURES: &[(&str, &[&str])]
|
||||||
|
include!(concat!(env!("OUT_DIR"), "/available_features.rs"));
|
||||||
|
|
||||||
pub static GIT_COMMIT_HASH: Option<&str> = option_env!("GIT_COMMIT_HASH");
|
pub static GIT_COMMIT_HASH: Option<&str> = option_env!("GIT_COMMIT_HASH");
|
||||||
|
|
||||||
pub static GIT_COMMIT_HASH_SHORT: Option<&str> = option_env!("GIT_COMMIT_HASH_SHORT");
|
pub static GIT_COMMIT_HASH_SHORT: Option<&str> = option_env!("GIT_COMMIT_HASH_SHORT");
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
name = "conduwuit_core"
|
name = "conduwuit_core"
|
||||||
description.workspace = true
|
description.workspace = true
|
||||||
edition.workspace = true
|
edition.workspace = true
|
||||||
|
homepage.workspace = true
|
||||||
license.workspace = true
|
license.workspace = true
|
||||||
readme.workspace = true
|
readme.workspace = true
|
||||||
repository.workspace = true
|
repository.workspace = true
|
||||||
|
|||||||
+27
-2
@@ -4,7 +4,7 @@ pub mod manager;
|
|||||||
pub mod proxy;
|
pub mod proxy;
|
||||||
|
|
||||||
use std::{
|
use std::{
|
||||||
collections::{BTreeMap, BTreeSet},
|
collections::{BTreeMap, BTreeSet, HashMap},
|
||||||
net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr},
|
net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr},
|
||||||
path::PathBuf,
|
path::PathBuf,
|
||||||
};
|
};
|
||||||
@@ -22,7 +22,7 @@ use ruma::{
|
|||||||
OwnedRoomId, OwnedRoomOrAliasId, OwnedServerName, OwnedUserId, RoomVersionId,
|
OwnedRoomId, OwnedRoomOrAliasId, OwnedServerName, OwnedUserId, RoomVersionId,
|
||||||
api::client::discovery::{discover_homeserver::RtcFocusInfo, discover_support::ContactRole},
|
api::client::discovery::{discover_homeserver::RtcFocusInfo, discover_support::ContactRole},
|
||||||
};
|
};
|
||||||
use serde::{Deserialize, de::IgnoredAny};
|
use serde::{Deserialize, Serialize, de::IgnoredAny};
|
||||||
use url::Url;
|
use url::Url;
|
||||||
|
|
||||||
use self::proxy::ProxyConfig;
|
use self::proxy::ProxyConfig;
|
||||||
@@ -655,6 +655,20 @@ pub struct Config {
|
|||||||
/// even if `recaptcha_site_key` is set.
|
/// even if `recaptcha_site_key` is set.
|
||||||
pub recaptcha_private_site_key: Option<String>,
|
pub recaptcha_private_site_key: Option<String>,
|
||||||
|
|
||||||
|
/// Policy documents, such as terms and conditions or a privacy policy,
|
||||||
|
/// which users must agree to when registering an account.
|
||||||
|
///
|
||||||
|
/// Example:
|
||||||
|
/// ```ignore
|
||||||
|
/// [global.registration_terms.privacy_policy]
|
||||||
|
/// en = { name = "Privacy Policy", url = "https://homeserver.example/en/privacy_policy.html" }
|
||||||
|
/// es = { name = "Política de Privacidad", url = "https://homeserver.example/es/privacy_policy.html" }
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// default: {}
|
||||||
|
#[serde(default)]
|
||||||
|
pub registration_terms: HashMap<String, HashMap<String, TermsDocument>>,
|
||||||
|
|
||||||
/// Controls whether encrypted rooms and events are allowed.
|
/// Controls whether encrypted rooms and events are allowed.
|
||||||
#[serde(default = "true_fn")]
|
#[serde(default = "true_fn")]
|
||||||
pub allow_encryption: bool,
|
pub allow_encryption: bool,
|
||||||
@@ -2191,6 +2205,10 @@ pub struct WellKnownConfig {
|
|||||||
/// listed.
|
/// listed.
|
||||||
pub support_mxid: Option<OwnedUserId>,
|
pub support_mxid: Option<OwnedUserId>,
|
||||||
|
|
||||||
|
/// PGP key URI for server support contacts, to be served as part of the
|
||||||
|
/// MSC1929 server support endpoint.
|
||||||
|
pub support_pgp_key: Option<String>,
|
||||||
|
|
||||||
/// **DEPRECATED**: Use `[global.matrix_rtc].foci` instead.
|
/// **DEPRECATED**: Use `[global.matrix_rtc].foci` instead.
|
||||||
///
|
///
|
||||||
/// A list of MatrixRTC foci URLs which will be served as part of the
|
/// A list of MatrixRTC foci URLs which will be served as part of the
|
||||||
@@ -2494,6 +2512,13 @@ pub struct SmtpConfig {
|
|||||||
pub require_email_for_token_registration: bool,
|
pub require_email_for_token_registration: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// A policy document for use with a m.login.terms stage.
|
||||||
|
#[derive(Clone, Debug, Deserialize, Serialize)]
|
||||||
|
pub struct TermsDocument {
|
||||||
|
pub name: String,
|
||||||
|
pub url: String,
|
||||||
|
}
|
||||||
|
|
||||||
const DEPRECATED_KEYS: &[&str] = &[
|
const DEPRECATED_KEYS: &[&str] = &[
|
||||||
"cache_capacity",
|
"cache_capacity",
|
||||||
"conduit_cache_capacity_modifier",
|
"conduit_cache_capacity_modifier",
|
||||||
|
|||||||
@@ -0,0 +1,7 @@
|
|||||||
|
//! Information about features the crates were compiled with.
|
||||||
|
//! Only available for crates that have called the `introspect_crate` macro
|
||||||
|
|
||||||
|
use std::collections::BTreeMap;
|
||||||
|
|
||||||
|
pub static ENABLED_FEATURES: std::sync::Mutex<BTreeMap<&str, &[&str]>> =
|
||||||
|
std::sync::Mutex::new(BTreeMap::new());
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
|
pub mod introspection;
|
||||||
pub mod room_version;
|
pub mod room_version;
|
||||||
pub mod version;
|
pub mod version;
|
||||||
|
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ pub use ::smallstr;
|
|||||||
pub use ::smallvec;
|
pub use ::smallvec;
|
||||||
pub use ::toml;
|
pub use ::toml;
|
||||||
pub use ::tracing;
|
pub use ::tracing;
|
||||||
|
pub use conduwuit_build_metadata as build_metadata;
|
||||||
pub use config::Config;
|
pub use config::Config;
|
||||||
pub use error::Error;
|
pub use error::Error;
|
||||||
pub use info::{
|
pub use info::{
|
||||||
@@ -34,6 +35,8 @@ pub use utils::{implement, result, result::Result};
|
|||||||
|
|
||||||
pub use crate as conduwuit_core;
|
pub use crate as conduwuit_core;
|
||||||
|
|
||||||
|
conduwuit_macros::introspect_crate! {}
|
||||||
|
|
||||||
#[cfg(any(not(conduwuit_mods), not(feature = "conduwuit_mods")))]
|
#[cfg(any(not(conduwuit_mods), not(feature = "conduwuit_mods")))]
|
||||||
pub mod mods {
|
pub mod mods {
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
name = "conduwuit_database"
|
name = "conduwuit_database"
|
||||||
description.workspace = true
|
description.workspace = true
|
||||||
edition.workspace = true
|
edition.workspace = true
|
||||||
|
homepage.workspace = true
|
||||||
license.workspace = true
|
license.workspace = true
|
||||||
readme.workspace = true
|
readme.workspace = true
|
||||||
repository.workspace = true
|
repository.workspace = true
|
||||||
@@ -54,7 +55,9 @@ bindgen-runtime = [
|
|||||||
[dependencies]
|
[dependencies]
|
||||||
async-channel.workspace = true
|
async-channel.workspace = true
|
||||||
conduwuit-core.workspace = true
|
conduwuit-core.workspace = true
|
||||||
|
conduwuit-macros.workspace = true
|
||||||
const-str.workspace = true
|
const-str.workspace = true
|
||||||
|
ctor.workspace = true
|
||||||
futures.workspace = true
|
futures.workspace = true
|
||||||
log.workspace = true
|
log.workspace = true
|
||||||
minicbor.workspace = true
|
minicbor.workspace = true
|
||||||
|
|||||||
@@ -70,17 +70,19 @@ fn descriptor_cf_options(
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut opts = opts
|
let opts = opts
|
||||||
.get_options_from_string("{{arena_block_size=2097152;}}")
|
.get_options_from_string("{{arena_block_size=2097152;}}")
|
||||||
.map_err(map_err)?;
|
.map_err(map_err)?;
|
||||||
|
|
||||||
#[cfg(debug_assertions)]
|
#[cfg(debug_assertions)]
|
||||||
let opts = opts
|
let opts = {
|
||||||
.get_options_from_string(
|
let mut opts = opts;
|
||||||
|
opts.get_options_from_string(
|
||||||
"{{paranoid_checks=true;paranoid_file_checks=true;force_consistency_checks=true;\
|
"{{paranoid_checks=true;paranoid_file_checks=true;force_consistency_checks=true;\
|
||||||
verify_sst_unique_id_in_manifest=true;}}",
|
verify_sst_unique_id_in_manifest=true;}}",
|
||||||
)
|
)
|
||||||
.map_err(map_err)?;
|
.map_err(map_err)?
|
||||||
|
};
|
||||||
|
|
||||||
Ok(opts)
|
Ok(opts)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,8 @@
|
|||||||
extern crate conduwuit_core as conduwuit;
|
extern crate conduwuit_core as conduwuit;
|
||||||
extern crate rust_rocksdb as rocksdb;
|
extern crate rust_rocksdb as rocksdb;
|
||||||
|
|
||||||
|
conduwuit_macros::introspect_crate! {}
|
||||||
|
|
||||||
conduwuit::mod_ctor! {}
|
conduwuit::mod_ctor! {}
|
||||||
conduwuit::mod_dtor! {}
|
conduwuit::mod_dtor! {}
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
name = "conduwuit_macros"
|
name = "conduwuit_macros"
|
||||||
description.workspace = true
|
description.workspace = true
|
||||||
edition.workspace = true
|
edition.workspace = true
|
||||||
|
homepage.workspace = true
|
||||||
license.workspace = true
|
license.workspace = true
|
||||||
readme.workspace = true
|
readme.workspace = true
|
||||||
repository.workspace = true
|
repository.workspace = true
|
||||||
@@ -17,6 +18,7 @@ syn.workspace = true
|
|||||||
quote.workspace = true
|
quote.workspace = true
|
||||||
proc-macro2.workspace = true
|
proc-macro2.workspace = true
|
||||||
itertools.workspace = true
|
itertools.workspace = true
|
||||||
|
cargo_toml.workspace = true
|
||||||
|
|
||||||
[lints]
|
[lints]
|
||||||
workspace = true
|
workspace = true
|
||||||
|
|||||||
@@ -0,0 +1,63 @@
|
|||||||
|
use proc_macro2::TokenStream;
|
||||||
|
use quote::quote;
|
||||||
|
|
||||||
|
use crate::Result;
|
||||||
|
|
||||||
|
pub(super) fn introspect(_args: TokenStream) -> Result<TokenStream> {
|
||||||
|
let cargo_crate_name = std::env::var("CARGO_CRATE_NAME").unwrap();
|
||||||
|
let crate_name = cargo_crate_name.trim_start_matches("conduwuit_");
|
||||||
|
let is_core = cargo_crate_name == "conduwuit_core";
|
||||||
|
|
||||||
|
let flags = std::env::args().collect::<Vec<_>>();
|
||||||
|
|
||||||
|
let mut enabled_features = Vec::new();
|
||||||
|
append_features(&mut enabled_features, flags);
|
||||||
|
|
||||||
|
let enabled_count = enabled_features.len();
|
||||||
|
|
||||||
|
let import_path = if is_core {
|
||||||
|
quote! { use crate::conduwuit_core; }
|
||||||
|
} else {
|
||||||
|
quote! { use ::conduwuit_core; }
|
||||||
|
};
|
||||||
|
|
||||||
|
let ret = quote! {
|
||||||
|
#[doc(hidden)]
|
||||||
|
mod __compile_introspection {
|
||||||
|
#import_path
|
||||||
|
|
||||||
|
/// Features that were enabled when this crate was compiled
|
||||||
|
const ENABLED: [&str; #enabled_count] = [#( #enabled_features ),*];
|
||||||
|
|
||||||
|
const CRATE_NAME: &str = #crate_name;
|
||||||
|
|
||||||
|
/// Register this crate's features with the global registry during static initialization
|
||||||
|
#[::ctor::ctor]
|
||||||
|
fn register() {
|
||||||
|
conduwuit_core::info::introspection::ENABLED_FEATURES.lock().unwrap().insert(#crate_name, &ENABLED);
|
||||||
|
}
|
||||||
|
#[::ctor::dtor]
|
||||||
|
fn unregister() {
|
||||||
|
conduwuit_core::info::introspection::ENABLED_FEATURES.lock().unwrap().remove(#crate_name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(ret)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn append_features(features: &mut Vec<String>, flags: Vec<String>) {
|
||||||
|
let mut next_is_cfg = false;
|
||||||
|
for flag in flags {
|
||||||
|
let is_cfg = flag == "--cfg";
|
||||||
|
let is_feature = flag.starts_with("feature=");
|
||||||
|
if std::mem::replace(&mut next_is_cfg, is_cfg) && is_feature {
|
||||||
|
if let Some(feature) = flag
|
||||||
|
.split_once('=')
|
||||||
|
.map(|(_, feature)| feature.trim_matches('"'))
|
||||||
|
{
|
||||||
|
features.push(feature.to_owned());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
mod admin;
|
mod admin;
|
||||||
|
mod build_info;
|
||||||
mod config;
|
mod config;
|
||||||
mod debug;
|
mod debug;
|
||||||
mod implement;
|
mod implement;
|
||||||
@@ -44,6 +45,13 @@ pub fn config_example_generator(args: TokenStream, input: TokenStream) -> TokenS
|
|||||||
attribute_macro::<ItemStruct, _>(args, input, config::example_generator)
|
attribute_macro::<ItemStruct, _>(args, input, config::example_generator)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[proc_macro]
|
||||||
|
pub fn introspect_crate(input: TokenStream) -> TokenStream {
|
||||||
|
build_info::introspect(input.into())
|
||||||
|
.unwrap_or_else(|e| e.to_compile_error())
|
||||||
|
.into()
|
||||||
|
}
|
||||||
|
|
||||||
fn attribute_macro<I, F>(args: TokenStream, input: TokenStream, func: F) -> TokenStream
|
fn attribute_macro<I, F>(args: TokenStream, input: TokenStream, func: F) -> TokenStream
|
||||||
where
|
where
|
||||||
F: Fn(I, &[Meta]) -> Result<TokenStream>,
|
F: Fn(I, &[Meta]) -> Result<TokenStream>,
|
||||||
|
|||||||
@@ -207,8 +207,10 @@ conduwuit-database.workspace = true
|
|||||||
conduwuit-router.workspace = true
|
conduwuit-router.workspace = true
|
||||||
conduwuit-service.workspace = true
|
conduwuit-service.workspace = true
|
||||||
conduwuit-build-metadata.workspace = true
|
conduwuit-build-metadata.workspace = true
|
||||||
|
conduwuit-macros.workspace = true
|
||||||
|
|
||||||
clap.workspace = true
|
clap.workspace = true
|
||||||
|
ctor.workspace = true
|
||||||
console-subscriber.optional = true
|
console-subscriber.optional = true
|
||||||
console-subscriber.workspace = true
|
console-subscriber.workspace = true
|
||||||
const-str.workspace = true
|
const-str.workspace = true
|
||||||
|
|||||||
@@ -4,6 +4,8 @@ use std::sync::{Arc, atomic::Ordering};
|
|||||||
|
|
||||||
use conduwuit_core::{debug_info, error};
|
use conduwuit_core::{debug_info, error};
|
||||||
|
|
||||||
|
conduwuit_macros::introspect_crate! {}
|
||||||
|
|
||||||
mod clap;
|
mod clap;
|
||||||
mod deadlock;
|
mod deadlock;
|
||||||
mod logging;
|
mod logging;
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
name = "conduwuit_router"
|
name = "conduwuit_router"
|
||||||
description.workspace = true
|
description.workspace = true
|
||||||
edition.workspace = true
|
edition.workspace = true
|
||||||
|
homepage.workspace = true
|
||||||
license.workspace = true
|
license.workspace = true
|
||||||
readme.workspace = true
|
readme.workspace = true
|
||||||
repository.workspace = true
|
repository.workspace = true
|
||||||
@@ -99,9 +100,11 @@ bytes.workspace = true
|
|||||||
conduwuit-admin.workspace = true
|
conduwuit-admin.workspace = true
|
||||||
conduwuit-api.workspace = true
|
conduwuit-api.workspace = true
|
||||||
conduwuit-core.workspace = true
|
conduwuit-core.workspace = true
|
||||||
|
conduwuit-macros.workspace = true
|
||||||
conduwuit-service.workspace = true
|
conduwuit-service.workspace = true
|
||||||
conduwuit-web.workspace = true
|
conduwuit-web.workspace = true
|
||||||
const-str.workspace = true
|
const-str.workspace = true
|
||||||
|
ctor.workspace = true
|
||||||
futures.workspace = true
|
futures.workspace = true
|
||||||
http.workspace = true
|
http.workspace = true
|
||||||
http-body-util.workspace = true
|
http-body-util.workspace = true
|
||||||
|
|||||||
@@ -8,6 +8,8 @@ mod serve;
|
|||||||
|
|
||||||
extern crate conduwuit_core as conduwuit;
|
extern crate conduwuit_core as conduwuit;
|
||||||
|
|
||||||
|
conduwuit_macros::introspect_crate! {}
|
||||||
|
|
||||||
use std::{panic::AssertUnwindSafe, pin::Pin, sync::Arc};
|
use std::{panic::AssertUnwindSafe, pin::Pin, sync::Arc};
|
||||||
|
|
||||||
use conduwuit::{Error, Result, Server};
|
use conduwuit::{Error, Result, Server};
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
name = "conduwuit_service"
|
name = "conduwuit_service"
|
||||||
description.workspace = true
|
description.workspace = true
|
||||||
edition.workspace = true
|
edition.workspace = true
|
||||||
|
homepage.workspace = true
|
||||||
license.workspace = true
|
license.workspace = true
|
||||||
readme.workspace = true
|
readme.workspace = true
|
||||||
repository.workspace = true
|
repository.workspace = true
|
||||||
@@ -88,7 +89,9 @@ base64.workspace = true
|
|||||||
bytes.workspace = true
|
bytes.workspace = true
|
||||||
conduwuit-core.workspace = true
|
conduwuit-core.workspace = true
|
||||||
conduwuit-database.workspace = true
|
conduwuit-database.workspace = true
|
||||||
|
conduwuit-macros.workspace = true
|
||||||
const-str.workspace = true
|
const-str.workspace = true
|
||||||
|
ctor.workspace = true
|
||||||
either.workspace = true
|
either.workspace = true
|
||||||
futures.workspace = true
|
futures.workspace = true
|
||||||
governor.workspace = true
|
governor.workspace = true
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ use std::{
|
|||||||
use askama::Template;
|
use askama::Template;
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use conduwuit::{Result, info, utils::ReadyExt};
|
use conduwuit::{Result, info, utils::ReadyExt};
|
||||||
use futures::StreamExt;
|
use futures::{FutureExt, StreamExt};
|
||||||
use ruma::{UserId, events::room::message::RoomMessageEventContent};
|
use ruma::{UserId, events::room::message::RoomMessageEventContent};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
@@ -133,7 +133,7 @@ impl Service {
|
|||||||
return Ok(false);
|
return Ok(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
self.services.admin.make_user_admin(user).await?;
|
self.services.admin.make_user_admin(user).boxed().await?;
|
||||||
|
|
||||||
// Send the welcome message
|
// Send the welcome message
|
||||||
let welcome_message = WelcomeMessage {
|
let welcome_message = WelcomeMessage {
|
||||||
|
|||||||
@@ -3,6 +3,9 @@
|
|||||||
|
|
||||||
extern crate conduwuit_core as conduwuit;
|
extern crate conduwuit_core as conduwuit;
|
||||||
extern crate conduwuit_database as database;
|
extern crate conduwuit_database as database;
|
||||||
|
|
||||||
|
conduwuit_macros::introspect_crate! {}
|
||||||
|
|
||||||
mod manager;
|
mod manager;
|
||||||
mod migrations;
|
mod migrations;
|
||||||
mod service;
|
mod service;
|
||||||
|
|||||||
@@ -72,8 +72,6 @@ impl super::Service {
|
|||||||
if let Some(pos) = dest.as_str().find(':') {
|
if let Some(pos) = dest.as_str().find(':') {
|
||||||
self.actual_dest_2(dest, cache, pos).await?
|
self.actual_dest_2(dest, cache, pos).await?
|
||||||
} else {
|
} else {
|
||||||
self.conditional_query_and_cache(dest.as_str(), 8448, true)
|
|
||||||
.await?;
|
|
||||||
self.services.server.check_running()?;
|
self.services.server.check_running()?;
|
||||||
match self.request_well_known(dest.as_str()).await? {
|
match self.request_well_known(dest.as_str()).await? {
|
||||||
| Some(delegated) =>
|
| Some(delegated) =>
|
||||||
|
|||||||
@@ -56,36 +56,32 @@ pub fn pdu_fits(owned_obj: &mut CanonicalJsonObject) -> bool {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Pulls the room version ID out of the given (create) event.
|
||||||
|
fn room_version_from_event(
|
||||||
|
room_id: OwnedRoomId,
|
||||||
|
event_type: &TimelineEventType,
|
||||||
|
content: &RawValue,
|
||||||
|
) -> Result<RoomVersionId> {
|
||||||
|
if event_type == &TimelineEventType::RoomCreate {
|
||||||
|
let content: RoomCreateEventContent = serde_json::from_str(content.get())?;
|
||||||
|
Ok(content.room_version)
|
||||||
|
} else {
|
||||||
|
Err(Error::InconsistentRoomState(
|
||||||
|
"non-create event for room of unknown version",
|
||||||
|
room_id,
|
||||||
|
))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Creates an event, but does not hash or sign it.
|
||||||
#[implement(super::Service)]
|
#[implement(super::Service)]
|
||||||
pub async fn create_hash_and_sign_event(
|
pub async fn create_event(
|
||||||
&self,
|
&self,
|
||||||
pdu_builder: PduBuilder,
|
pdu_builder: PduBuilder,
|
||||||
sender: &UserId,
|
sender: &UserId,
|
||||||
room_id: Option<&RoomId>,
|
room_id: Option<&RoomId>,
|
||||||
_mutex_lock: &RoomMutexGuard, /* Take mutex guard to make sure users get the room
|
_mutex_lock: &RoomMutexGuard,
|
||||||
* state mutex */
|
) -> Result<(PduEvent, RoomVersionId)> {
|
||||||
) -> Result<(PduEvent, CanonicalJsonObject)> {
|
|
||||||
#[allow(clippy::boxed_local)]
|
|
||||||
fn from_evt(
|
|
||||||
room_id: OwnedRoomId,
|
|
||||||
event_type: &TimelineEventType,
|
|
||||||
content: &RawValue,
|
|
||||||
) -> Result<RoomVersionId> {
|
|
||||||
if event_type == &TimelineEventType::RoomCreate {
|
|
||||||
let content: RoomCreateEventContent = serde_json::from_str(content.get())?;
|
|
||||||
Ok(content.room_version)
|
|
||||||
} else {
|
|
||||||
Err(Error::InconsistentRoomState(
|
|
||||||
"non-create event for room of unknown version",
|
|
||||||
room_id,
|
|
||||||
))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if !self.services.globals.user_is_local(sender) {
|
|
||||||
return Err!(Request(Forbidden("Sender must be a local user")));
|
|
||||||
}
|
|
||||||
|
|
||||||
let PduBuilder {
|
let PduBuilder {
|
||||||
event_type,
|
event_type,
|
||||||
content,
|
content,
|
||||||
@@ -108,12 +104,16 @@ pub async fn create_hash_and_sign_event(
|
|||||||
.get_room_version(room_id)
|
.get_room_version(room_id)
|
||||||
.await
|
.await
|
||||||
.or_else(|_| {
|
.or_else(|_| {
|
||||||
from_evt(room_id.to_owned(), &event_type.clone(), &content.clone())
|
room_version_from_event(
|
||||||
|
room_id.to_owned(),
|
||||||
|
&event_type.clone(),
|
||||||
|
&content.clone(),
|
||||||
|
)
|
||||||
})?
|
})?
|
||||||
},
|
},
|
||||||
| None => {
|
| None => {
|
||||||
trace!("No room ID, assuming room creation");
|
trace!("No room ID, assuming room creation");
|
||||||
from_evt(
|
room_version_from_event(
|
||||||
RoomId::new(self.services.globals.server_name()),
|
RoomId::new(self.services.globals.server_name()),
|
||||||
&event_type.clone(),
|
&event_type.clone(),
|
||||||
&content.clone(),
|
&content.clone(),
|
||||||
@@ -186,7 +186,7 @@ pub async fn create_hash_and_sign_event(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut pdu = PduEvent {
|
let pdu = PduEvent {
|
||||||
event_id: ruma::event_id!("$thiswillbefilledinlater").into(),
|
event_id: ruma::event_id!("$thiswillbefilledinlater").into(),
|
||||||
room_id: room_id.map(ToOwned::to_owned),
|
room_id: room_id.map(ToOwned::to_owned),
|
||||||
sender: sender.to_owned(),
|
sender: sender.to_owned(),
|
||||||
@@ -259,19 +259,29 @@ pub async fn create_hash_and_sign_event(
|
|||||||
pdu.event_id,
|
pdu.event_id,
|
||||||
pdu.room_id.as_ref().map_or("None", |id| id.as_str())
|
pdu.room_id.as_ref().map_or("None", |id| id.as_str())
|
||||||
);
|
);
|
||||||
|
Ok((pdu, room_version_id))
|
||||||
|
}
|
||||||
|
|
||||||
|
#[implement(super::Service)]
|
||||||
|
pub async fn create_hash_and_sign_event(
|
||||||
|
&self,
|
||||||
|
pdu_builder: PduBuilder,
|
||||||
|
sender: &UserId,
|
||||||
|
room_id: Option<&RoomId>,
|
||||||
|
mutex_lock: &RoomMutexGuard, /* Take mutex guard to make sure users get the room
|
||||||
|
* state mutex */
|
||||||
|
) -> Result<(PduEvent, CanonicalJsonObject)> {
|
||||||
|
if !self.services.globals.user_is_local(sender) {
|
||||||
|
return Err!(Request(Forbidden("Sender must be a local user")));
|
||||||
|
}
|
||||||
|
let (mut pdu, room_version_id) = self
|
||||||
|
.create_event(pdu_builder, sender, room_id, mutex_lock)
|
||||||
|
.await?;
|
||||||
// Hash and sign
|
// Hash and sign
|
||||||
let mut pdu_json = utils::to_canonical_object(&pdu).map_err(|e| {
|
let mut pdu_json = utils::to_canonical_object(&pdu).map_err(|e| {
|
||||||
err!(Request(BadJson(warn!("Failed to convert PDU to canonical JSON: {e}"))))
|
err!(Request(BadJson(warn!("Failed to convert PDU to canonical JSON: {e}"))))
|
||||||
})?;
|
})?;
|
||||||
|
pdu_json.remove("event_id");
|
||||||
// room v3 and above removed the "event_id" field from remote PDU format
|
|
||||||
match room_version_id {
|
|
||||||
| RoomVersionId::V1 | RoomVersionId::V2 => {},
|
|
||||||
| _ => {
|
|
||||||
pdu_json.remove("event_id");
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
trace!("hashing and signing event {}", pdu.event_id);
|
trace!("hashing and signing event {}", pdu.event_id);
|
||||||
if let Err(e) = self
|
if let Err(e) = self
|
||||||
|
|||||||
@@ -455,6 +455,7 @@ impl Service {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
| AuthData::Terms(_) => Ok(AuthType::Terms),
|
||||||
| _ => Err(StandardErrorBody {
|
| _ => Err(StandardErrorBody {
|
||||||
kind: ErrorKind::Unrecognized,
|
kind: ErrorKind::Unrecognized,
|
||||||
message: "Unsupported stage type".into(),
|
message: "Unsupported stage type".into(),
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
name = "conduwuit_web"
|
name = "conduwuit_web"
|
||||||
description.workspace = true
|
description.workspace = true
|
||||||
edition.workspace = true
|
edition.workspace = true
|
||||||
|
homepage.workspace = true
|
||||||
license.workspace = true
|
license.workspace = true
|
||||||
readme.workspace = true
|
readme.workspace = true
|
||||||
repository.workspace = true
|
repository.workspace = true
|
||||||
|
|||||||
Reference in New Issue
Block a user