diff --git a/.cargo/config.toml b/.cargo/config.toml new file mode 100644 index 0000000000000000000000000000000000000000..e2e5fa90e2dc79647fe8aa162eda34b641296071 --- /dev/null +++ b/.cargo/config.toml @@ -0,0 +1,11 @@ +[env] +# In unoptimised builds tokio tends to use a lot of stack space when +# creating some complicated futures, tokio has an open issue for this: +# https://github.com/tokio-rs/tokio/issues/2055. Some of our tests +# manage to not fit in the default 2MiB stack anymore due to this, so +# while the issue is not resolved we want to work around this. +# Because compiling optimised builds takes a very long time we prefer +# to avoid that. Setting this environment variable ensures that when +# invoking `cargo test` threads are allowed to have a large enough +# stack size without needing to use an optimised build. +RUST_MIN_STACK = "8388608" diff --git a/.gitattributes b/.gitattributes index a6344aac8c09253b3b630fb776ae94478aa0275b..da58b35f146700f40b84a2e57c84f604abad6e48 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,35 +1,30 @@ -*.7z filter=lfs diff=lfs merge=lfs -text -*.arrow filter=lfs diff=lfs merge=lfs -text -*.bin filter=lfs diff=lfs merge=lfs -text -*.bz2 filter=lfs diff=lfs merge=lfs -text -*.ckpt filter=lfs diff=lfs merge=lfs -text -*.ftz filter=lfs diff=lfs merge=lfs -text -*.gz filter=lfs diff=lfs merge=lfs -text -*.h5 filter=lfs diff=lfs merge=lfs -text -*.joblib filter=lfs diff=lfs merge=lfs -text -*.lfs.* filter=lfs diff=lfs merge=lfs -text -*.mlmodel filter=lfs diff=lfs merge=lfs -text -*.model filter=lfs diff=lfs merge=lfs -text -*.msgpack filter=lfs diff=lfs merge=lfs -text -*.npy filter=lfs diff=lfs merge=lfs -text -*.npz filter=lfs diff=lfs merge=lfs -text -*.onnx filter=lfs diff=lfs merge=lfs -text -*.ot filter=lfs diff=lfs merge=lfs -text -*.parquet filter=lfs diff=lfs merge=lfs -text -*.pb filter=lfs diff=lfs merge=lfs -text -*.pickle filter=lfs diff=lfs merge=lfs -text -*.pkl filter=lfs diff=lfs merge=lfs -text -*.pt filter=lfs diff=lfs merge=lfs -text -*.pth filter=lfs diff=lfs merge=lfs -text -*.rar filter=lfs diff=lfs merge=lfs -text -*.safetensors filter=lfs diff=lfs merge=lfs -text -saved_model/**/* filter=lfs diff=lfs merge=lfs -text -*.tar.* filter=lfs diff=lfs merge=lfs -text -*.tar filter=lfs diff=lfs merge=lfs -text -*.tflite filter=lfs diff=lfs merge=lfs -text -*.tgz filter=lfs diff=lfs merge=lfs -text -*.wasm filter=lfs diff=lfs merge=lfs -text -*.xz filter=lfs diff=lfs merge=lfs -text -*.zip filter=lfs diff=lfs merge=lfs -text -*.zst filter=lfs diff=lfs merge=lfs -text -*tfevents* filter=lfs diff=lfs merge=lfs -text +# normal text files should contain a simple LF lineend, the following settings +# ensures this even if the user has not set core.autocrlf. +* text=auto + +# Checkout JavaScript files with LF line endings +# to prevent `prettier` from reporting errors on Windows. +*.js eol=lf +*.jsx eol=lf +*.ts eol=lf +*.tsx eol=lf +*.json eol=lf + +# This directory contains email messages verbatim, and changing CRLF to +# LF will corrupt them. +test-data/** text=false + +# binary files should be detected by git, however, to be sure, you can add them here explicitly +*.png binary +*.jpg binary +*.gif binary +*.ico binary + +*.py diff=python +*.rs diff=rust +*.md diff=markdown +assets/welcome-image.jpg filter=lfs diff=lfs merge=lfs -text +test-data/image/screenshot-rgba.png filter=lfs diff=lfs merge=lfs -text +test-data/image/screenshot.gif filter=lfs diff=lfs merge=lfs -text +test-data/image/screenshot.jpg filter=lfs diff=lfs merge=lfs -text +test-data/image/screenshot.png filter=lfs diff=lfs merge=lfs -text diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 0000000000000000000000000000000000000000..82c6ef093ee649e83463da56e61346d2259f90e9 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,35 @@ +--- +name: Bug report +about: Report something that isn't working. +title: '' +assignees: '' +labels: bug +--- + + + +- Operating System (Linux/Mac/Windows/iOS/Android): +- Core Version: +- Client Version: + +## Expected behavior + +*What did you try to achieve?* + +## Actual behavior + +*What happened instead?* + +### Steps to reproduce the problem + +1. +2. + +### Screenshots + +### Logs + diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000000000000000000000000000000000000..53a6945a296f49610668322f0fc26213b065edf4 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,20 @@ +version: 2 +updates: + - package-ecosystem: "cargo" + directory: "/" + schedule: + interval: "monthly" + commit-message: + prefix: "chore(cargo)" + open-pull-requests-limit: 50 + cooldown: + default-days: 7 + + # Keep GitHub Actions up to date. + # + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "weekly" + cooldown: + default-days: 7 diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000000000000000000000000000000000000..a7f97c6e170884c9528793b29780c4fe2ec6ac1b --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,380 @@ +# GitHub Actions workflow to +# lint Rust and Python code +# and run Rust tests, Python tests and async Python tests. + +name: Rust CI + +# Cancel previously started workflow runs +# when the branch is updated. +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +on: + pull_request: + push: + branches: + - main + +permissions: {} + +env: + RUSTFLAGS: -Dwarnings + RUST_VERSION: 1.92.0 + + # Minimum Supported Rust Version + MSRV: 1.88.0 + +jobs: + lint_rust: + name: Lint Rust + runs-on: ubuntu-latest + timeout-minutes: 60 + steps: + - uses: actions/checkout@v6 + with: + show-progress: false + persist-credentials: false + - name: Install rustfmt and clippy + run: rustup toolchain install $RUST_VERSION --profile minimal --component rustfmt --component clippy + - run: rustup override set $RUST_VERSION + shell: bash + - name: Cache rust cargo artifacts + uses: swatinem/rust-cache@779680da715d629ac1d338a641029a2f4372abb5 + - name: Run rustfmt + run: cargo fmt --all -- --check + - name: Run clippy + run: scripts/clippy.sh + - name: Check with all features + run: cargo check --workspace --all-targets --all-features + - name: Check with only default features + run: cargo check --all-targets + + cargo_deny: + name: cargo deny + runs-on: ubuntu-latest + timeout-minutes: 60 + steps: + - uses: actions/checkout@v6 + with: + show-progress: false + persist-credentials: false + - uses: EmbarkStudios/cargo-deny-action@76cd80eb775d7bbbd2d80292136d74d39e1b4918 + with: + arguments: --all-features --workspace + command: check + command-arguments: "-Dwarnings" + + provider_database: + name: Check provider database + runs-on: ubuntu-latest + timeout-minutes: 60 + steps: + - uses: actions/checkout@v6 + with: + show-progress: false + persist-credentials: false + - name: Install rustfmt + run: rustup component add --toolchain stable-x86_64-unknown-linux-gnu rustfmt + - name: Check provider database + run: scripts/update-provider-database.sh + + docs: + name: Rust doc comments + runs-on: ubuntu-latest + timeout-minutes: 60 + env: + RUSTDOCFLAGS: -Dwarnings + steps: + - uses: actions/checkout@v6 + with: + show-progress: false + persist-credentials: false + - name: Cache rust cargo artifacts + uses: swatinem/rust-cache@779680da715d629ac1d338a641029a2f4372abb5 + - name: Rustdoc + run: cargo doc --document-private-items --no-deps + + rust_tests: + name: Rust tests + strategy: + matrix: + include: + - os: ubuntu-latest + rust: latest + - os: windows-latest + rust: latest + - os: macos-latest + rust: latest + + # Minimum Supported Rust Version + - os: ubuntu-latest + rust: minimum + runs-on: ${{ matrix.os }} + timeout-minutes: 60 + steps: + - run: + echo "RUSTUP_TOOLCHAIN=$MSRV" >> $GITHUB_ENV + shell: bash + if: matrix.rust == 'minimum' + - run: + echo "RUSTUP_TOOLCHAIN=$RUST_VERSION" >> $GITHUB_ENV + shell: bash + if: matrix.rust == 'latest' + + - uses: actions/checkout@v6 + with: + show-progress: false + persist-credentials: false + + - name: Install Rust ${{ matrix.rust }} + run: rustup toolchain install --profile minimal $RUSTUP_TOOLCHAIN + shell: bash + - run: rustup override set $RUSTUP_TOOLCHAIN + shell: bash + + - name: Cache rust cargo artifacts + uses: swatinem/rust-cache@779680da715d629ac1d338a641029a2f4372abb5 + + - name: Install nextest + uses: taiki-e/install-action@69e777b377e4ec209ddad9426ae3e0c1008b0ef3 + with: + tool: nextest + + - name: Tests + env: + RUST_BACKTRACE: 1 + run: cargo nextest run --workspace --locked + + - name: Doc-Tests + env: + RUST_BACKTRACE: 1 + run: cargo test --workspace --locked --doc + + - name: Test cargo vendor + run: cargo vendor + + c_library: + name: Build C library + strategy: + matrix: + os: [ubuntu-latest, macos-latest] + runs-on: ${{ matrix.os }} + timeout-minutes: 60 + steps: + - uses: actions/checkout@v6 + with: + show-progress: false + persist-credentials: false + + - name: Cache rust cargo artifacts + uses: swatinem/rust-cache@779680da715d629ac1d338a641029a2f4372abb5 + + - name: Build C library + run: cargo build -p deltachat_ffi + + - name: Upload C library + uses: actions/upload-artifact@v6 + with: + name: ${{ matrix.os }}-libdeltachat.a + path: target/debug/libdeltachat.a + retention-days: 1 + + rpc_server: + name: Build deltachat-rpc-server + strategy: + matrix: + os: [ubuntu-latest, macos-latest, windows-latest] + runs-on: ${{ matrix.os }} + timeout-minutes: 60 + steps: + - uses: actions/checkout@v6 + with: + show-progress: false + persist-credentials: false + + - name: Cache rust cargo artifacts + uses: swatinem/rust-cache@779680da715d629ac1d338a641029a2f4372abb5 + + - name: Build deltachat-rpc-server + run: cargo build -p deltachat-rpc-server + + - name: Upload deltachat-rpc-server + uses: actions/upload-artifact@v6 + with: + name: ${{ matrix.os }}-deltachat-rpc-server + path: ${{ matrix.os == 'windows-latest' && 'target/debug/deltachat-rpc-server.exe' || 'target/debug/deltachat-rpc-server' }} + retention-days: 1 + + python_lint: + name: Python lint + runs-on: ubuntu-latest + timeout-minutes: 60 + steps: + - uses: actions/checkout@v6 + with: + show-progress: false + persist-credentials: false + + - name: Install tox + run: pip install tox + + - name: Lint Python bindings + working-directory: python + run: tox -e lint + + - name: Lint deltachat-rpc-client + working-directory: deltachat-rpc-client + run: tox -e lint + + # mypy does not work with PyPy since mypy 1.19 + # as it introduced native `librt` dependency + # that uses CPython internals. + # We only run mypy with CPython because of this. + cffi_python_mypy: + name: CFFI Python mypy + needs: ["c_library", "python_lint"] + runs-on: ubuntu-latest + timeout-minutes: 60 + steps: + - uses: actions/checkout@v6 + with: + show-progress: false + persist-credentials: false + + - name: Download libdeltachat.a + uses: actions/download-artifact@v7 + with: + name: ubuntu-latest-libdeltachat.a + path: target/debug + + - name: Install tox + run: pip install tox + + - name: Run mypy + env: + DCC_RS_TARGET: debug + DCC_RS_DEV: ${{ github.workspace }} + working-directory: python + run: tox -e mypy + + + cffi_python_tests: + name: CFFI Python tests + needs: ["c_library", "python_lint"] + strategy: + fail-fast: false + matrix: + include: + # Currently used Rust version. + - os: ubuntu-latest + python: 3.14 + - os: macos-latest + python: 3.14 + + # PyPy tests + - os: ubuntu-latest + python: pypy3.10 + - os: macos-latest + python: pypy3.10 + + # Minimum Supported Python Version = 3.10 + # This is the minimum version for which manylinux Python wheels are + # built. Test it with minimum supported Rust version. + - os: ubuntu-latest + python: "3.10" + + runs-on: ${{ matrix.os }} + timeout-minutes: 60 + steps: + - uses: actions/checkout@v6 + with: + show-progress: false + persist-credentials: false + + - name: Download libdeltachat.a + uses: actions/download-artifact@v7 + with: + name: ${{ matrix.os }}-libdeltachat.a + path: target/debug + + - name: Install python + uses: actions/setup-python@v6 + with: + python-version: ${{ matrix.python }} + + - name: Install tox + run: pip install tox + + - name: Run python tests + env: + CHATMAIL_DOMAIN: ${{ vars.CHATMAIL_DOMAIN }} + DCC_RS_TARGET: debug + DCC_RS_DEV: ${{ github.workspace }} + working-directory: python + run: tox -e doc,py + + rpc_python_tests: + name: JSON-RPC Python tests + needs: ["python_lint", "rpc_server"] + strategy: + fail-fast: false + matrix: + include: + - os: ubuntu-latest + python: 3.14 + - os: macos-latest + python: 3.14 + - os: windows-latest + python: 3.14 + + # PyPy tests + - os: ubuntu-latest + python: pypy3.10 + - os: macos-latest + python: pypy3.10 + + # Minimum Supported Python Version = 3.10 + - os: ubuntu-latest + python: "3.10" + + runs-on: ${{ matrix.os }} + timeout-minutes: 60 + steps: + - uses: actions/checkout@v6 + with: + show-progress: false + persist-credentials: false + + - name: Install python + uses: actions/setup-python@v6 + with: + python-version: ${{ matrix.python }} + + - name: Install tox + run: pip install tox + + - name: Download deltachat-rpc-server + uses: actions/download-artifact@v7 + with: + name: ${{ matrix.os }}-deltachat-rpc-server + path: target/debug + + - name: Make deltachat-rpc-server executable + if: ${{ matrix.os != 'windows-latest' }} + run: chmod +x target/debug/deltachat-rpc-server + + - name: Add deltachat-rpc-server to path + if: ${{ matrix.os != 'windows-latest' }} + run: echo ${{ github.workspace }}/target/debug >> $GITHUB_PATH + + - name: Add deltachat-rpc-server to path + if: ${{ matrix.os == 'windows-latest' }} + run: | + "${{ github.workspace }}/target/debug" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append + + - name: Run deltachat-rpc-client tests + env: + CHATMAIL_DOMAIN: ${{ vars.CHATMAIL_DOMAIN }} + working-directory: deltachat-rpc-client + run: tox -e py diff --git a/.github/workflows/deltachat-rpc-server.yml b/.github/workflows/deltachat-rpc-server.yml new file mode 100644 index 0000000000000000000000000000000000000000..50a6ba7f279261175e235781549e33eec8f0dd41 --- /dev/null +++ b/.github/workflows/deltachat-rpc-server.yml @@ -0,0 +1,531 @@ +# GitHub Actions workflow +# to build `deltachat-rpc-server` binaries +# and upload them to the release. +# +# The workflow is automatically triggered on releases. +# It can also be triggered manually +# to produce binary artifacts for testing. + +name: Build deltachat-rpc-server binaries + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +on: + workflow_dispatch: + release: + types: [published] + +permissions: {} + +jobs: + # Build a version statically linked against musl libc + # to avoid problems with glibc version incompatibility. + build_linux: + name: Linux + strategy: + fail-fast: false + matrix: + arch: [aarch64, armv7l, armv6l, i686, x86_64] + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v6 + with: + show-progress: false + persist-credentials: false + - uses: cachix/install-nix-action@4e002c8ec80594ecd40e759629461e26c8abed15 # v31 + + - name: Build deltachat-rpc-server binaries + run: nix build .#deltachat-rpc-server-${{ matrix.arch }}-linux + + - name: Upload binary + uses: actions/upload-artifact@v6 + with: + name: deltachat-rpc-server-${{ matrix.arch }}-linux + path: result/bin/deltachat-rpc-server + if-no-files-found: error + + build_linux_wheel: + name: Linux wheel + strategy: + fail-fast: false + matrix: + arch: [aarch64, armv7l, armv6l, i686, x86_64] + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v6 + with: + show-progress: false + persist-credentials: false + - uses: cachix/install-nix-action@4e002c8ec80594ecd40e759629461e26c8abed15 # v31 + + - name: Build deltachat-rpc-server wheels + run: nix build .#deltachat-rpc-server-${{ matrix.arch }}-linux-wheel + + - name: Upload wheel + uses: actions/upload-artifact@v6 + with: + name: deltachat-rpc-server-${{ matrix.arch }}-linux-wheel + path: result/*.whl + if-no-files-found: error + + build_windows: + name: Windows + strategy: + fail-fast: false + matrix: + arch: [win32, win64] + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v6 + with: + show-progress: false + persist-credentials: false + - uses: cachix/install-nix-action@4e002c8ec80594ecd40e759629461e26c8abed15 # v31 + + - name: Build deltachat-rpc-server binaries + run: nix build .#deltachat-rpc-server-${{ matrix.arch }} + + - name: Upload binary + uses: actions/upload-artifact@v6 + with: + name: deltachat-rpc-server-${{ matrix.arch }} + path: result/bin/deltachat-rpc-server.exe + if-no-files-found: error + + build_windows_wheel: + name: Windows wheel + strategy: + fail-fast: false + matrix: + arch: [win32, win64] + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v6 + with: + show-progress: false + persist-credentials: false + - uses: cachix/install-nix-action@4e002c8ec80594ecd40e759629461e26c8abed15 # v31 + + - name: Build deltachat-rpc-server wheels + run: nix build .#deltachat-rpc-server-${{ matrix.arch }}-wheel + + - name: Upload wheel + uses: actions/upload-artifact@v6 + with: + name: deltachat-rpc-server-${{ matrix.arch }}-wheel + path: result/*.whl + if-no-files-found: error + + build_macos: + name: macOS + strategy: + fail-fast: false + matrix: + arch: [x86_64, aarch64] + + runs-on: macos-latest + steps: + - uses: actions/checkout@v6 + with: + show-progress: false + persist-credentials: false + + - name: Setup rust target + run: rustup target add ${{ matrix.arch }}-apple-darwin + + - name: Build + run: cargo build --release --package deltachat-rpc-server --target ${{ matrix.arch }}-apple-darwin --features vendored + + - name: Upload binary + uses: actions/upload-artifact@v6 + with: + name: deltachat-rpc-server-${{ matrix.arch }}-macos + path: target/${{ matrix.arch }}-apple-darwin/release/deltachat-rpc-server + if-no-files-found: error + + build_android: + name: Android + strategy: + fail-fast: false + matrix: + arch: [arm64-v8a, armeabi-v7a] + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v6 + with: + show-progress: false + persist-credentials: false + - uses: cachix/install-nix-action@4e002c8ec80594ecd40e759629461e26c8abed15 # v31 + + - name: Build deltachat-rpc-server binaries + run: nix build .#deltachat-rpc-server-${{ matrix.arch }}-android + + - name: Upload binary + uses: actions/upload-artifact@v6 + with: + name: deltachat-rpc-server-${{ matrix.arch }}-android + path: result/bin/deltachat-rpc-server + if-no-files-found: error + + build_android_wheel: + name: Android wheel + strategy: + fail-fast: false + matrix: + arch: [arm64-v8a, armeabi-v7a] + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v6 + with: + show-progress: false + persist-credentials: false + - uses: cachix/install-nix-action@4e002c8ec80594ecd40e759629461e26c8abed15 # v31 + + - name: Build deltachat-rpc-server wheels + run: nix build .#deltachat-rpc-server-${{ matrix.arch }}-android-wheel + + - name: Upload wheel + uses: actions/upload-artifact@v6 + with: + name: deltachat-rpc-server-${{ matrix.arch }}-android-wheel + path: result/*.whl + if-no-files-found: error + + publish: + name: Build wheels and upload binaries to the release + needs: ["build_linux", "build_linux_wheel", "build_windows", "build_windows_wheel", "build_macos", "build_android", "build_android_wheel"] + environment: + name: pypi + url: https://pypi.org/p/deltachat-rpc-server + permissions: + id-token: write + contents: write + runs-on: "ubuntu-latest" + steps: + - uses: actions/checkout@v6 + with: + show-progress: false + persist-credentials: false + - uses: cachix/install-nix-action@4e002c8ec80594ecd40e759629461e26c8abed15 # v31 + + - name: Download Linux aarch64 binary + uses: actions/download-artifact@v7 + with: + name: deltachat-rpc-server-aarch64-linux + path: deltachat-rpc-server-aarch64-linux.d + + - name: Download Linux aarch64 wheel + uses: actions/download-artifact@v7 + with: + name: deltachat-rpc-server-aarch64-linux-wheel + path: deltachat-rpc-server-aarch64-linux-wheel.d + + - name: Download Linux armv7l binary + uses: actions/download-artifact@v7 + with: + name: deltachat-rpc-server-armv7l-linux + path: deltachat-rpc-server-armv7l-linux.d + + - name: Download Linux armv7l wheel + uses: actions/download-artifact@v7 + with: + name: deltachat-rpc-server-armv7l-linux-wheel + path: deltachat-rpc-server-armv7l-linux-wheel.d + + - name: Download Linux armv6l binary + uses: actions/download-artifact@v7 + with: + name: deltachat-rpc-server-armv6l-linux + path: deltachat-rpc-server-armv6l-linux.d + + - name: Download Linux armv6l wheel + uses: actions/download-artifact@v7 + with: + name: deltachat-rpc-server-armv6l-linux-wheel + path: deltachat-rpc-server-armv6l-linux-wheel.d + + - name: Download Linux i686 binary + uses: actions/download-artifact@v7 + with: + name: deltachat-rpc-server-i686-linux + path: deltachat-rpc-server-i686-linux.d + + - name: Download Linux i686 wheel + uses: actions/download-artifact@v7 + with: + name: deltachat-rpc-server-i686-linux-wheel + path: deltachat-rpc-server-i686-linux-wheel.d + + - name: Download Linux x86_64 binary + uses: actions/download-artifact@v7 + with: + name: deltachat-rpc-server-x86_64-linux + path: deltachat-rpc-server-x86_64-linux.d + + - name: Download Linux x86_64 wheel + uses: actions/download-artifact@v7 + with: + name: deltachat-rpc-server-x86_64-linux-wheel + path: deltachat-rpc-server-x86_64-linux-wheel.d + + - name: Download Win32 binary + uses: actions/download-artifact@v7 + with: + name: deltachat-rpc-server-win32 + path: deltachat-rpc-server-win32.d + + - name: Download Win32 wheel + uses: actions/download-artifact@v7 + with: + name: deltachat-rpc-server-win32-wheel + path: deltachat-rpc-server-win32-wheel.d + + - name: Download Win64 binary + uses: actions/download-artifact@v7 + with: + name: deltachat-rpc-server-win64 + path: deltachat-rpc-server-win64.d + + - name: Download Win64 wheel + uses: actions/download-artifact@v7 + with: + name: deltachat-rpc-server-win64-wheel + path: deltachat-rpc-server-win64-wheel.d + + - name: Download macOS binary for x86_64 + uses: actions/download-artifact@v7 + with: + name: deltachat-rpc-server-x86_64-macos + path: deltachat-rpc-server-x86_64-macos.d + + - name: Download macOS binary for aarch64 + uses: actions/download-artifact@v7 + with: + name: deltachat-rpc-server-aarch64-macos + path: deltachat-rpc-server-aarch64-macos.d + + - name: Download Android binary for arm64-v8a + uses: actions/download-artifact@v7 + with: + name: deltachat-rpc-server-arm64-v8a-android + path: deltachat-rpc-server-arm64-v8a-android.d + + - name: Download Android wheel for arm64-v8a + uses: actions/download-artifact@v7 + with: + name: deltachat-rpc-server-arm64-v8a-android-wheel + path: deltachat-rpc-server-arm64-v8a-android-wheel.d + + - name: Download Android binary for armeabi-v7a + uses: actions/download-artifact@v7 + with: + name: deltachat-rpc-server-armeabi-v7a-android + path: deltachat-rpc-server-armeabi-v7a-android.d + + - name: Download Android wheel for armeabi-v7a + uses: actions/download-artifact@v7 + with: + name: deltachat-rpc-server-armeabi-v7a-android-wheel + path: deltachat-rpc-server-armeabi-v7a-android-wheel.d + + - name: Create bin/ directory + run: | + mkdir -p bin + mv deltachat-rpc-server-aarch64-linux.d/deltachat-rpc-server bin/deltachat-rpc-server-aarch64-linux + mv deltachat-rpc-server-armv7l-linux.d/deltachat-rpc-server bin/deltachat-rpc-server-armv7l-linux + mv deltachat-rpc-server-armv6l-linux.d/deltachat-rpc-server bin/deltachat-rpc-server-armv6l-linux + mv deltachat-rpc-server-i686-linux.d/deltachat-rpc-server bin/deltachat-rpc-server-i686-linux + mv deltachat-rpc-server-x86_64-linux.d/deltachat-rpc-server bin/deltachat-rpc-server-x86_64-linux + mv deltachat-rpc-server-win32.d/deltachat-rpc-server.exe bin/deltachat-rpc-server-win32.exe + mv deltachat-rpc-server-win64.d/deltachat-rpc-server.exe bin/deltachat-rpc-server-win64.exe + mv deltachat-rpc-server-x86_64-macos.d/deltachat-rpc-server bin/deltachat-rpc-server-x86_64-macos + mv deltachat-rpc-server-aarch64-macos.d/deltachat-rpc-server bin/deltachat-rpc-server-aarch64-macos + mv deltachat-rpc-server-arm64-v8a-android.d/deltachat-rpc-server bin/deltachat-rpc-server-arm64-v8a-android + mv deltachat-rpc-server-armeabi-v7a-android.d/deltachat-rpc-server bin/deltachat-rpc-server-armeabi-v7a-android + + - name: List binaries + run: ls -l bin/ + + - name: Install wheel + run: pip install wheel + + - name: Build deltachat-rpc-server Python wheels + run: | + mkdir -p dist + mv deltachat-rpc-server-aarch64-linux-wheel.d/*.whl dist/ + mv deltachat-rpc-server-armv7l-linux-wheel.d/*.whl dist/ + mv deltachat-rpc-server-armv6l-linux-wheel.d/*.whl dist/ + mv deltachat-rpc-server-i686-linux-wheel.d/*.whl dist/ + mv deltachat-rpc-server-x86_64-linux-wheel.d/*.whl dist/ + mv deltachat-rpc-server-win64-wheel.d/*.whl dist/ + mv deltachat-rpc-server-win32-wheel.d/*.whl dist/ + mv deltachat-rpc-server-arm64-v8a-android-wheel.d/*.whl dist/ + mv deltachat-rpc-server-armeabi-v7a-android-wheel.d/*.whl dist/ + python3 scripts/wheel-rpc-server.py x86_64-darwin bin/deltachat-rpc-server-x86_64-macos + python3 scripts/wheel-rpc-server.py aarch64-darwin bin/deltachat-rpc-server-aarch64-macos + mv *.whl dist/ + + - name: List artifacts + run: ls -l dist/ + + - name: Upload binaries to the GitHub release + if: github.event_name == 'release' + env: + GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}" + REF_NAME: ${{ github.ref_name }} + run: | + gh release upload "$REF_NAME" \ + --repo ${{ github.repository }} \ + bin/* dist/* + + - name: Publish deltachat-rpc-server to PyPI + if: github.event_name == 'release' + uses: pypa/gh-action-pypi-publish@ed0c53931b1dc9bd32cbe73a98c7f6766f8a527e + + publish_npm_package: + name: Build & Publish npm prebuilds and deltachat-rpc-server + needs: ["build_linux", "build_windows", "build_macos"] + runs-on: "ubuntu-latest" + environment: + name: npm-stdio-rpc-server + url: https://www.npmjs.com/package/@deltachat/stdio-rpc-server + permissions: + id-token: write + + # Needed to publish the binaries to the release. + contents: write + steps: + - uses: actions/checkout@v6 + with: + show-progress: false + persist-credentials: false + - uses: actions/setup-python@v6 + with: + python-version: "3.11" + + - name: Download Linux aarch64 binary + uses: actions/download-artifact@v7 + with: + name: deltachat-rpc-server-aarch64-linux + path: deltachat-rpc-server-aarch64-linux.d + + - name: Download Linux armv7l binary + uses: actions/download-artifact@v7 + with: + name: deltachat-rpc-server-armv7l-linux + path: deltachat-rpc-server-armv7l-linux.d + + - name: Download Linux armv6l binary + uses: actions/download-artifact@v7 + with: + name: deltachat-rpc-server-armv6l-linux + path: deltachat-rpc-server-armv6l-linux.d + + - name: Download Linux i686 binary + uses: actions/download-artifact@v7 + with: + name: deltachat-rpc-server-i686-linux + path: deltachat-rpc-server-i686-linux.d + + - name: Download Linux x86_64 binary + uses: actions/download-artifact@v7 + with: + name: deltachat-rpc-server-x86_64-linux + path: deltachat-rpc-server-x86_64-linux.d + + - name: Download Win32 binary + uses: actions/download-artifact@v7 + with: + name: deltachat-rpc-server-win32 + path: deltachat-rpc-server-win32.d + + - name: Download Win64 binary + uses: actions/download-artifact@v7 + with: + name: deltachat-rpc-server-win64 + path: deltachat-rpc-server-win64.d + + - name: Download macOS binary for x86_64 + uses: actions/download-artifact@v7 + with: + name: deltachat-rpc-server-x86_64-macos + path: deltachat-rpc-server-x86_64-macos.d + + - name: Download macOS binary for aarch64 + uses: actions/download-artifact@v7 + with: + name: deltachat-rpc-server-aarch64-macos + path: deltachat-rpc-server-aarch64-macos.d + + - name: Download Android binary for arm64-v8a + uses: actions/download-artifact@v7 + with: + name: deltachat-rpc-server-arm64-v8a-android + path: deltachat-rpc-server-arm64-v8a-android.d + + - name: Download Android binary for armeabi-v7a + uses: actions/download-artifact@v7 + with: + name: deltachat-rpc-server-armeabi-v7a-android + path: deltachat-rpc-server-armeabi-v7a-android.d + + - name: make npm packets for prebuilds and `@deltachat/stdio-rpc-server` + run: | + cd deltachat-rpc-server/npm-package + + python --version + + python scripts/pack_binary_for_platform.py aarch64-unknown-linux-musl ../../deltachat-rpc-server-aarch64-linux.d/deltachat-rpc-server + python scripts/pack_binary_for_platform.py armv7-unknown-linux-musleabihf ../../deltachat-rpc-server-armv7l-linux.d/deltachat-rpc-server + python scripts/pack_binary_for_platform.py arm-unknown-linux-musleabihf ../../deltachat-rpc-server-armv6l-linux.d/deltachat-rpc-server + python scripts/pack_binary_for_platform.py i686-unknown-linux-musl ../../deltachat-rpc-server-i686-linux.d/deltachat-rpc-server + python scripts/pack_binary_for_platform.py x86_64-unknown-linux-musl ../../deltachat-rpc-server-x86_64-linux.d/deltachat-rpc-server + python scripts/pack_binary_for_platform.py i686-pc-windows-gnu ../../deltachat-rpc-server-win32.d/deltachat-rpc-server.exe + python scripts/pack_binary_for_platform.py x86_64-pc-windows-gnu ../../deltachat-rpc-server-win64.d/deltachat-rpc-server.exe + python scripts/pack_binary_for_platform.py x86_64-apple-darwin ../../deltachat-rpc-server-x86_64-macos.d/deltachat-rpc-server + python scripts/pack_binary_for_platform.py aarch64-apple-darwin ../../deltachat-rpc-server-aarch64-macos.d/deltachat-rpc-server + python scripts/pack_binary_for_platform.py aarch64-linux-android ../../deltachat-rpc-server-arm64-v8a-android.d/deltachat-rpc-server + python scripts/pack_binary_for_platform.py armv7-linux-androideabi ../../deltachat-rpc-server-armeabi-v7a-android.d/deltachat-rpc-server + + ls -lah platform_package + + for platform in ./platform_package/*; do npm pack "$platform"; done + npm pack + ls -lah + + - name: Upload to artifacts + uses: actions/upload-artifact@v6 + with: + name: deltachat-rpc-server-npm-package + path: deltachat-rpc-server/npm-package/*.tgz + if-no-files-found: error + + - name: Upload npm packets to the GitHub release + if: github.event_name == 'release' + env: + GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}" + REF_NAME: ${{ github.ref_name }} + run: | + gh release upload "$REF_NAME" \ + --repo ${{ github.repository }} \ + deltachat-rpc-server/npm-package/*.tgz + + # Configure Node.js for publishing. + - uses: actions/setup-node@v6 + with: + node-version: 20 + registry-url: "https://registry.npmjs.org" + + # Ensure npm 11.5.1 or later is installed. + # It is needed for + - name: Update npm + run: npm install -g npm@latest + + - name: Publish npm packets for prebuilds and `@deltachat/stdio-rpc-server` + if: github.event_name == 'release' + working-directory: deltachat-rpc-server/npm-package + run: | + ls -lah platform_package + for platform in *.tgz; do npm publish --provenance "$platform" --access public; done diff --git a/.github/workflows/dependabot.yml b/.github/workflows/dependabot.yml new file mode 100644 index 0000000000000000000000000000000000000000..c626894fa77d3f0c9e8800760a3115aea313db45 --- /dev/null +++ b/.github/workflows/dependabot.yml @@ -0,0 +1,24 @@ +# GitHub Actions workflow +# to automatically approve PRs made by Dependabot. + +name: Dependabot auto-approve +on: pull_request + +permissions: + pull-requests: write + +jobs: + dependabot: + runs-on: ubuntu-latest + if: ${{ github.actor == 'dependabot[bot]' }} + steps: + - name: Dependabot metadata + id: metadata + uses: dependabot/fetch-metadata@v2.4.0 + with: + github-token: "${{ secrets.GITHUB_TOKEN }}" + - name: Approve a PR + run: gh pr review --approve "$PR_URL" + env: + PR_URL: ${{github.event.pull_request.html_url}} + GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}} diff --git a/.github/workflows/jsonrpc-client-npm-package.yml b/.github/workflows/jsonrpc-client-npm-package.yml new file mode 100644 index 0000000000000000000000000000000000000000..d66ed8406ba0118cecf06979b1f209e129ba76e3 --- /dev/null +++ b/.github/workflows/jsonrpc-client-npm-package.yml @@ -0,0 +1,47 @@ +name: "Publish @deltachat/jsonrpc-client" +on: + workflow_dispatch: + release: + types: [published] + +permissions: {} + +jobs: + pack-module: + name: "Publish @deltachat/jsonrpc-client" + runs-on: ubuntu-latest + environment: + name: npm-jsonrpc-client + url: https://www.npmjs.com/package/@deltachat/jsonrpc-client + permissions: + id-token: write + contents: read + steps: + - uses: actions/checkout@v6 + with: + show-progress: false + persist-credentials: false + + - uses: actions/setup-node@v6 + with: + node-version: 20 + registry-url: "https://registry.npmjs.org" + + # Ensure npm 11.5.1 or later is installed. + # It is needed for + - name: Update npm + run: npm install -g npm@latest + + - name: Install dependencies without running scripts + working-directory: deltachat-jsonrpc/typescript + run: npm install --ignore-scripts + + - name: Package + working-directory: deltachat-jsonrpc/typescript + run: | + npm run build + npm pack . + + - name: Publish + working-directory: deltachat-jsonrpc/typescript + run: npm publish --provenance deltachat-jsonrpc-client-* --access public diff --git a/.github/workflows/jsonrpc.yml b/.github/workflows/jsonrpc.yml new file mode 100644 index 0000000000000000000000000000000000000000..35daf49e9c2cdf477090abaf10cc734b0b726eca --- /dev/null +++ b/.github/workflows/jsonrpc.yml @@ -0,0 +1,42 @@ +name: JSON-RPC API Test + +on: + push: + branches: [main] + pull_request: + branches: [main] + +permissions: {} + +env: + CARGO_TERM_COLOR: always + RUST_MIN_STACK: "8388608" + +jobs: + build_and_test: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v6 + with: + show-progress: false + persist-credentials: false + - name: Use Node.js 18.x + uses: actions/setup-node@v6 + with: + node-version: 18.x + - name: Add Rust cache + uses: Swatinem/rust-cache@779680da715d629ac1d338a641029a2f4372abb5 + - name: npm install + working-directory: deltachat-jsonrpc/typescript + run: npm install + - name: Build TypeScript, run Rust tests, generate bindings + working-directory: deltachat-jsonrpc/typescript + run: npm run build + - name: Run integration tests + working-directory: deltachat-jsonrpc/typescript + run: npm run test + env: + CHATMAIL_DOMAIN: ${{ vars.CHATMAIL_DOMAIN }} + - name: Run linter + working-directory: deltachat-jsonrpc/typescript + run: npm run prettier:check diff --git a/.github/workflows/nix.yml b/.github/workflows/nix.yml new file mode 100644 index 0000000000000000000000000000000000000000..08d65eb2436ecef449726b6091f8b66a96a49761 --- /dev/null +++ b/.github/workflows/nix.yml @@ -0,0 +1,109 @@ +name: Test Nix flake + +on: + pull_request: + paths: + - flake.nix + - flake.lock + - .github/workflows/nix.yml + push: + paths: + - flake.nix + - flake.lock + - .github/workflows/nix.yml + branches: + - main + +permissions: {} + +jobs: + format: + name: check flake formatting + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v6 + with: + show-progress: false + persist-credentials: false + - uses: cachix/install-nix-action@4e002c8ec80594ecd40e759629461e26c8abed15 # v31 + - run: nix fmt flake.nix -- --check + + build: + name: nix build + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + installable: + # Ensure `nix develop` will work. + - devShells.x86_64-linux.default + + - deltachat-python + - deltachat-repl + - deltachat-repl-aarch64-linux + - deltachat-repl-arm64-v8a-android + - deltachat-repl-armeabi-v7a-android + - deltachat-repl-armv6l-linux + - deltachat-repl-armv7l-linux + - deltachat-repl-i686-linux + - deltachat-repl-win32 + - deltachat-repl-win64 + - deltachat-repl-x86_64-linux + - deltachat-rpc-client + - deltachat-rpc-server + - deltachat-rpc-server-aarch64-linux + - deltachat-rpc-server-aarch64-linux-wheel + - deltachat-rpc-server-arm64-v8a-android + - deltachat-rpc-server-arm64-v8a-android-wheel + - deltachat-rpc-server-armeabi-v7a-android + - deltachat-rpc-server-armeabi-v7a-android-wheel + - deltachat-rpc-server-armv6l-linux + - deltachat-rpc-server-armv6l-linux-wheel + - deltachat-rpc-server-armv7l-linux + - deltachat-rpc-server-armv7l-linux-wheel + - deltachat-rpc-server-i686-linux + - deltachat-rpc-server-i686-linux-wheel + - deltachat-rpc-server-source + - deltachat-rpc-server-win32 + - deltachat-rpc-server-win32-wheel + - deltachat-rpc-server-win64 + - deltachat-rpc-server-win64-wheel + - deltachat-rpc-server-x86_64-linux + - deltachat-rpc-server-x86_64-linux-wheel + - docs + - libdeltachat + - python-docs + + # Fails to build + #- deltachat-repl-x86_64-android + #- deltachat-repl-x86-android + #- deltachat-rpc-server-x86_64-android + #- deltachat-rpc-server-x86-android + steps: + - uses: actions/checkout@v6 + with: + show-progress: false + persist-credentials: false + - uses: cachix/install-nix-action@4e002c8ec80594ecd40e759629461e26c8abed15 # v31 + - run: nix build .#${{ matrix.installable }} + + build-macos: + name: nix build on macOS + runs-on: macos-latest + strategy: + fail-fast: false + matrix: + installable: + - deltachat-rpc-server + - deltachat-rpc-server-x86_64-darwin + + # Fails to build + # because of . + # - deltachat-rpc-server-aarch64-darwin + steps: + - uses: actions/checkout@v6 + with: + show-progress: false + persist-credentials: false + - uses: cachix/install-nix-action@4e002c8ec80594ecd40e759629461e26c8abed15 # v31 + - run: nix build .#${{ matrix.installable }} diff --git a/.github/workflows/publish-deltachat-rpc-client-pypi.yml b/.github/workflows/publish-deltachat-rpc-client-pypi.yml new file mode 100644 index 0000000000000000000000000000000000000000..46049eac888c65de17ff4cf924c4cfa922296aab --- /dev/null +++ b/.github/workflows/publish-deltachat-rpc-client-pypi.yml @@ -0,0 +1,50 @@ +name: Publish deltachat-rpc-client to PyPI + +on: + workflow_dispatch: + release: + types: [published] + +permissions: {} + +jobs: + build: + name: Build distribution + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v6 + with: + show-progress: false + persist-credentials: false + - name: Install pypa/build + run: python3 -m pip install build + - name: Build a binary wheel and a source tarball + working-directory: deltachat-rpc-client + run: python3 -m build + - name: Store the distribution packages + uses: actions/upload-artifact@v6 + with: + name: python-package-distributions + path: deltachat-rpc-client/dist/ + + publish-to-pypi: + name: Publish Python distribution to PyPI + if: github.event_name == 'release' + needs: + - build + runs-on: ubuntu-latest + environment: + name: pypi + url: https://pypi.org/p/deltachat-rpc-client + permissions: + id-token: write + + steps: + - name: Download all the dists + uses: actions/download-artifact@v7 + with: + name: python-package-distributions + path: dist/ + - name: Publish deltachat-rpc-client to PyPI + uses: pypa/gh-action-pypi-publish@ed0c53931b1dc9bd32cbe73a98c7f6766f8a527e diff --git a/.github/workflows/repl.yml b/.github/workflows/repl.yml new file mode 100644 index 0000000000000000000000000000000000000000..da6d52bfc87f74dee58f37becfef54d2d3f12ae2 --- /dev/null +++ b/.github/workflows/repl.yml @@ -0,0 +1,28 @@ +# Manually triggered GitHub Actions workflow +# to build a Windows repl.exe which users can +# download to debug complex bugs. + +name: Build Windows REPL .exe + +on: + workflow_dispatch: + +permissions: {} + +jobs: + build_repl: + name: Build REPL example + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v6 + with: + show-progress: false + persist-credentials: false + - uses: cachix/install-nix-action@4e002c8ec80594ecd40e759629461e26c8abed15 # v31 + - name: Build + run: nix build .#deltachat-repl-win64 + - name: Upload binary + uses: actions/upload-artifact@v6 + with: + name: repl.exe + path: "result/bin/deltachat-repl.exe" diff --git a/.github/workflows/upload-docs.yml b/.github/workflows/upload-docs.yml new file mode 100644 index 0000000000000000000000000000000000000000..4f11702ff2fcad25b9d60230c44b49f4f449020d --- /dev/null +++ b/.github/workflows/upload-docs.yml @@ -0,0 +1,95 @@ +name: Build & deploy documentation on rs.delta.chat, c.delta.chat, and py.delta.chat + +on: + push: + branches: + - main + - build_jsonrpc_docs_ci + +permissions: {} + +jobs: + build-rs: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v6 + with: + show-progress: false + persist-credentials: false + - name: Build the documentation with cargo + run: | + cargo doc --package deltachat --no-deps --document-private-items + - name: Upload to rs.delta.chat + run: | + mkdir -p "$HOME/.ssh" + echo "${{ secrets.KEY }}" > "$HOME/.ssh/key" + chmod 600 "$HOME/.ssh/key" + rsync -avzh -e "ssh -i $HOME/.ssh/key -o StrictHostKeyChecking=no" $GITHUB_WORKSPACE/target/doc "${{ secrets.USERNAME }}@rs.delta.chat:/var/www/html/rs/" + + build-python: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v6 + with: + show-progress: false + persist-credentials: false + fetch-depth: 0 # Fetch history to calculate VCS version number. + - uses: cachix/install-nix-action@4e002c8ec80594ecd40e759629461e26c8abed15 # v31 + - name: Build Python documentation + run: nix build .#python-docs + - name: Upload to py.delta.chat + run: | + mkdir -p "$HOME/.ssh" + echo "${{ secrets.CODESPEAK_KEY }}" > "$HOME/.ssh/key" + chmod 600 "$HOME/.ssh/key" + rsync -avzh -e "ssh -i $HOME/.ssh/key -o StrictHostKeyChecking=no" $GITHUB_WORKSPACE/result/html/ "delta@py.delta.chat:/home/delta/build/master" + + build-c: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v6 + with: + show-progress: false + persist-credentials: false + fetch-depth: 0 # Fetch history to calculate VCS version number. + - uses: cachix/install-nix-action@4e002c8ec80594ecd40e759629461e26c8abed15 # v31 + - name: Build C documentation + run: nix build .#docs + - name: Upload to c.delta.chat + run: | + mkdir -p "$HOME/.ssh" + echo "${{ secrets.CODESPEAK_KEY }}" > "$HOME/.ssh/key" + chmod 600 "$HOME/.ssh/key" + rsync -avzh -e "ssh -i $HOME/.ssh/key -o StrictHostKeyChecking=no" $GITHUB_WORKSPACE/result/html/ "delta@c.delta.chat:/home/delta/build-c/master" + + build-ts: + runs-on: ubuntu-latest + defaults: + run: + working-directory: ./deltachat-jsonrpc/typescript + + steps: + - uses: actions/checkout@v6 + with: + show-progress: false + persist-credentials: false + fetch-depth: 0 # Fetch history to calculate VCS version number. + - name: Use Node.js + uses: actions/setup-node@v6 + with: + node-version: '18' + - name: npm install + run: npm install + - name: npm run build + run: npm run build + - name: Run docs script + run: npm run docs + - name: Upload to js.jsonrpc.delta.chat + run: | + mkdir -p "$HOME/.ssh" + echo "${{ secrets.KEY }}" > "$HOME/.ssh/key" + chmod 600 "$HOME/.ssh/key" + rsync -avzh -e "ssh -i $HOME/.ssh/key -o StrictHostKeyChecking=no" $GITHUB_WORKSPACE/deltachat-jsonrpc/typescript/docs/ "${{ secrets.USERNAME }}@js.jsonrpc.delta.chat:/var/www/html/js-jsonrpc/" diff --git a/.github/workflows/upload-ffi-docs.yml b/.github/workflows/upload-ffi-docs.yml new file mode 100644 index 0000000000000000000000000000000000000000..2d4e532fb571fa78d797d93254ffef948830ed30 --- /dev/null +++ b/.github/workflows/upload-ffi-docs.yml @@ -0,0 +1,31 @@ +# GitHub Actions workflow +# to build `deltachat_ffi` crate documentation +# and upload it to + +name: Build & Deploy Documentation on cffi.delta.chat + +on: + push: + branches: + - main + +permissions: {} + +jobs: + build: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v6 + with: + show-progress: false + persist-credentials: false + - name: Build the documentation with cargo + run: | + cargo doc --package deltachat_ffi --no-deps + - name: Upload to cffi.delta.chat + run: | + mkdir -p "$HOME/.ssh" + echo "${{ secrets.KEY }}" > "$HOME/.ssh/key" + chmod 600 "$HOME/.ssh/key" + rsync -avzh -e "ssh -i $HOME/.ssh/key -o StrictHostKeyChecking=no" $GITHUB_WORKSPACE/target/doc/ "${{ secrets.USERNAME }}@delta.chat:/var/www/html/cffi/" diff --git a/.github/workflows/zizmor-scan.yml b/.github/workflows/zizmor-scan.yml new file mode 100644 index 0000000000000000000000000000000000000000..228beb2de5cd177d7c3bb549ec54bf7762a2b757 --- /dev/null +++ b/.github/workflows/zizmor-scan.yml @@ -0,0 +1,31 @@ +name: GitHub Actions Security Analysis with zizmor + +on: + push: + branches: ["main"] + pull_request: + branches: ["**"] + +jobs: + zizmor: + name: zizmor latest via PyPI + runs-on: ubuntu-latest + permissions: + security-events: write + steps: + - name: Checkout repository + uses: actions/checkout@v6 + with: + persist-credentials: false + + - name: Install the latest version of uv + uses: astral-sh/setup-uv@681c641aba71e4a1c380be3ab5e12ad51f415867 + + - name: Run zizmor + run: uvx zizmor --format sarif . > results.sarif + + - name: Upload SARIF file + uses: github/codeql-action/upload-sarif@v4 + with: + sarif_file: results.sarif + category: zizmor diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..78c482c5c15e279179c3b78acf4a7a41d14c3e89 --- /dev/null +++ b/.gitignore @@ -0,0 +1,57 @@ +target/ +**/*.rs.bk +/build +/dist +/fuzz/fuzz_targets/corpus/ +/fuzz/fuzz_targets/crashes/ + +# ignore vi temporaries +*~ +*.swp +*.swo + +include +.dc-history.txt +*.db +*.db-blobs + +.tox +python/.eggs +*.egg-info +__pycache__ +python/src/deltachat/capi*.so +python/.venv/ +python/venv/ +venv/ +env/ + +python/liveconfig* + +# ignore doxgen generated files +deltachat-ffi/html +deltachat-ffi/xml + +.rsynclist + +coverage/ +.DS_Store +.vscode +.zed +python/accounts.txt +python/all-testaccounts.txt +tmp/ + +# from deltachat-node +node_modules/ +node/build/ +node/dist/ +node/prebuilds/ +node/.nyc_output/ + +# Nix symlink. +result + +# direnv +.envrc +.direnv +.aider* diff --git a/.npmignore b/.npmignore new file mode 100644 index 0000000000000000000000000000000000000000..bdf8be46af1a2f4133baad40a8d0e39f1c5b3a54 --- /dev/null +++ b/.npmignore @@ -0,0 +1,56 @@ +.circleci/ +.gitmodules +node/.nyc_output/ +.travis.yml +appveyor.yml +node/build/ +node/README.md +rustfmt.toml +spec.md +test-data/ +build2/ +node_modules +.git +.idea/ +.pytest_cache +CMakeLists.txt +README.md +contrib/ +node/ci_scripts/ +coverage/ +node/.circleci +node/appveyor.yml +ci/ +ci_scripts/ +python/ +target +proptest-regressions +deltachat-ffi/Doxyfile +scripts +webxdc.md +standards.md +draft/ +node/examples/ +# deltachat-core-rust/assets # don't exclude assets, otherwise it won't build +node/images/ +node/test/ +node/windows.md +node/*.tar.gz +node/old_docs.md +.vscode/ +.github/ +node/.prettierrc.yml + +deltachat-jsonrpc/TODO.md +deltachat-jsonrpc/README.MD +deltachat-jsonrpc/.gitignore +deltachat-jsonrpc/typescript/.gitignore +deltachat-jsonrpc/typescript/.prettierignore +deltachat-jsonrpc/typescript/accounts/ +deltachat-jsonrpc/typescript/index.html +deltachat-jsonrpc/typescript/node-demo.js +deltachat-jsonrpc/typescript/report_api_coverage.mjs +deltachat-jsonrpc/typescript/test +deltachat-jsonrpc/typescript/example.ts + +.DS_Store \ No newline at end of file diff --git a/.npmrc b/.npmrc new file mode 100644 index 0000000000000000000000000000000000000000..43c97e719a5a824700932f72e6e7e6748ce45d01 --- /dev/null +++ b/.npmrc @@ -0,0 +1 @@ +package-lock=false diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000000000000000000000000000000000000..bd3cfad98ae798aef5d682811f2a879e471ef48c --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,7509 @@ +# Changelog + +## [2.36.0] - 2026-01-03 + +### CI + +- Pin GitHub Action references. + +### API-Changes + +- Add transports event to FFI. + +### Features / Changes + +- Add core version to `receive_imf` failure message. +- Connectivity view: quota for all transports ([#7630](https://github.com/chatmail/core/pull/7630)). +- Send sync messages over SMTP and do not move them to mvbox. + +### Fixes + +- When accepting group, add members with `Origin::IncomingTo` and sort them down in the contact list (7592). +- Update fallback welcome message. +- `inner_configure`: Check Config::OnlyFetchMvbox before MvboxMove for multi-transport ([#7637](https://github.com/chatmail/core/pull/7637)). +- Reset options not available for chatmail on chatmail profiles. +- Don't send webxdc notification for `notify: "*"` when chat is muted ([#7658](https://github.com/chatmail/core/pull/7658)). + +### Documentation + +- `delete_chat()`: don't lie that messages aren't deleted from server. +- Remove references to removed `sentbox_watch` config. +- Update documentation for `TransportsModified` event. + +### Tests + +- Contact list after accepting group with unknown contacts ([#7592](https://github.com/chatmail/core/pull/7592)). +- Port test_import_export_online_all to JSON-RPC ([#7411](https://github.com/chatmail/core/pull/7411)). + +### Refactor + +- Turn `DC_VERSION_STR` into `&str`. +- ffi: Remove one pointer indirection for `dc_accounts_t`. + +### Miscellaneous Tasks + +- deps: Bump actions/download-artifact from 6 to 7. +- deps: Bump actions/upload-artifact from 5 to 6. +- deps: Bump astral-sh/setup-uv from 7.1.4 to 7.1.6. +- deps: Bump cachix/install-nix-action from 31.8.4 to 31.9.0. +- cargo: Bump serde_json from 1.0.145 to 1.0.147. +- cargo: Bump uuid from 1.18.1 to 1.19.0. +- cargo: Bump toml from 0.9.8 to 0.9.10+spec-1.1.0. +- cargo: Bump tempfile from 3.23.0 to 3.24.0. +- cargo: Bump libc from 0.2.177 to 0.2.178. +- cargo: Bump tracing from 0.1.41 to 0.1.44. +- cargo: Bump hyper-util from 0.1.18 to 0.1.19. +- cargo: Bump log from 0.4.28 to 0.4.29. +- cargo: Bump rustls-pki-types from 1.13.0 to 1.13.2. +- cargo: Bump criterion from 0.7.0 to 0.8.1. + +## [2.35.0] - 2025-12-16 + +### API-Changes + +- Add blob dir size to storage info ([#7605](https://github.com/chatmail/core/pull/7605)). + +### Features / Changes + +- Use `turn.delta.chat` as fallback TURN server ([#7382](https://github.com/chatmail/core/pull/7382)). +- Add ip addresses of known public chatmail relays from https://chatmail.at/relays to DNS cache ([#7607](https://github.com/chatmail/core/pull/7607)). +- Improve error messages on adding relays. +- Add transport addresses to IMAP URLs in message info. +- `lookup_host_with_cache()`: Don't return empty address list ([#7596](https://github.com/chatmail/core/pull/7596)). + +### Fixes + +- `get_chat_msgs_ex()`: Don't match on "S=" (Cmd) in param payload. +- Remove `SecurejoinWait` info message when received Alice's key ([#7585](https://github.com/chatmail/core/pull/7585)). +- Do not set normalized name for existing chats and contacts in a migration. +- Remove now redundant "used_account_settings" and "entered_account_settings" from `Context.get_info()` ([#7587](https://github.com/chatmail/core/pull/7587)). +- Don't use fallback servers if got TURN servers from IMAP METADATA. +- Use fallback ICE servers if server can't IMAP METADATA ([#7382](https://github.com/chatmail/core/pull/7382)). +- Add explicit limit for adding relays (5 at the moment) ([#7611](https://github.com/chatmail/core/pull/7611)). +- Take `transport_id` into account when using `imap` table. + +### CI + +- Update Rust to 1.92.0. + +### Miscellaneous Tasks + +- Apply Rust 1.92.0 clippy suggestions. + +### Other + +- Log entered login params and actual used params on configuration failure ([#7610](https://github.com/chatmail/core/pull/7610)). + +## [2.34.0] - 2025-12-11 + +### API-Changes + +- rpc-client: Accept `Account` for `Chat.{add,remove}_contact()`. +- rpc-client: Add `Chat.num_contacts()`. +- Forwarding messages to another profile ([#7491](https://github.com/chatmail/core/pull/7491)). + +### Features / Changes + +- Double ringing time to 120 seconds. +- Better logging for failing securejoin messages ([#7593](https://github.com/chatmail/core/pull/7593)). +- Add multi-transport information to `Context.get_info` ([#7583](https://github.com/chatmail/core/pull/7583)) + +### Fixes + +- Multi-transport: all transports were shown as "inbox" in connectivity view, now they are shown by their hostname ([#7582](https://github.com/chatmail/core/pull/7582)). +- Multi-transport: Synchronize primary transport immediately after changing it. +- Use u64 instead of usize to calculate storage usage. +- Use u64 to represent the number of bytes in backup files. +- Use u64 to count the number of bytes sent/received over the network. +- Use logging macros instead of emitting event directly, so that it is also logged by tracing ([#7459](https://github.com/chatmail/core/pull/7459)). +- Let securejoin succeed even if the chat was deleted in the meantime ([#7594](https://github.com/chatmail/core/pull/7594)). + +### Miscellaneous Tasks + +- Add RUSTSEC-2025-0134 exception to deny.toml. + +### Refactor + +- Use u16 instead of usize to represent progress bar. +- Remove EncryptHelper.prefer_encrypt. +- Add params when forwarding message instead of removing unneeded ones. + +### Tests + +- Port test_synchronize_member_list_on_group_rejoin to JSON-RPC. +- Test setting up second device between core versions. + +## [2.33.0] - 2025-12-05 + +### Features / Changes + +- Case-insensitive search for non-ASCII chat and contact names ([#7477](https://github.com/chatmail/core/pull/7477)). + +### Fixes + +- Recognize all transport addresses as own addresses. + +## [2.32.0] - 2025-12-04 + +Version bump to trigger publishing of npm prebuilds +that failed to be published for 2.31.0 due to not configured "trusted publishers". + +### Features / Changes + +- Lookup_or_create_adhoc_group(): Add context to SQL errors ([#7554](https://github.com/chatmail/core/pull/7554)). + +## [2.31.0] - 2025-12-04 + +### CI + +- Update npm before publishing packages. + +### Features / Changes + +- Use v2 SEIPD when sending messages to self. + +## [2.30.0] - 2025-12-04 + +### Features / Changes + +- Disable SNI for STARTTLS ([#7499](https://github.com/chatmail/core/pull/7499)). +- Introduce cross-core testing along with improvements to test frameworking. +- Synchronize transports via sync messages. + +### Fixes + +- Fix shutdown shortly after call. + +### API-Changes + +- Add `TransportsModified` event (for tests). + +### CI + +- Use "trusted publishing" for NPM packages. + +### Miscellaneous Tasks + +- deps: Bump actions/checkout from 5 to 6. +- cargo: Bump syn from 2.0.110 to 2.0.111. +- deps: Bump astral-sh/setup-uv from 7.1.3 to 7.1.4. +- cargo: Bump sdp from 0.8.0 to 0.10.0. +- Remove two outdated todo comments ([#7550](https://github.com/chatmail/core/pull/7550)). + +## [2.29.0] - 2025-12-01 + +### API-Changes + +- deltachat-rpc-client: Add Message.exists(). + +### Features / Changes + +- [**breaking**] Increase backup version from 3 to 4. +- Hide `To` header in encrypted messages. +- `deltachat_rpc_client.Rpc` accepts `rpc_server_path` for using a particular deltachat-rpc-server ([#7493](https://github.com/chatmail/core/pull/7493)). +- Don't send `Chat-Group-Avatar` header in unencrypted groups. +- Don't update `self-{avatar,status}` from received messages ([#7002](https://github.com/chatmail/core/pull/7002)). + +### Fixes + +- `CREATE INDEX imap_only_rfc724_mid ON imap(rfc724_mid)` ([#7490](https://github.com/chatmail/core/pull/7490)). +- Use the same webxdc ratelimit for all email servers. +- Handle the case when account does not exist in `get_existing_msg_ids()`. +- Don't send self-avatar in unencrypted messages ([#7136](https://github.com/chatmail/core/pull/7136)). +- Do not configure folders during transport configuration. +- Upload sync messages only with the primary transport. +- Do not use deprecated ConfiguredProvider in get_configured_provider. + +### Build system + +- Make scripts for remote testing usable. +- Increase minimum supported Python version to 3.10. +- Use SPDX license expression in Python package metadata. + +### CI + +- Set timeout-minutes for all jobs in ci.yaml workflow. +- Do not install Python manually to bulid RPC server wheels. +- Do not build fake RPC server source packages. +- Build Python wheels in separate jobs. + +### Refactor + +- [**breaking**] Remove some unneeded stock strings ([#7496](https://github.com/chatmail/core/pull/7496)). +- Strike events in rpc-client request handling, get result from queue. +- Use ConfiguredProvider config directly when loading legacy settings. +- Remove update_icons and disable_server_delete migrations. +- Use `SYMMETRIC_KEY_ALGORITHM` constant in `symm_encrypt_message()`. +- Make signing key non-optional for `pk_encrypt`. + +### Tests + +- `test_remove_member_bcc`: Test unencrypted group as it was initially. + +### Miscellaneous Tasks + +- deps: Bump cachix/install-nix-action from 31.8.1 to 31.8.4. +- cargo: Bump hyper from 1.7.0 to 1.8.1. +- cargo: Bump human-panic from 2.0.3 to 2.0.4. +- cargo: Bump hyper-util from 0.1.17 to 0.1.18. +- cargo: Bump rusqlite from 0.36.0 to 0.37.0. +- cargo: Bump tokio-util from 0.7.16 to 0.7.17. +- cargo: Bump toml from 0.9.7 to 0.9.8. +- cargo: Bump proptest from 1.8.0 to 1.9.0. +- cargo: Bump parking_lot from 0.12.4 to 0.12.5. +- cargo: Bump syn from 2.0.106 to 2.0.110. +- cargo: Bump quick-xml from 0.38.3 to 0.38.4. +- cargo: Bump rustls-pki-types from 1.12.0 to 1.13.0. +- cargo: Bump nu-ansi-term from 0.50.1 to 0.50.3. +- cargo: Bump sanitize-filename from 0.5.0 to 0.6.0. +- cargo: Bump quote from 1.0.41 to 1.0.42. +- cargo: Bump libc from 0.2.176 to 0.2.177. +- cargo: Bump bytes from 1.10.1 to 1.11.0. +- cargo: Bump image from 0.25.8 to 0.25.9. +- cargo: Bump rand from 0.9.0 to 0.9.2 ([#7501](https://github.com/chatmail/core/pull/7501)). +- cargo: Bump tokio from 1.45.1 to 1.48.0. + +## [2.28.0] - 2025-11-23 + +### API-Changes + +- New API `get_existing_msg_ids()` to check if the messages with given IDs exist. +- Add API to get storage usage information. (JSON-RPC method: `get_storage_usage_report_string`) ([#7486](https://github.com/chatmail/core/pull/7486)). + +### Features / Changes + +- Experimentaly allow adding second transport. + There is no synchronization yet, so UIs should not allow the user to change the address manually and only expose the ability to add transports if `bcc_self` is disabled. +- Default `bcc_self` to 0 for all new accounts. +- Rephrase "Establishing end-to-end encryption" -> "Establishing connection". +- Stock string for joining a channel ([#7480](https://github.com/chatmail/core/pull/7480)). + +### Fixes + +- Limit the range of `Date` to up to 6 days in the past. +- `ContactId::set_name_ex()`: Emit ContactsChanged when transaction is completed. +- Set SQLite busy timeout to 1 minute on iOS. +- Sort system messages to the bottom of the chat. +- Assign outgoing self-sent unencrypted messages to ad-hoc groups with only SELF ([#7409](https://github.com/chatmail/core/pull/7409)). +- Add missing stock strings. +- Look up or create ad-hoc group if there are duplicate addresses in "To". + +### Documentation + +- Add missing RFC 9788, link 'Header Protection for Cryptographically Protected Email' as other RFC. +- Remove unsupported RFC 3503 (`$MDNSent` flag) from the list of standards. +- Mark database encryption support as deprecated ([#7403](https://github.com/chatmail/core/pull/7403)). + +### Build system + +- Increase Minimum Supported Rust Version to 1.88.0. +- Update rPGP from 0.17.0 to 0.18.0. +- nix: Update `fenix` and use it for all Rust builds. + +### CI + +- Do not use --encoding option for rst-lint. + +### Refactor + +- Use `HashMap::extract_if()` stabilized in Rust 1.88.0. +- Remove some easy to remove unwrap() calls. + +### Tests + +- Contact shalln't be verified by another having unknown verifier. + +## [2.27.0] - 2025-11-16 + +### API-Changes + +- Add APIs to stop background fetch. +- [**breaking**]: rename JSON-RPC method accounts_background_fetch() into background_fetch() +- rpc-client: Add APIs for background fetch. +- rpc-client: Add Account.wait_for_msg(). +- Deprecate deletion timer string for '1 Minute'. + +### Features / Changes + +- Implement RFC 9788 (Header Protection for Cryptographically Protected Email) ([#7130](https://github.com/chatmail/core/pull/7130)). +- Tweak initial info-message for unencrypted chats ([#7427](https://github.com/chatmail/core/pull/7427)). +- Add Contact::get_or_gen_color. Use it in CFFI and JSON-RPC to avoid gray self-color ([#7374](https://github.com/chatmail/core/pull/7374)). +- [**breaking**] Withdraw broadcast invites. Add Qr::WithdrawJoinBroadcast and Qr::ReviveJoinBroadcast QR code types. ([#7439](https://github.com/chatmail/core/pull/7439)). + +### Fixes + +- Set `get_max_smtp_rcpt_to` for chatmail to the actual limit of 1000 instead of unlimited. ([#7432](https://github.com/chatmail/core/pull/7432)). +- Always set bcc_self on backup import/export. +- Escape connectivity HTML. +- Send webm as file, it is not supported by all UI. + +### Build system + +- nix: Exclude CONTRIBUTING.md from the source files. + +### Refactor + +- Use wait_for_incoming_msg() in more tests. + +### Tests + +- Fix flaky test_send_receive_locations. +- Port folder-related CFFI tests to JSON-RPC. +- HP-Outer headers are added to messages with standard Header Protection ([#7130](https://github.com/chatmail/core/pull/7130)). +- rpc-client: Test_qr_securejoin_broadcast: Wait for incoming message before getting chatlist ([#7442](https://github.com/chatmail/core/pull/7442)). +- Add pytest fixture for account manager. +- Test background_fetch() and stop_background_fetch(). + +## [2.26.0] - 2025-11-11 + +### API-Changes + +- [**breaking**] JSON-RPC: `chat_type` now contains a variant of a string enum/union. Affected places: `FullChat.chat_type`, `BasicChat.chat_type`, `ChatListItemFetchResult::ChatListItem.chat_type`, `Event:: SecurejoinInviterProgress.chat_type` and `MessageSearchResult.chat_type` ([#7285](https://github.com/chatmail/core/pull/7285)) + +### Features / Changes + +- Error toast for "Not creating securejoin QR for old broadcast". + +### Fixes + +- `is_encrypted()` should be true for Saved Messages chat so messages there are editable. +- Do not return an error from `receive_imf` if we fail to add a member because we are not in chat. +- Do not add QR inviter to groups immediately. +- Do not ignore I/O errors in `BlobObject::store_from_base64`. + +### Miscellaneous Tasks + +- Rustfmt. + +### Refactor + +- imap: Move resync request from Context to Imap. +- Replace imap:: calls in migration 73 with SQL queries. +- Remove unused imports. + +### Documentation + +- Readme: update language binding section to avoid usage of cffi in new projects ([#7380](https://github.com/chatmail/core/pull/7380)). +- Fix Context::set_stock_translation reference. + +### Tests + +- Test editing saved messages. +- Remove ThreadPoolExecutor from test_wait_next_messages. +- Move test_two_group_securejoins from receive_imf to securejoin module. +- At the end of securejoin Bob has two members in a group chat. +- Bob has 0 members in the chat until securejoin finishes. +- Do not add QR inviter to groups right after scanning the code. + +## [2.25.0] - 2025-11-05 + +### Features / Changes + +- Put self-name into group invite codes ([#7398](https://github.com/chatmail/core/pull/7398)). +- Slightly nicer and shorter QR and invite codes ([#7390](https://github.com/chatmail/core/pull/7390)) + +### Fixes + +- Add device message instead of partial message when receive_imf fails. This fixes a rare bug where the IMAP loop got stuck. +- Add info message if user tries to create a QR code for deprecated channel ([#7399](https://github.com/chatmail/core/pull/7399)). + +### Miscellaneous Tasks + +- deps: Bump actions/upload-artifact from 4 to 5. +- deps: Bump actions/download-artifact from 5 to 6. +- deps: Bump astral-sh/setup-uv from 7.1.0 to 7.1.2. + +### Refactor + +- sql: Do not expose rusqlite Error type in query_map methods. + +## [2.24.0] - 2025-11-03 + +***Note that in v2.24.0, the IMAP loop can get stuck in rare circumstances; +use v2.23.0 or v2.25.0 instead.*** + +### Documentation + +- Comment why spaced en dash is used to separate message Subject from text. + +### Features / Changes + +- [**breaking**] QR codes and symmetric encryption for broadcast channels ([#7268](https://github.com/chatmail/core/pull/7268)). + - A new QR type AskJoinBroadcast; cloning a broadcast + channel is no longer possible; manually adding a member to a broadcast + channel is no longer possible (the only way to join a channel is scanning a QR code or clicking a link) + +### Refactor + +- Split "transport" module out of "login_param". + +## [2.23.0] - 2025-11-01 + +### API-Changes + +- Make `dc_chat_is_protected` always return 0. +- [**breaking**] Remove public APIs to check if the chat is protected. +- [**breaking**] Remove APIs to create protected chats. +- [**breaking**] Remove Chat.is_protected(). +- deltachat-rpc-client: Add Account.add_transport_from_qr() API. +- JSON-RPC: add `get_push_state` to check push notification state ([#7356](https://github.com/chatmail/core/pull/7356)). +- JSON-RPC: remove unused TypeScript constants ([#7355](https://github.com/chatmail/core/pull/7355)). +- Remove `Config::SentboxWatch` ([#7178](https://github.com/chatmail/core/pull/7178)). +- Remove `Config::ConfiguredSentboxFolder` and everything related. + +### Build system + +- Ignore configuration for the zed editor ([#7322](https://github.com/chatmail/core/pull/7322)). +- nix: Fix build of deltachat-rpc-server-x86_64-darwin. +- Update rand to 0.9. +- Do not install `pdbpp` in the test environment for CFFI Python bindings. +- Migrate from tokio-tar to astral-tokio-tar. +- deps: Bump actions/setup-node from 5 to 6. +- deps: Bump cachix/install-nix-action from 31.8.0 to 31.8.1. +- Fix Rust 1.91.0 lint for derivable Default. + +### CI + +- Pin GitHub action `astral-sh/setup-uv`. +- Set 7 days cooldown on Dependabot updates. +- Update Rust to 1.91.0. + +### Documentation + +- Document Autocrypt-Gossip `_verified` attribute. + +### Features/Changes + +Metadata reduction: +- Protect Autocrypt header. +- Anonymize OpenPGP recipients (temorarily disabled due to interoperability problems, see ). +- Protect the `Date` header. + +Onboarding improvements: +- Allow plain domain in `dcaccount:` scheme. +- Do not resolve MX records during configuration. + +Preparation for multi-transport: +- Move the messages only from INBOX and Spam folders. +- deltachat-rpc-client: Support multiple transports in resetup_account(). + +Various other changes: +- Opt-in weekly sending of statistics ([#6851](https://github.com/chatmail/core/pull/6851)) +- Synchronize encrypted groups creation across devices ([#7001](https://github.com/chatmail/core/pull/7001)). +- Do not send Autocrypt in MDNs. +- Do not run SecureJoin if we are already in the group. +- Show if proxy is enabled in connectivity view ([#7359](https://github.com/chatmail/core/pull/7359)). + +### Fixes + +- Don't ignore QR token timestamp from sync messages. +- Do not allow sync item timestamps to be in the future. +- jsonrpc: Fix `ChatListItem::is_self_in_group`. +- Delete obsolete "configured*" keys from `config` table ([#7171](https://github.com/chatmail/core/pull/7171)). +- Fix flaky tests::verified_chats::test_verified_chat_editor_reordering and receive_imf::receive_imf_tests::test_two_group_securejoins. +- Stop using `leftgrps` table. +- Stop notifying about messages in contact request chats. + +### Refactor + +- Remove invalid Gmail OAuth2 tokens. +- Remove ProtectionStatus. +- Rename chat::create_group_chat() to create_group(). +- Remove error stock strings that are rarely used these days ([#7327](https://github.com/chatmail/core/pull/7327)). +- Jsonrpc rename change casing in names of jsonrpc structs/enums to comply with rust naming conventions. ([#7324](https://github.com/chatmail/core/pull/7324)). +- Stop using deprecated Account.configure(). +- add_transport_from_qr: Do not set deprecated config values. +- sql: Change second query_map function from FnMut to FnOnce. +- sql: Add query_map_vec(). +- sql: Add query_map_collect(). +- Use rand::fill() instead of rand::rng().fill(). +- Use SampleString. +- Remove unused call to get_credentials(). + +### Tests + +- rpc-client: VCard color is the same as the contact color ([#7294](https://github.com/chatmail/core/pull/7294)). +- Add unique offsets to ids generated by `TestContext` to increase test correctness ([#7297](https://github.com/chatmail/core/pull/7297)). + +## [2.22.0] - 2025-10-17 + +### Fixes + +- Do not notify about incoming calls for contact requests and blocked contacts. + +### Tests + +- Accept the chat with the caller before accepting calls. + +## [2.21.0] - 2025-10-16 + +### Build system + +- nix: Remove unused dependencies. + +### Features / Changes + +- TLS 1.3 session resumption. +- REPL: Add send-sync command. +- Set `User-Agent` for tile.openstreetmap.org requests. +- Cache tile.openstreetmap.org tiles for 7 days. + +### Fixes + +- Remove Exif with non-fatal errors from images. +- jsonrpc: Use Core's logic for computing VcardContact.color ([#7294](https://github.com/chatmail/core/pull/7294)). + +### Miscellaneous Tasks + +- deps: Bump cachix/install-nix-action from 31.7.0 to 31.8.0. +- cargo: Bump async_zip from 0.0.17 to 0.0.18 ([#7257](https://github.com/chatmail/core/pull/7257)). +- deps: Bump github/codeql-action from 3 to 4 ([#7304](https://github.com/chatmail/core/pull/7304)). + +### Refactor + +- Use rustls reexported from tokio_rustls. +- Pass ALPN around as &str. +- mimeparser: Store only one signature fingerprint. + +### Tests + +- Test expiration of ephemeral messages with unknown viewtype. +- Test expiration of non-ephemeral message with unknown viewtype. + +## [2.20.0] - 2025-10-13 + +This release fixes a bug that resulted in ephemeral loop getting stuck in infinite loop +when trying to delete a message with unknown viewtype. + +### Fixes + +- Accept unknown viewtype in ephemeral loop. +- Accept unknown viewtype in delete-old-messages loop. + +## [2.19.0] - 2025-10-12 + +### Features / Changes + +- Slightly increase saturation of colors. + +### Fixes + +- Do not fail to receive call accepted/ended messages referring to non-call Message-ID. +- Do not fail to fully download previously trashed messages. +- Emit AccountsItemChanged when own key is generated/imported, use gray self-color until that ([#7296](https://github.com/chatmail/core/pull/7296)). +- Do not try to process calls from partial messages. + +### CI + +- Update to Python 3.14. + +### Refactor + +- Use variables directly in formatted strings ([#7284](https://github.com/chatmail/core/pull/7284)). +- Set_chat_profile_image(): Remove !chat.is_mailing_list() check. + +### Miscellaneous Tasks + +- cargo: Bump quick-xml from 0.37.5 to 0.38.3. +- Add nodejs to nix dev env ([#7283](https://github.com/chatmail/core/pull/7283)) + +## [2.18.0] - 2025-10-08 + +### API-Changes + +- [**breaking**] Remove APIs for video chat invitations. + +### CI + +- nix: Run the workflow when workflow file changes. +- nix: Switch from DeterminateSystems/nix-installer-action to cachix/install-nix-action. + +### Features / Changes + +- No implicit member changes from old Delta Chat clients ([#7220](https://github.com/chatmail/core/pull/7220)). + +### Fixes + +- Do not fail to load messages with unknown viewtype. +- Only omit group changes messages if SELF is really added ([#7220](https://github.com/chatmail/core/pull/7220)). + +### Refactor + +- Assert that Iroh node addresses have home relay URL. + +## [2.17.0] - 2025-10-04 + +### API-Changes + +- [**breaking**] Remove deprecated verified_one_on_one_chats config. + +### CI + +- Require that Cargo.lock is up to date. +- Fix CI checking Nix formatting. + +### Documentation + +- Comment about outdated timespan. +- Clarify CALL events ([#7188](https://github.com/chatmail/core/pull/7188)). +- Add docs for JS `BaseDeltaChat`. + +### Features / Changes + +- Make `text/calendar` alternative available as an attachment. +- Better summary for calls. +- Add strings 'You left the channel.' and 'Scan to join Channel' ([#7266](https://github.com/chatmail/core/pull/7266)). +- Stock strings for calls. +- ffi: Add DC_STR_CANT_DECRYPT_OUTGOING_MSGS define. + +### Fixes + +- Prefer last part in `multipart/alternative`. +- Prefetch messages in limited batches ([#6915](https://github.com/chatmail/core/pull/6915)). +- Forward calls as text messages. +- Consistent spelling of "canceled" with a single "l". +- Lowercase "call" in "Missed call" and similar strings. + +### Refactor + +- Return the reason when failing to place calls. + +### Tests + +- Test reception of `multipart/alternative` with `text/calendar`. + +## [2.16.0] - 2025-10-01 + +### API-Changes + +- [**breaking**] Get rid of inviter progress other than 0 and 1000. +- Add has_video attribute to incoming call events. +- Add JSON-RPC API to get ICE servers. +- Add call_info() JSON-RPC API. +- Add chat ID to SecureJoinInviterProgress. +- deltachat-rpc-client: Add Chat.resend_messages(). +- Add `chat_id` to all call events ([#7216](https://github.com/chatmail/core/pull/7216)). + +### Build system + +- Update rPGP from 0.16.0 to 0.17.0. + +### CI + +- Update Rust to 1.90.0. +- Install rustfmt before checking provider database. + +### Documentation + +- Add more `get_next_event` docs. +- SecurejoinInviterProgress never returns an error. + +### Features / Changes + +- Don't fetch messages from unknown folders ([#7190](https://github.com/chatmail/core/pull/7190)). +- Get ICE servers from IMAP METADATA. +- Don't ignore receive_imf_inner() errors, try adding partially downloaded message instead ([#7196](https://github.com/chatmail/core/pull/7196)). +- Set dimensions for outgoing Sticker messages. + +### Fixes + +- Create 1:1 chat only if auth token is for setup contact. +- Ignore vc-/vg- prefix for SecurejoinInviterProgress. +- Don't init Iroh on channel leave ([#7210](https://github.com/chatmail/core/pull/7210)). +- Take the last valid Autocrypt header ([#7167](https://github.com/chatmail/core/pull/7167)). +- Don't add "member removed" messages from nonmembers ([#7207](https://github.com/chatmail/core/pull/7207)). +- Do not consider the call stale if it is not sent out yet. +- Receive_imf: Report replaced message id in `MsgsChanged` if chat is the same. +- Allow Exif for stickers, don't recode them because of that ([#6447](https://github.com/chatmail/core/pull/6447)). + +### Refactor + +- Remove unused prop (TS, `BaseDeltaChat`). +- Remove unused FolderMeaning::Drafts. + +### Tests + +- Rename test_udpate_call_text into test_update_call_text. +- Update timestamp_sent in pop_sent_msg_opt(). +- Do not match call ID from second alice with first alice event. + +## [2.15.0] - 2025-09-15 + +### API-Changes + +- Add JSON-RPC API for calls ([#7194](https://github.com/chatmail/core/pull/7194)). + +### Build system + +- Remove unused `quoted_printable` dependency. + +## [2.14.0] - 2025-09-12 + +### API-Changes + +- Put the chattype into the SecurejoinInviterProgress event ([#7181](https://github.com/chatmail/core/pull/7181)). + +### Fixes + +- param: Split params only on \n. +- B-encode SDP offer and answer sent in headers. + +### Refactor + +- Use recv_msg_trash() instead of recv_msg_opt(). +- Prepare_msg_raw(): don't return MsgId. + +### Tests + +- Message is OutFailed if all keys are missing ([#6849](https://github.com/chatmail/core/pull/6849)). +- Test sending SDP offer and answer with newlines. + +## [2.13.0] - 2025-09-09 + +### API-Changes + +- [**breaking**] Remove `is_profile_verified` APIs. +- [**breaking**] Remove deprecated `is_protection_broken`. +- [**breaking**] Remove `e2ee_enabled` preference. + +### Features / Changes + +- Add call ringing API ([#6650](https://github.com/chatmail/core/pull/6650), [#7174](https://github.com/chatmail/core/pull/7174), [#7175](https://github.com/chatmail/core/pull/7175), [#7179](https://github.com/chatmail/core/pull/7179)) +- Warn for outdated versions after 6 months instead of 1 year ([#7144](https://github.com/chatmail/core/pull/7144)). +- Do not set "unknown sender for this chat" error. +- Do not replace messages with an error on verification failure. +- Support receiving Autocrypt-Gossip with `_verified` attribute. +- Withdraw all QR codes when one is withdrawn. + +### Fixes + +- Don't reverify contacts by SELF on receipt of a message from another device. +- Don't verify contacts by others having an unknown verifier. +- Update verifier_id if it's "unknown" and new verifier has known verifier. +- Mark message as failed if it can't be sent ([#7143](https://github.com/chatmail/core/pull/7143)). +- Add "Messages are end-to-end encrypted." to non-protected groups. + +### Documentation + +- Fix for SecurejoinInviterProgress with progress == 600. +- STYLE.md: Prefer BTreeMap and BTreeSet over hash variants. + +### Miscellaneous Tasks + +- Update provider database. +- Update dependencies. + +### Refactor + +- Check that verifier is verified in turn. +- Remove unused `EncryptPreference::Reset`. +- Remove `Aheader::new`. + +### Tests + +- Add another TimeShiftFalsePositiveNote ([#7142](https://github.com/chatmail/core/pull/7142)). +- Add TestContext.create_chat_id. + +## [2.12.0] - 2025-08-26 + +### API-Changes + +- api!(python): remove remaining broken API for reactions + +### Features / Changes + +- Use Group ID for chat color generation instead of the name for encrypted groups. +- Use key fingerprints instead of addresses for key-contacts color generation. +- Replace HSLuv colors with OKLCh. +- `wal_checkpoint()`: Do `wal_checkpoint(PASSIVE)` and `wal_checkpoint(FULL)` before `wal_checkpoint(TRUNCATE)`. +- Assign messages to key-contacts based on Issuer Fingerprint. +- Create_group_ex(): Log and replace invalid chat name with "…". + +### Fixes + +- Do not create a group if the sender includes self in the `To` field. +- Do not reverify already verified contacts via gossip. +- `get_connectivity()`: Get rid of locking SchedulerState::inner ([#7124](https://github.com/chatmail/core/pull/7124)). +- Make reaction message hidden only if there are no other parts. + +### Refactor + +- Do not return `Result` from `valid_signature_fingerprints()`. +- Make `ConnectivityStore` use a non-async lock ([#7129](https://github.com/chatmail/core/pull/7129)). + +### Documentation + +- Remove broken link from documentation comments. +- Remove the comment about Color Vision Deficiency correction. + +## [2.11.0] - 2025-08-13 + +### Features / Changes + +- Contact::lookup_id_by_addr_ex: Prefer returning key-contact. +- Contact::lookup_id_by_addr_ex: Prefer returning accepted contacts. +- Better string when using disappearing messages of one year (365..367 days, so it can be tweaked later). +- Do not require resent messages to be from the same chat. +- `lookup_key_contact_by_address()`: Allow looking up ContactId::SELF without chat id. +- `get_securejoin_qr()`: Log error if group doesn't have grpid. +- `receive_imf::add_parts()`: Get rid of extra `Chat::load_from_db()` calls. + +### Fixes + +- Ignore case when trying to detect 'invalid unencrypted mail' and add an info-message. +- Run wal_checkpoint during housekeeping ([#6089](https://github.com/chatmail/core/pull/6089)). +- Allow receiving empty files. +- Set correct sent_timestamp for saved outgoing messages. +- Do not remove query parameters from URLs. +- Log and set imex progress error ([#7091](https://github.com/chatmail/core/pull/7091)). +- Do not add key-contacts to unencrypted groups. +- Do not reset `GuaranteeE2ee` in the database when resending messages. +- Assign messages to a group if there is a `Chat-Group-Name`. +- Take `Chat-Group-Name` into account when matching ad hoc groups. +- Don't break long group names with non-ASCII characters. +- Add messages that can't be verified as `DownloadState::Available` ([#7059](https://github.com/chatmail/core/pull/7059)). + +### Tests + +- Log the number of the test account if there are multiple alices ([#7087](https://github.com/chatmail/core/pull/7087)). + +### CI + +- Update Rust to 1.89.0. + +### Refactor + +- Rename icon-address-contact to icon-unencrypted. +- Skip loading the contact of 1:1 unencrypted chat to show the avatar. +- Chat::is_encrypted(): Make one query instead of two for 1:1 chats. + +### Miscellaneous Tasks + +- cargo: Bump toml from 0.8.23 to 0.9.4. +- cargo: Bump human-panic from 2.0.2 to 2.0.3. +- deny.toml: Add exception for duplicate toml_datetime 0.6.11 dependency. +- deps: Bump actions/checkout from 4 to 5. +- deps: Bump actions/download-artifact from 4 to 5. + +## [2.10.0] - 2025-08-04 + +### Features / Changes + +- Also lookup key contacts in lookup_id_by_addr() ([#7073](https://github.com/chatmail/core/pull/7073)). + +### Miscellaneous Tasks + +- cargo: Bump serde_json from 1.0.140 to 1.0.142. +- cargo: Bump bolero from 0.13.3 to 0.13.4. +- cargo: Bump async-channel from 2.3.1 to 2.5.0. +- cargo: Bump hyper-util from 0.1.14 to 0.1.16. +- cargo: Bump criterion from 0.6.0 to 0.7.0. +- cargo: Bump strum from 0.27.1 to 0.27.2. +- cargo: Bump strum_macros from 0.27.1 to 0.27.2. +- Upgrade async-imap to 0.11.1. + +## [2.9.0] - 2025-07-31 + +### Features / Changes + +- repl: Add import-vcard and make-vcard commands ([#7048](https://github.com/chatmail/core/pull/7048)). + +### Fixes + +- Display correct timer value for ephemeral timer changes. +- Get_chat_msgs_ex(): Report local midnight in ChatItem::DayMarker. + +### Refactor + +- Rename add_or_lookup_key_contacts_by_address_list() to add_or_lookup_key_contacts(). +- Don't call add_or_lookup_key_contacts() in advance. + +## [2.8.0] - 2025-07-28 + +### Features / Changes + +- Remove ProtectionBroken, make such chats Unprotected ([#7041](https://github.com/chatmail/core/pull/7041)). + +### Fixes + +- Lookup self by address if there is no fingerprint or gossip. + +## [2.7.0] - 2025-07-26 + +### Features / Changes + +- Mimefactory: Order message recipients by time of addition ([#6872](https://github.com/chatmail/core/pull/6872)). +- Put the debug/release build version into the info ([#7034](https://github.com/chatmail/core/pull/7034)). + +### Fixes + +- Realtime late join ([#6869](https://github.com/chatmail/core/pull/6869)). +- Do not fail to upgrade if the verifier of a contact doesn't exist anymore ([#7044](https://github.com/chatmail/core/pull/7044)). + +### Tests + +- Add regression test for verification-gossiping crash ([#7033](https://github.com/chatmail/core/pull/7033)). + +## [2.6.0] - 2025-07-23 + +### Fixes + +- Fix crash when receiving a verification-gossiping message which a contact also sends to itself ([#7032](https://github.com/chatmail/core/pull/7032)). + +## [2.5.0] - 2025-07-22 + +### Fixes + +- Correctly migrate "verified by me". +- Mark all email chats as unprotected in the migration ([#7026](https://github.com/chatmail/core/pull/7026)). +- Do not ignore errors in add_flag_finalized_with_set. + +### Documentation + +- Deprecate protection-broken and related stuff ([#7018](https://github.com/chatmail/core/pull/7018)). +- Clarify the meaning of is_verified() vs verifier_id() ([#7027](https://github.com/chatmail/core/pull/7027)). +- STYLE.md: Prefer `try_next()` over `next()`. + +## [2.4.0] - 2025-07-21 + +### Fixes + +- Do not ignore errors when draining FETCH responses. This avoids IMAP loop getting stuck in an infinite loop retrying reading from the connection. +- Update `tokio-io-timeout` to 1.2.1. This release includes a fix to reset timeout after every error, so timeout error is returned at most once a minute if read is attempted after a timeout. + +### Miscellaneous Tasks + +- Update async-imap to 0.11.0. + +### Refactor + +- Use `try_next()` when processing FETCH responses. + +## [2.3.0] - 2025-07-19 + +### Features / Changes + +- Add "e2ee encrypted" info message to all e2ee chats ([#7008](https://github.com/chatmail/core/pull/7008)). +- repl: Print errors and debug logs to stderr. +- `{ensure_and,logged}_debug_assert`: Don't evaluate condition twice. +- Log when background fetch of all accounts finishes successfully. +- Log the number of read/written bytes on IMAP stream read error ([#6924](https://github.com/chatmail/core/pull/6924)). + +### Fixes + +- Ignore protected headers in outer message part ([#6357](https://github.com/chatmail/core/pull/6357)). +- List e-mail contacts in repl listcontacts command. +- Save peer address for LoggingStream early. + +## [2.2.0] - 2025-07-14 + +### API-Changes + +- Add chat::create_group_ex(), deprecate create_group_chat() ([#6927](https://github.com/chatmail/core/pull/6927)). +- jsonrpc: Add CommandApi::create_group_chat_unencrypted() ([#6927](https://github.com/chatmail/core/pull/6927)). +- [**breaking**] In ChatListItem, replace is_group and is_(out_)broadcast with chat_type property ([#7003](https://github.com/chatmail/core/pull/7003)). + +### Features / Changes + +- Log failed debug assertions in all configurations. +- Donation request device message ([#6913](https://github.com/chatmail/core/pull/6913)). +- Advance next UID even if connection fails while fetching. + +### Fixes + +- Always prefer the last header. + +### Tests + +- Tune down DELTACHAT_SAVE_TMP_DB hint ([#6998](https://github.com/chatmail/core/pull/6998)). +- Unencrypted group creation ([#6927](https://github.com/chatmail/core/pull/6927)). + +## [2.1.0] - 2025-07-11 + +### Features / Changes + +- Add account ordering functionality ([#6993](https://github.com/chatmail/core/pull/6993)). +- feat: Make it possible to leave broadcast channels ([#6984](https://github.com/chatmail/core/pull/6984)) +- Migrations: Use tools::Time to measure time for logging. +- Log emitted logging events with `tracing`. +- Ensure_and_debug_assert{,_eq,_ne} macros combining `debug_assert*` and anyhow::ensure ([#6907](https://github.com/chatmail/core/pull/6907)). + +### Fixes + +- Use Viewtype::File for messages with invalid images, images of unknown size, images > 50 Mpx ([#6825](https://github.com/chatmail/core/pull/6825)). +- Don't apply chat name and avatar changes from non-members. + +### Documentation + +- Update showpadlock ffi. + +### Miscellaneous Tasks + +- cargo: Update cordyceps from 0.3.2 to 0.3.4. + +### Tests + +- Add option to save database on test failure ([#6992](https://github.com/chatmail/core/pull/6992)). + +## [2.0.0] - 2025-07-09 + +This release changes the way the core handles contact keys. +Instead of tracking OpenPGP keys corresponding to the +contacts in [Autocrypt](https://autocrypt.org/) peerstate, +the core creates a new "key-contact" for each known public key. +Reception of a message signed with a new unknown key +no longer results in warnings about setup changes, +but creates a new contact and a new 1:1 chat if necessary. +Additionally, there are "address-contacts" corresponding +to the e-mail addresses. + +### Features / Changes + +- Key-contacts ([#6796](https://github.com/chatmail/core/pull/6796), [#6941](https://github.com/chatmail/core/pull/6941)). +- Increase event channel size from 1000 to 10000. +- Minimize the amount of data preserved for trashed messages. +- Show broadcast channels in their own, proper "Channel" chat ([#6901](https://github.com/chatmail/core/pull/6901), [#6975](https://github.com/chatmail/core/pull/6975)). +- Check images passed as `File` before making them `Image`. + +### API-Changes + +- CFFI: Add dc_contact_is_key_contact() ([#6955](https://github.com/chatmail/core/pull/6955)). +- Contact::get_all(): Support listing address-contacts. +- [**breaking**] Add InBroadcastChannel, OutBroadcastChannel chattypes, add create_broadcast_channel() ([#6901](https://github.com/chatmail/core/pull/6901)). +- deltachat-rpc-client: Add Message.get_read_receipts(). + +### Fixes + +- Remove display name from get_info(). This information usually goes at the top of the log and we don't want users to include it in bug reports. +- Wait for scheduler tasks shutdown in parallel. +- Update deltachat-repl help and autocomplete to match implementation ([#6978](https://github.com/chatmail/core/pull/6978), ([#6979](https://github.com/chatmail/core/pull/6979)). +- Send Autocrypt header in MDNs. This is needed to assign MDNs to key-contacts. +- Prefer encrypted List-Id header ([#6983](https://github.com/chatmail/core/pull/6983)). +- Treat "tgs" as Viewtype::File. +- Treat and send images that can't be decoded as Viewtype::File. +- Decide on filename used for sending depending on the original Viewtype. +- Migrate_key_contacts(): Remove "id>9" from encrypted messages SELECT. +- Save msgs to key-contacts migration state and run migration periodically ([#6956](https://github.com/chatmail/core/pull/6956)). +- Do not try to lookup key-contacts for unencrypted 1:1 messages. +- Add query to post request for account creation ([#6989](https://github.com/chatmail/core/pull/6989)). + +### CI + +- Update Rust to 1.88.0. + +### Documentation + +- Remove outdated comment that says MDNs are unencrypted. + +### Refactor + +- Upgrade to Rust 2024. +- Build_body_file(): Remove guessing mimetype by file extension. + +### Tests + +- Add online test for read receipts. +- Add a test reproducing chat assignment bug. + +### Miscellaneous Tasks + +- cargo: Bump smallvec from 1.15.0 to 1.15.1. +- cargo: Bump syn from 2.0.101 to 2.0.104. +- cargo: Bump hyper-util from 0.1.13 to 0.1.14. +- cargo: Bump toml from 0.8.19 to 0.8.23. +- cargo: Bump proptest from 1.6.0 to 1.7.0. +- cargo: Bump libc from 0.2.172 to 0.2.174. + +## [1.160.0] - 2025-06-22 + +### API-Changes + +- [**breaking**] jsonrpc: remove webxdc info from MessageObject. + Users need to call `get_webxdc_info` separately now + and expect that the call may fail e.g. if WebXDC is not a valid ZIP archive. +- [**breaking**] Deprecate `DC_GCL_VERIFIED_ONLY`. +- [**breaking**] Make logging macros private. + +### Features / Changes + +- Add more IMAP logging. +- Sort apps by recently-updated ([#6875](https://github.com/chatmail/core/pull/6875)). +- Better error for quoting a message from another chat. +- Put "biography" in the vCard ([#6819](https://github.com/chatmail/core/pull/6819)). + +### Fixes + +- Do not allow chat creation if decryption failed. +- Remove faulty test ([#6880](https://github.com/chatmail/core/pull/6880)). +- Reduce the scope of the last_full_folder_scan lock in scan_folders. +- Ignore verification error if the chat is not protected yet. +- Create group chats unprotected on verification error. +- `fetch_url`: return err on non 2xx reponses. +- Sort multiple saved messages by timestamp ([#6862](https://github.com/chatmail/core/pull/6862)). +- contact-tools: Escape commas in vCards' FN, KEY, PHOTO, NOTE ([#6912](https://github.com/chatmail/core/pull/6912)). +- Don't change ConfiguredAddr when adding a transport ([#6804](https://github.com/chatmail/core/pull/6804)). + +### Build system + +- Increase MSRV to 1.85.0. +- Update Doxygen config and layout file. +- Update to rPGP 0.16.0 ([#6719](https://github.com/chatmail/core/pull/6719)). +- Enable async-native-tls/vendored feature. +- Update rusqlite to 0.36.0. + +### CI + +- Update Rust to 1.87.0. +- nix: Test build on macOS without cross-compilation. +- Use installed toolchain to lint Rust. + +### Refactor + +- Remove explicit lock drop at the end of scope. +- Use CancellationToken instead of a 1-message channel. + +### Documentation + +- Add more code style guide references. + +## [1.159.5] - 2025-05-14 + +### Fixes + +- Don't change webxdc self-addr when saving and loading draft ([#6854](https://github.com/chatmail/core/pull/6854)). + +### Miscellaneous Tasks + +- Remove duplicate miniz_oxide dependency. +- Update async-smtp to 0.10.2. + +## [1.159.4] - 2025-05-13 + +### Documentation + +- Add missing documentation to deltachat-rpc-client. + +### Features / Changes + +- Better avatar quality ([#6822](https://github.com/chatmail/core/pull/6822)). +- Update iroh from 0.33.0 to 0.35.0 ([#6687](https://github.com/chatmail/core/pull/6687)). +- Other dependency updates. + +### Fixes + +- Emit progress(0) in case AEAP is tried. +- Replace `FuturesUnordered` from `futures` with `JoinSet` from `tokio`. +- Fix order of operations when handling "vc-request-with-auth" ([#6850](https://github.com/chatmail/core/pull/6850)). +- Generate rfc724_mid when creating Message ([#6704](https://github.com/chatmail/core/pull/6704)) + +### Tests + +- Profile data is attached to group leave messages. + +## [1.159.3] - 2025-04-24 + +### CI + +- Use `ubuntu-latest` runner for `@deltachat/jsonrpc-client` publishing. + +## [1.159.2] - 2025-04-23 + +### Fixes + +- Allow to send to chats after failed securejoin again ([#6817](https://github.com/chatmail/core/pull/6817)). +- Parse login scheme in `add_transport_from_qr()` ([#6802](https://github.com/chatmail/core/pull/6802)). +- Lowercase address in add_transport() ([#6805](https://github.com/chatmail/core/pull/6805)). + +### API-Changes + +- Rename add_transport() -> add_or_update_transport() ([#6800](https://github.com/chatmail/core/pull/6800)). + +### Miscellaneous Tasks + +- Update yerpc to 0.6.4. +- Clean up `deltachat-jsonrpc` dependencies. + +### Refactor + +- Move logins into SQL table ([#6724](https://github.com/chatmail/core/pull/6724)). + +### Tests + +- Check headers absense straightforwardly. +- Fix mismatch between the contact and the account in securejoin tests. +- Test that key of the recipient is gossiped in 1:1 chats. + +## [1.159.1] - 2025-04-12 + +### API-Changes + +- deltachat-rpc-client: Add `Account.add_transport()`. +- Add jsonrpc for info_contact_id. + +### Build system + +- Update crossbeam-channel from 0.5.14 to 0.5.15. +- Increase MSRV to 1.82.0. + +### CI + +- Don't make ruff format quiet ([#6785](https://github.com/chatmail/core/pull/6785)). + +### Documentation + +- MimeFactory.member_timestamps has the same order as To: rather than RCPT TO:. +- Two JsonRPC doc improvements ([#6778](https://github.com/chatmail/core/pull/6778)). + +### Features / Changes + +- Improve error message when the user tries to do AEAP ([#6786](https://github.com/chatmail/core/pull/6786)). +- Pass email and password via env in python-jsonrpc. +- Track gossiping per (chat, fingerprint) pair. + +### Fixes + +- Add missing ChatDeleted event to python jsonrpc client. +- Never send Autocrypt-Gossip in broadcast lists. +- Restart I/O when mvbox_move setting is changed. + +### Tests + +- Port test_delete_deltachat_folder to JSON-RPC. +- Autocrypt-Gossip header isn't sent in broadcast messages. +- Encrypt test_subject_in_group(). +- Encrypt test_remove_member_bcc. + +## [1.159.0] - 2025-04-08 + +### API-Changes + +- deltachat-rpc-client: Add Message.get_info(). +- CFFI: Add `dc_make_vcard()` and `dc_import_vcard()`. +- Add legacy Python bindings for `make_vcard` and `import_vcard`. + +### CI + +- Upgrade Rust from 1.84.1 to 1.86.0 ([#6784](https://github.com/chatmail/core/pull/6784)). + +### Features / Changes + +- Add name resp. "Me" to contact encryption info ([#6720](https://github.com/chatmail/core/pull/6720)). +- Get contact-id for info messages ([#6714](https://github.com/chatmail/core/pull/6714)). +- No unencrypted chat when securejoin times out ([#6722](https://github.com/chatmail/core/pull/6722)). +- Clear `Param::IsEdited` when forwarding a message. +- Remove email address from 'add second device' qr code ([#6760](https://github.com/chatmail/core/pull/6760)). +- Parse Proton Mail vCards again ([#6771](https://github.com/chatmail/core/pull/6771)). +- Do not consider encrypting to the primary OpenPGP key. + +### Fixes + +- jsonrpc: Fix deadlock in get_all_accounts(). +- Set GroupNameTimestamp on group promotion ([#6729](https://github.com/chatmail/core/pull/6729)). +- Encrypt broadcast lists. + +### Miscellaneous Tasks + +- Update yerpc to 0.6.3. +- cargo: Update textwrap from 0.16.1 to 0.16.2. +- cargo: Bump uuid from 1.15.1 to 1.16.0. +- cargo: Bump libc from 0.2.170 to 0.2.171. +- cargo: Bump anyhow from 1.0.96 to 1.0.97. +- cargo: Bump bytes from 1.10.0 to 1.10.1. +- cargo: Bump once_cell from 1.20.3 to 1.21.3. +- cargo: Bump thiserror from 2.0.11 to 2.0.12. +- cargo: Bump pin-project from 1.1.9 to 1.1.10. +- cargo: Bump hyper-util from 0.1.10 to 0.1.11. +- cargo: Bump log from 0.4.26 to 0.4.27. +- cargo: Bump tokio-util from 0.7.13 to 0.7.14. +- cargo: Bump syn from 2.0.98 to 2.0.100. +- cargo: Bump serde_json from 1.0.139 to 1.0.140. +- cargo: Bump quote from 1.0.38 to 1.0.40. +- cargo: Bump http-body-util from 0.1.2 to 0.1.3. +- cargo: Bump openssl from 0.10.71 to 0.10.72. +- cargo: Bump quick-xml from 0.37.2 to 0.37.4. +- cargo: Bump blake3 from 1.6.1 to 1.8.0. +- cargo: Bump tokio from 1.43.0 to 1.43.1 ([#6780](https://github.com/chatmail/core/pull/6780)). +- Add issue template. +- Add bug label on bug issue template. +- cargo: Bump tokio from 1.43.0 to 1.44.1. +- cargo: Bump fd-lock from 4.0.2 to 4.0.4. +- Update async-smtp from 0.10.0 to 0.10.1. +- Update async-imap from 0.10.3 to 0.10.4. +- cargo: Bump tempfile from 3.14.0 to 3.19.1. +- cargo: Bump image from 0.25.5 to 0.25.6. +- cargo: Bump serde from 1.0.218 to 1.0.219. + +### Other + +- Add python and tox to flake.nix devshell ([#6233](https://github.com/chatmail/core/pull/6233)) +- Update spec wrt edit/delete, minor rewordings ([#6708](https://github.com/chatmail/core/pull/6708)) +- Update 'takes longer' fallback wording. +- Handle classic emails as such only in classic profiles ([#6767](https://github.com/chatmail/core/pull/6767)) +- Move ASM strings to core, point to "Add Second Device" ([#6777](https://github.com/chatmail/core/pull/6777)) + +### Refactor + +- Replace `once_cell::sync::Lazy` with `std::sync::LazyLock`. +- Move vCard code to its own file ([#6776](https://github.com/chatmail/core/pull/6776)). + +### Tests + +- Use encryption in more Rust tests. +- Use encryption in all JSON-RPC online tests. +- Encrypt legacy Python tests. +- Send only encrypted messages in online JS tests. +- Add APIs to create `dom@example.net` and `elena@example.net`. +- Split public keys from secret keys in runtime. +- Remove fetch_existing tests. +- Port test_forward_encrypted_to_unencrypted from legacy Python to Rust. +- Port test_one_account_send_bcc_setting from legacy Python to JSON-RPC. +- Port test_multidevice_sync_seen to JSON-RPC. +- Use QR codes to setup contact with test bots. +- Remove flaky key::tests::test_load_self_existing test ([#6763](https://github.com/chatmail/core/pull/6763)). +- Update blob hash in blob::blob_tests::test_selfavatar_outside_blobdir. + +## [1.158.0] - 2025-03-29 + +### API-Changes + +- deltachat-rpc-client: Accept `Account` as `Account.create_contact()` argument. +- Rust: Add `ContactId.set_name()`. +- JSON-RPC: Rename parameter name in `get_webxdc_href` to `info_msg_id` to reduce confusion potential ([#6681](https://github.com/chatmail/core/pull/6681)). + +### Features / Changes + +- Nicer configuration error ([#6684](https://github.com/chatmail/core/pull/6684)). +- securejoin: Do not create 1:1 chat on Alice's side until `vc-request-with-auth`. +- Understandable error message when accounts.lock can't be locked ([#6695](https://github.com/chatmail/core/pull/6695)). +- Simplify e2ee decision logic, remove majority vote. +- Stop saving txt_raw. + +### Fixes + +- Do not fail to send the message if some keys are missing. +- Synchronize contact name changes. +- Move group name timestamp update up in create_send_msg_jobs(). +- Fixes for transport JSON-RPC ([#6680](https://github.com/chatmail/core/pull/6680)). + +### Build system + +- deltachat-rpc-client: Move development dependencies from tox.ini to pyproject.toml. +- Update resolve-conf from 0.7.0 to 0.7.1. + +### Refactor + +- Do not convert SQL arguments to `String` unnecessarily. +- Factor out `update_chat_names()`. +- Use `created_timestamp()` instead of duplicating its code ([#6692](https://github.com/chatmail/core/pull/6692)). +- Use `chat_id.get_timestamp()` instead of duplicating its code ([#6691](https://github.com/chatmail/core/pull/6691)). +- Move `mark_recipients_as_verified()` call out of `has_verified_encryption()`. +- Move `proxy_config` out of `ConfiguredLoginParam` ([#6712](https://github.com/chatmail/core/pull/6712)). + +### Tests + +- Use vCard in TestContext.add_or_lookup_contact(). +- Remove test_group_with_removed_message_id. +- Use add_or_lookup_address_contact() in get_chat(). +- Use add_or_lookup_address_contact in test_setup_contact_ex. +- Use vCards more in Python tests. +- Use TestContextManager in more tests. +- Use vCards to create contacts in more Rust tests. +- Set chat name multiple times in a row. +- Online test for renaming the group multiple times. + +## [1.157.3] - 2025-03-19 + +### API-Changes + +- jsonrpc: Add `copy_to_blob_dir` api ([#6660](https://github.com/chatmail/core/pull/6660)). +- Add "delete_for_all" function in json-rpc ([#6672](https://github.com/chatmail/core/pull/6672)). +- Sketch add_transport_from_qr(), add_transport(), list_transports(), delete_transport() APIs ([#6589](https://github.com/chatmail/core/pull/6589)). + +### Build system + +- Remove websocket support from deltachat-jsonrpc. +- Remove encoded-words dependency. + +### Fixes + +- Never send empty `To:` header ([#6663](https://github.com/chatmail/core/pull/6663)). +- Use protected `Date` header for signed messages. +- Fix setting up a profile and immediately transferring to a second device ([#6657](https://github.com/chatmail/core/pull/6657)). +- Don't SMTP-send self-only messages if DeleteServerAfter is "immediate" ([#6661](https://github.com/chatmail/core/pull/6661)). +- Use protected `Date` with protected Autocrypt. + +### Miscellaneous Tasks + +- cargo: Bump uuid from 1.12.1 to 1.15.1. +- Update `strum` dependency. + +### Refactor + +- deltachat-rpc-client: Use wait_for_event() type argument. + +### Tests + +- Avoid creating contacts in `test_sync_{accept,block}_before_first_msg()`. +- Fix `test_no_old_msg_is_fresh` flakiness. + +## [1.157.2] - 2025-03-15 + +### Fixes + +- Prefer hidden Message-ID header if any. +- Update async-compression to 0.4.21 to fix IMAP COMPRESS getting stuck. + +### Refactor + +- Extract handle_edit_delete() function for message edit/delete ([#6664](https://github.com/chatmail/core/pull/6664)). + +### Tests + +- test_secure_join: Bob should not create a 1:1 chat before sending a message. +- Return chat ID from TestContext.exec_securejoin_qr(). + +## [1.157.1] - 2025-03-13 + +### Miscellaneous Tasks + +- Update repository URLs to make npm and PyPI publishing possible. + +## [1.157.0] - 2025-03-12 + +### Features / Changes + +- Ignore encryption preferences. + +### API-Changes + +- deltachat-rpc-client: Make it possible to clone accounts. +- deltachat-rpc-client: Add Account.device_contact. +- deltachat-rpc-client: Add Account.get_device_chat(). +- deltechat-rpc-client: Add Account.wait_for_msgs_noticed_event(). +- ffi: Store reference pointer to Context in dc_chat_t. + +### Build system + +- Intergrate `fuzz` crate into workspace. +- Update env_logger to get rid of unmaintained humantime dependency. +- nix: Update NDK to 27.2.12479018. +- Build Android wheels for PyPI. + +### Documentation + +- deltachat-rpc-client: Document Account.check_qr(). +- deltachat-rpc-client: Document Account.import_vcard(). + +### Fixes + +- Update async-imap to 0.10.23 to fix division by zero. +- Ignore hidden headers in IMF section. +- Process Autocrypt-Gossip only after merging protected headers. + +### Miscellaneous Tasks + +- cargo: Bump smallvec from 1.13.2 to 1.14.0. + +### Tests + +- Deletion request fails in an unencrypted chat and the message remains. +- python: port `test_no_old_msg_is_fresh` to JSON-RPC. + +## [1.156.3] - 2025-03-09 + +### API-Changes + +- jsonrpc: Add import_vcard_contents() method. +- jsonrpc: Add API to make and import vCards. +- [**breaking**] Remove save_mime_headers config option and dc_get_mime_headers(). +- [**breaking**] Remove key_gen_type config. + +### Features / Changes + +- Add chat-deleted event. +- Delete messages on IMAP when deleting chat ([#6613](https://github.com/chatmail/core/pull/6613)). +- Allow doubled avatar resolution + +### Fixes + +- Move Chat-Group-Avatar to hidden headers. +- Ignore outer Chat-User-Avatar header in Autocrypt-encrypted messages. + +### Build system + +- Use mailbuilder from crates.io. +- Update iroh to 0.33. + +### Documentation + +- Nonstandard headers needing DKIM protection should be hidden. + +### Refactor + +- Recode_to_size(): Rename strict_limits to is_avatar. + +### Tests + +- Test for ChatDeleted event. +- Replace create_chat() with get_chat() in test_setup_contact_ex() and test_secure_join(). +- Transfer vCards in TestContext.create_chat(). + +## [1.156.2] - 2025-03-02 + +### Fixes + +- Upgrade native-tls from 0.2.13 to 0.2.14. This fixes "Accept invalid certificates" failing on Android with "OpenSSL error". The bug was there since 1.156.0 due to upgrade of native-tls from 0.2.11 to 0.2.13. + +### Features / Changes + +- Show sender name in 'Saved Messages' summary ([#6607](https://github.com/chatmail/core/pull/6607)). +- Sync chats deletion across devices. + +### Documentation + +- Add DC_QR_BACKUP_TOO_NEW documentation. + +### Miscellaneous Tasks + +- cargo: Bump anyhow from 1.0.95 to 1.0.96. +- cargo: Bump serde from 1.0.217 to 1.0.218. + +## [1.156.1] - 2025-02-28 + +### Fixes + +- Update mailparse to 0.16.1 to fix panic when parsing a message. +- Add Chat-Group-Name-Timestamp header and use it to update group names ([#6412](https://github.com/chatmail/core/pull/6412)). +- Log tokio::fs::metadata errors. + +### Build system + +- Update fuzzing setup. + +## [1.156.0] - 2025-02-26 + +### API-Changes + +- Save messages API in JSON RPC ([#6554](https://github.com/chatmail/core/pull/6554)). +- jsonrpc: Add `MessageObject.is_edited`. +- jsonrpc: Add `send_edit_request`. +- Deduplicate blob files in the JsonRPC API ([#6470](https://github.com/chatmail/core/pull/6470)). +- Message deletion request API ([#6576](https://github.com/chatmail/core/pull/6576)) + +### Features / Changes + +- Edit message's text ([#6550](https://github.com/chatmail/core/pull/6550)) +- Sync message deletion to other devices ([#6573](https://github.com/chatmail/core/pull/6573)) +- Allow scanning multiple securejoin QR codes in parallel. +- When reactions are seen, remove notification from second device ([#6480](https://github.com/chatmail/core/pull/6480)). +- Enable bcc-self automatically when doing Autocrypt Setup Message. +- Don't send a notification when a group member left ([#6575](https://github.com/chatmail/core/pull/6575)). +- Fail on too new backups ([#6580](https://github.com/chatmail/core/pull/6580)). + +### Fixes + +- Make it impossible to overwrite default key. +- Do not allow to edit html messages ([#6564](https://github.com/chatmail/core/pull/6564)). +- `get_config(Config::Selfavatar)` returns the path, not the name ([#6570](https://github.com/chatmail/core/pull/6570)). +- `chat::save_msgs`: Interrupt inbox loop to send a sync message. +- Do not delete files if cannot read their metadata. + +### Build system + +- nix: Update hashes of git dependencies. +- Update some dependencies. + +### CI + +- Remove deprecated DeterminateSystems/magic-nix-cache-action. + +### Refactor + +- Use mail-builder instead of lettre_email. +- Move even even more tests into their own files ([#6559](https://github.com/chatmail/core/pull/6559)). +- Remove `Message.set_file()`, `dc_msg_set_file()` and related code ([#6558](https://github.com/chatmail/core/pull/6558)). +- Remove unused blob functions ([#6563](https://github.com/chatmail/core/pull/6563)). +- Let `BlobObject::from_name()` take `&str` ([#6571](https://github.com/chatmail/core/pull/6571)). +- Don't use traits where it's not necessary ([#6567](https://github.com/chatmail/core/pull/6567)). + +## [1.155.6] - 2025-02-17 + +### Features / Changes + +- Sort past members by the timestamp of removal. +- Use UUID v4 to generate Message-IDs. + +### Fixes + +- Use dedicated ID for sync messages affecting device chat. +- Do not allow non-members to change ephemeral timer settings. +- Show padlock when the message is not sent over the network. + +### Build system + +- Remove deprecated node module. + +### CI + +- Audit workflows with zizmor. + +### Documentation + +- Improve docstrings ([#6496](https://github.com/chatmail/core/pull/6496)). + +## [1.155.5] - 2025-02-14 + +### Fixes + +- Get_filename() is now guaranteed to return a valid filename ([#6537](https://github.com/chatmail/core/pull/6537)). + +### Miscellaneous Tasks + +- Add RUSTSEC-2025-0006 to deny.toml. + +### Refactor + +- Do not cancel the task returned from async_imap `Handle.wait_with_timeout`. + +## [1.155.4] - 2025-02-10 + +### CI + +- Upgrade Rust from 1.84.0 to 1.84.1. + +### Fixes + +- Use CRLF newlines in vCards. +- Make vCard parsing more robust in case of trailing newlines. +- Do not include CRLF before MIME boundary in the part body. +- Accept QR codes with 'broken' JSON ([#6528](https://github.com/chatmail/core/pull/6528)). + +### Other + +- Add `MessageQuote.chat_id`. + +### Refactor + +- Move even more tests into their own files ([#6521](https://github.com/chatmail/core/pull/6521)). + +## [1.155.3] - 2025-02-05 + +### Fixes + +- Store device token in IMAP METADATA on each connection. + +### Miscellaneous Tasks + +- Upgrade iroh from 0.30 to 0.32. +- Update `pgp` to 0.15. +- cargo: Bump thiserror from 1.0.69 to 2.0.9. +- cargo: Bump pin-project from 1.1.7 to 1.1.8. +- cargo: Bump dirs from 5.0.1 to 6.0.0. +- cargo: Bump hyper from 1.5.2 to 1.6.0. +- cargo: Bump webpki-roots from 0.26.7 to 0.26.8. +- cargo: Bump futures-lite from 2.5.0 to 2.6.0. +- Update OpenSSL to fix RUSTSEC-2025-0004. +- cargo: Bump tokio from 1.42.0 to 1.43.0. +- cargo: Bump syn from 2.0.94 to 2.0.98. +- cargo: Bump rustls from 0.23.20 to 0.23.22. +- cargo: Bump data-encoding from 2.6.0 to 2.7.0. +- cargo: Bump serde_json from 1.0.134 to 1.0.138. +- cargo: Bump uuid from 1.11.0 to 1.12.1. +- cargo: Bump log from 0.4.22 to 0.4.25. +- cargo: Bump rustls-pki-types from 1.10.1 to 1.11.0. +- Update futures-concurrency. + +### Documentation + +- Assign docs to correct object. + +### Tests + +- Make sure DCBACKUP2 compatibility does not break again. + +## [1.155.2] - 2025-01-31 + +This release accidentally broke compatibility +with previous versions of `DCBACKUP2` QR codes +due to iroh upgrade. + +### API-Changes + +- Add `IncomingReaction.chat_id` ([#6459](https://github.com/chatmail/core/pull/6459)). + +### Features / Changes + +- Deduplicate blob files in `chat.rs`, `config.rs`, and `integration.rs`. +- Improve logging around IMAP IDLE. +- Upgrade to iroh@0.30.0. + +### Fixes + +- Don't remove file extension when recoding avatars. +- Use `BufReader` when reading .xdc files. +- No implicit member changes when we are added to the group ([#6493](https://github.com/chatmail/core/pull/6493)). + +### Documentation + +- jsonrpc: Update documentation for `select_account` and `get_selected_account_id` ([#6483](https://github.com/chatmail/core/pull/6483)). +- jsonrpc: Add docs for some functions. + +## [1.155.1] - 2025-01-25 + +### Features / Changes + +- Only accept SetContacts sync messages for broadcast lists. + +### Fixes + +- Don't create tombstones when synchronizing broadcast list members. +- Use non-empty `To:` field for "saved messages". +- Only send Chat-Group-Member-Timestamps in groups. +- Use 0 timestamps if Chat-Group-Member-Timestamps is not set. + +### Refactor + +- Remove BlobObject::create(), use create_and_deduplicate_from_bytes() instead ([#6467](https://github.com/chatmail/core/pull/6467)). +- Move more tests into their own files ([#6473](https://github.com/chatmail/core/pull/6473)). + +## [1.155.0] - 2025-01-23 + +### API-Changes + +- Add JSON-RPC API to get past members. + +### Build system + +- Update Rust. +- Increase MSRV to 1.81.0 + +### Features / Changes + +- feat: Set BccSelf to true when receiving a sync message ([#6434](https://github.com/chatmail/core/pull/6434)) +- File deduplication ([#6332](https://github.com/chatmail/core/pull/6332)) + +### Refactor + +- Move tests to their own files. +- Extract `group_changes_msgs()` function ([#6460](https://github.com/chatmail/core/pull/6460)). + +## [1.154.3] - 2025-01-20 + +### Build system + +- Remove encoded-words from flake.nix. +- nix: Update rust-email hash in flake.nix. + +### Miscellaneous Tasks + +- Remove unused function delete_files_in_dir() ([#6454](https://github.com/chatmail/core/pull/6454)). + +## [1.154.2] - 2025-01-20 + +### Features / Changes + +- Add API to save messages ([#5606](https://github.com/chatmail/core/pull/5606)). + +### Fixes + +- fix: Don't accidentally remove Self from groups ([#6455](https://github.com/chatmail/core/pull/6455)). +- Do not create tombstones for members removed from unpromoted groups. + +### Build system + +- Switch to non-git version of encoded-words. + +### Refactor + +- Make memberlist update logic easier to follow. + +## [1.154.1] - 2025-01-15 + +### Tests + +- Expect trashing of no-op "member added" in non_member_cannot_modify_member_list. + +## [1.154.0] - 2025-01-15 + +### Features / Changes + +- New group consistency algorithm. + +### Fixes + +- Migration: Set bcc_self=1 if it's unset and delete_server_after!=1 ([#6432](https://github.com/chatmail/core/pull/6432)). +- Clear the config cache after every migration ([#6438](https://github.com/chatmail/core/pull/6438)). + +### Build system + +- Increase minimum supported Python version to 3.8. +- [**breaking**] Remove jsonrpc feature flag. + +### CI + +- Update Rust to 1.84.0. + +### Miscellaneous Tasks + +- Beta Clippy suggestions ([#6422](https://github.com/chatmail/core/pull/6422)). + +### Refactor + +- Use let..else. +- Add why_cant_send_ex() capable to only ignore specified conditions. +- Remove unnecessary is_contact_in_chat check. +- Eliminate remaining repeat_vars() calls ([#6359](https://github.com/chatmail/core/pull/6359)). + +### Tests + +- Use assert_eq! to compare chatlist length. + +## [1.153.0] - 2025-01-05 + +### Features / Changes + +- Remove "jobs" from imap_markseen if folder doesn't exist ([#5870](https://github.com/chatmail/core/pull/5870)). +- Delete `vg-request-with-auth` from IMAP after processing ([#6208](https://github.com/chatmail/core/pull/6208)). + +### API-Changes + +- Add `IncomingWebxdcNotify.chat_id` ([#6356](https://github.com/chatmail/core/pull/6356)). +- rpc-client: Add INCOMING_REACTION to const.EventType ([#6349](https://github.com/chatmail/core/pull/6349)). + +### Documentation + +- Viewtype::Sticker may be changed to Image and how to disable that ([#6352](https://github.com/chatmail/core/pull/6352)). + +### Fixes + +- Never change Viewtype::Sticker to Image if file has non-image extension ([#6352](https://github.com/chatmail/core/pull/6352)). +- Change BccSelf default to 0 for chatmail ([#6340](https://github.com/chatmail/core/pull/6340)). +- Mark holiday notice messages as bot-generated. +- Don't treat location-only and sync messages as bot ones ([#6357](https://github.com/chatmail/core/pull/6357)). +- Update shadowsocks crate to 1.22.0 to avoid panic when parsing some QR codes. +- Prefer to encrypt if E2eeEnabled even if peers have EncryptPreference::NoPreference. +- Prioritize mailing list over self-sent messages. +- Allow empty `To` field for self-sent messages. +- Default `to_id` to self instead of 0. + +### Refactor + +- Remove unused parameter and return value from `build_body_file(…)` ([#6369](https://github.com/chatmail/core/pull/6369)). +- Deprecate Param::ErroneousE2ee. +- Add `emit_msgs_changed_without_msg_id`. +- Add_parts: Remove excessive `is_mdn` checks. +- Simplify `self_sent` condition. +- Don't ignore get_for_contact errors. + +### Tests + +- Messages without recipients are assigned to self chat. +- Message with empty To: field should have a valid to_id. +- Fix `test_logged_ac_process_ffi_failure` flakiness. + +## [1.152.2] - 2024-12-24 + +### Features / Changes + +- Emit ImexProgress(1) after receiving backup size. +- `delete_msgs`: Use `transaction()` instead of `call_write()`. +- Start ephemeral timers when the chat is noticed. +- Start ephemeral timers when the chat is archived. +- Revalidate HTTP cache entries once per minute maximum. + +### Fixes + +- Reduce number of `repeat_vars()` calls. +- `sanitise_name`: Don't consider punctuation and control chars as part of file extension ([#6362](https://github.com/chatmail/core/pull/6362)). + +### Refactor + +- Remove marknoticed_chat_if_older_than(). + +### Miscellaneous Tasks + +- Remove contrib/ directory. + +## [1.152.1] - 2024-12-17 + +### Build system + +- Downgrade Rust version used to build binaries. +- Reduce MSRV to 1.77.0. + +## [1.152.0] - 2024-12-12 + +### API-Changes + +- [**breaking**] Remove `dc_prepare_msg` and `dc_msg_is_increation`. + +### Build system + +- Increase MSRV to 1.81.0. + +### Features / Changes + +- Cache HTTP GET requests. +- Prefix server-url in info. +- Set `mime_modified` for the last message part, not the first ([#4462](https://github.com/chatmail/core/pull/4462)). + +### Fixes + +- Render "message" parts in multipart messages' HTML ([#4462](https://github.com/chatmail/core/pull/4462)). +- Ignore garbage at the end of the keys. + +## [1.151.6] - 2024-12-11 + +### Features / Changes + +- Don't add "Failed to send message to ..." info messages to group chats. +- Add info messages about implicit membership changes if group member list is recreated ([#6314](https://github.com/chatmail/core/pull/6314)). + +### Fixes + +- Add self-addition message to chat when recreating member list. +- Do not subscribe to heartbeat if already subscribed via metadata. + +### Build system + +- Add idna 0.5.0 exception into deny.toml. + +### Documentation + +- Update links to Node.js bindings in the README. + +### Refactor + +- Factor out `wait_for_all_work_done()`. + +### Tests + +- Notifiy more prominently & in more tests about false positives when running `cargo test` ([#6308](https://github.com/chatmail/core/pull/6308)). + +## [1.151.5] - 2024-12-05 + +### API-Changes + +- [**breaking**] Remove dc_all_work_done(). + +### Security + +- cargo: Update rPGP to 0.14.2. + + This fixes [Panics on Malformed Untrusted Input](https://github.com/rpgp/rpgp/security/advisories/GHSA-9rmp-2568-59rv) + and [Potential Resource Exhaustion when handling Untrusted Messages](https://github.com/rpgp/rpgp/security/advisories/GHSA-4grw-m28r-q285). + This allows the attacker to crash the application via specially crafted messages and keys. + We recommend all users and bot operators to upgrade to the latest version. + There is no impact on the confidentiality of the messages and keys so no action other than upgrading is needed. + +### Fixes + +- Store plaintext in mime_headers of truncated sent messages ([#6273](https://github.com/chatmail/core/pull/6273)). + +### Documentation + +- Document `push` module. +- Remove mention of non-existent `nightly` feature. + +### Tests + +- Fix panic in `receive_emails` benchmark ([#6306](https://github.com/chatmail/core/pull/6306)). + +## [1.151.4] - 2024-12-03 + +### Features / Changes + +- Encrypt notification tokens. + +### Fixes + +- Replace connectivity state "Connected" with "Preparing". + +### Miscellaneous Tasks + +- Beta clippy suggestions ([#6271](https://github.com/chatmail/core/pull/6271)). + +### Tests + +- Fix `cargo check` for `receive_emails` benchmark. + +### CI + +- Also run cargo check without all-features. + +## [1.151.3] - 2024-12-02 + +### API-Changes + +- Remove experimental `request_internet_access` option from webxdc's `manifest.toml`. +- Add getWebxdcHref to json api ([#6281](https://github.com/chatmail/core/pull/6281)). + +### CI + +- Update Rust to 1.83.0. + +### Documentation + +- Update dc_msg_get_info_type() and dc_get_securejoin_qr() ([#6269](https://github.com/chatmail/core/pull/6269)). +- Fix references to iroh-related headers in peer_channels docs. +- Improve CFFI docs, link to corresponding JSON-RPC docs. + +### Features / Changes + +- Allow the user to replace maps integration ([#5678](https://github.com/chatmail/core/pull/5678)). +- Mark saved messages chat as protected. + +### Fixes + +- Close iroh endpoint when I/O is stopped. +- Do not add protection messages to Saved Messages chat. +- Mark Saved Messages chat as protected if it exists. +- Sync chat action even if sync message arrives before first one from contact ([#6259](https://github.com/chatmail/core/pull/6259)). + +### Refactor + +- Remove some .unwrap() calls. +- Create_status_update_record: Remove double check of info_msg_id. +- Use Option::or_else() to dedup emitting IncomingWebxdcNotify. + +## [1.151.2] - 2024-11-26 + +### API-Changes + +- Deprecate webxdc `descr` parameter ([#6255](https://github.com/chatmail/core/pull/6255)). + +### Features / Changes + +- AEAP: Check that the old peerstate verified key fingerprint hasn't changed when removing it. +- Add `AccountsChanged` and `AccountsItemChanged` events ([#6118](https://github.com/chatmail/core/pull/6118)). +- Do not use format=flowed in outgoing messages ([#6256](https://github.com/chatmail/core/pull/6256)). +- Add webxdc limits api. +- Add href to IncomingWebxdcNotify event ([#6266](https://github.com/chatmail/core/pull/6266)). + +### Fixes + +- Revert treating some transient SMTP errors as permanent. + +### Refactor + +- Create_status_update_record: Get rid of `notify` var. + +### Tests + +- Check that IncomingMsg isn't emitted for reactions. + +## [1.151.1] - 2024-11-24 + +### Build system + +- nix: Fix deltachat-rpc-server-source installable. + +### CI + +- Test building nix targets to avoid regressions. + +## [1.151.0] - 2024-11-23 + +### Features / Changes + +- Trim whitespace from scanned QR codes. +- Use privacy-preserving webxdc addresses ([#6237](https://github.com/chatmail/core/pull/6237)). +- Webxdc notify ([#6230](https://github.com/chatmail/core/pull/6230)). +- `update.href` api ([#6248](https://github.com/chatmail/core/pull/6248)). + +### Fixes + +- Never notify SELF ([#6251](https://github.com/chatmail/core/pull/6251)). + +### Build system + +- Use underscores in deltachat-rpc-server source package filename. +- Remove imap_tools from dependencies ([#6238](https://github.com/chatmail/core/pull/6238)). +- cargo: Update Rustls from 0.23.14 to 0.23.18. +- deps: Bump curve25519-dalek from 3.2.0 to 4.1.3 in /fuzz. + +### Documentation + +- Move style guide into a separate document. +- Clarify DC_EVENT_INCOMING_WEBXDC_NOTIFY documentation ([#6249](https://github.com/chatmail/core/pull/6249)). + +### Tests + +- After AEAP, 1:1 chat isn't available for sending, but unprotected groups are ([#6222](https://github.com/chatmail/core/pull/6222)). + +## [1.150.0] - 2024-11-21 + +### API-Changes + +- Correct `DC_CERTCK_ACCEPT_*` values and docs ([#6176](https://github.com/chatmail/core/pull/6176)). + +### Features / Changes + +- Use Rustls for connections with strict TLS ([#6186](https://github.com/chatmail/core/pull/6186)). +- Experimental header protection for Autocrypt. +- Tune down io-not-started info in connectivity-html. +- Clear config cache in start_io() ([#6228](https://github.com/chatmail/core/pull/6228)). +- Line-before-quote may be up to 120 character long instead of 80. +- Use i.delta.chat in qr codes ([#6223](https://github.com/chatmail/core/pull/6223)). + +### Fixes + +- Prevent accidental wrong-password-notifications ([#6122](https://github.com/chatmail/core/pull/6122)). +- Remove footers from "Show Full Message...". +- `send_msg_to_smtp`: Return Ok if `smtp` row is deleted in parallel. +- Only add "member added/removed" messages if they actually do that ([#5992](https://github.com/chatmail/core/pull/5992)). +- Do not fail to load chatlist summary if the message got removed. +- deltachat-jsonrpc: Do not fail `get_chatlist_items_by_entries` if the message got deleted. +- deltachat-jsonrpc: Do not fail `get_draft` if draft is deleted. +- `markseen_msgs`: Limit not yet downloaded messages state to `InNoticed` ([#2970](https://github.com/chatmail/core/pull/2970)). +- Update state of message when fully downloading it. +- Dont overwrite equal drafts ([#6212](https://github.com/chatmail/core/pull/6212)). + +### Build system + +- Silence RUSTSEC-2024-0384. +- cargo: Update rPGP from 0.13.2 to 0.14.0. +- cargo: Update futures-concurrency from 7.6.1 to 7.6.2. +- Update flake.nix ([#6200](https://github.com/chatmail/core/pull/6200)) + +### CI + +- Ensure flake is formatted. + +### Documentation + +- Scanned proxies are added and normalized. + +### Refactor + +- Fix nightly clippy warnings. +- Remove slicing from `is_file_in_use`. +- Remove unnecessary `allow(clippy::indexing_slicing)`. +- Don't use slicing in `remove_nonstandard_footer`. +- Do not use slicing in `qr` module. +- Eliminate indexing in `compute_mailinglist_name`. +- Remove unused `allow(clippy::indexing_slicing)`. +- Remove indexing/slicing from `remove_message_footer`. +- Remove indexing/slicing from `squash_attachment_parts`. +- Remove unused allow(clippy::indexing_slicing) for heuristically_parse_ndn. +- Remove indexing/slicing from `parse_message_ids`. +- Remove slicing from `remove_bottom_quote`. +- Get rid of slicing in `remove_top_quote`. +- Remove unused allow(clippy::indexing_slicing) from 'truncate'. +- Forbid clippy::indexing_slicing. +- Forbid clippy::string_slice. +- Delete chat in a transaction. +- Fix typo in `context.rs`. + +### Tests + +- Remove all calls to print() from deltachat-rpc-client tests. +- Reply to protected group from MUA. +- Mark not downloaded message as seen ([#2970](https://github.com/chatmail/core/pull/2970)). +- Mark `receive_imf()` as only for tests and "internals" feature ([#6235](https://github.com/chatmail/core/pull/6235)). + +## [1.149.0] - 2024-11-05 + +### Build system + +- Update tokio to 1.41 and Android NDK to r27. +- `nix flake update android`. + +### Fixes + +- cargo: Update iroh to 0.28.1. + This fixes the problem with iroh not sending the `Host:` header and not being able to connect to relays behind nginx reverse proxy. + +## [1.148.7] - 2024-11-03 + +### API-Changes + +- Add API to reset contact encryption. + +### Features / Changes + +- Emit chatlist events only if message still exists. + +### Fixes + +- send_msg_to_smtp: Do not fail if the message does not exist anymore. +- Do not percent-encode dot when passing to autoconfig server. +- Save contact name from SecureJoin QR to `authname`, not to `name` ([#6115](https://github.com/chatmail/core/pull/6115)). +- Always exit fake IDLE after at most 60 seconds. +- Concat NDNs ([#6129](https://github.com/chatmail/core/pull/6129)). + +### Refactor + +- Remove `has_decrypted_pgp_armor()`. + +### Miscellaneous Tasks + +- Update dependencies. + +## [1.148.6] - 2024-10-31 + +### API-Changes + +- Add Message::new_text() ([#6123](https://github.com/chatmail/core/pull/6123)). +- Add `MessageSearchResult.chat_id` ([#6120](https://github.com/chatmail/core/pull/6120)). + +### Features / Changes + +- Enable Webxdc realtime by default ([#6125](https://github.com/chatmail/core/pull/6125)). + +### Fixes + +- Save full text to mime_headers for long outgoing messages ([#6091](https://github.com/chatmail/core/pull/6091)). +- Show root SMTP connection failure in connectivity view ([#6121](https://github.com/chatmail/core/pull/6121)). +- Skip IDLE if we got unsolicited FETCH ([#6130](https://github.com/chatmail/core/pull/6130)). + +### Miscellaneous Tasks + +- Silence another rust-analyzer false-positive ([#6124](https://github.com/chatmail/core/pull/6124)). +- cargo: Upgrade iroh to 0.26.0. + +### Refactor + +- Directly use connectives ([#6128](https://github.com/chatmail/core/pull/6128)). +- Use Message::new_text() more ([#6127](https://github.com/chatmail/core/pull/6127)). + +## [1.148.5] - 2024-10-27 + +### Fixes + +- Set Config::NotifyAboutWrongPw before saving configuration ([#5896](https://github.com/chatmail/core/pull/5896)). +- Do not take write lock for maybe_network_lost() and set_push_device_token(). +- Do not lock the account manager for the whole duration of background_fetch. + +### Features / Changes + +- Auto-restore 1:1 chat protection after receiving old unverified message. + +### CI + +- Take `CHATMAIL_DOMAIN` from variables instead of secrets. + +### Other + +- Revert "build: nix flake update fenix" to fix `nix build .#deltachat-rpc-server-armeabi-v7a-android`. + +### Refactor + +- Receive_imf::add_parts: Remove excessive `from_id == ContactId::SELF` checks. +- Factor out `add_gossip_peer_from_header()`. + +## [1.148.4] - 2024-10-24 + +### Features / Changes + +- Jsonrpc: add `private_tag` to `Account::Configured` Object ([#6107](https://github.com/chatmail/core/pull/6107)). + +### Fixes + +- Normalize proxy URLs before saving into proxy_url. +- Do not wait for connections in maybe_add_gossip_peers(). + +## [1.148.3] - 2024-10-24 + +### Fixes + +- Fix reception of realtime advertisements. + +### Features / Changes + +- Allow sending realtime messages up to 128 KB in size. + +### API-Changes + +- deltachat-rpc-client: Add EventType.WEBXDC_REALTIME_ADVERTISEMENT_RECEIVED. + +### Documentation + +- Fix DC_QR_PROXY docs ([#6099](https://github.com/chatmail/core/pull/6099)). + +### Refactor + +- Generate topic inside create_iroh_header(). + +### Tests + +- Test that realtime advertisements work after chatting. + +## [1.148.2] - 2024-10-23 + +### Fixes + +- Never initialize Iroh if realtime is disabled. + +### Features / Changes + +- Add more logging for iroh initialization and peer addition. + +### Build system + +- `nix flake update nixpkgs`. +- `nix flake update fenix`. + +## [1.148.1] - 2024-10-23 + +### Build system + +- Revert "build: nix flake update" + +This reverts commit 6f22ce2722b51773d7fbb0d89e4764f963cafd91.. + +## [1.148.0] - 2024-10-22 + +### API-Changes + +- Create QR codes from any data ([#6090](https://github.com/chatmail/core/pull/6090)). +- Add delta chat logo to QR codes ([#6093](https://github.com/chatmail/core/pull/6093)). +- Add realtime advertisement received event ([#6043](https://github.com/chatmail/core/pull/6043)). +- Notify adding reactions ([#6072](https://github.com/chatmail/core/pull/6072)) +- Internal profile names ([#6088](https://github.com/chatmail/core/pull/6088)). + +### Features / Changes + +- IMAP COMPRESS support. +- Sort received outgoing message down if it's fresher than all non fresh messages. +- Prioritize cached results if DNS resolver returns many results. +- Add in-memory cache for DNS. +- deltachat-repl: Built-in QR code printer. +- Log the logic for (not) doing AEAP. +- Log when late Autocrypt header is ignored. +- Add more context to `send_msg` errors. + +### Fixes + +- Replace old draft with a new one atomically. +- ChatId::maybe_delete_draft: Don't delete message if it's not a draft anymore ([#6053](https://github.com/chatmail/core/pull/6053)). +- Call update_connection_history for proxified connections. +- sql: Set PRAGMA query_only to avoid writing on read-only connections. +- sql: Run `PRAGMA incremental_vacuum` on a write connection. +- Increase MAX_SECONDS_TO_LEND_FROM_FUTURE to 30. + +### Build system + +- Nix flake update. +- Resolve warning about default-features, and make it possible to disable vendoring ([#6079](https://github.com/chatmail/core/pull/6079)). +- Silence a rust-analyzer false-positive ([#6077](https://github.com/chatmail/core/pull/6077)). + +### CI + +- Update Rust to 1.82.0. + +### Documentation + +- Set_protection_for_timestamp_sort does not send messages. +- Document MimeFactory.req_mdn. +- Fix `too_long_first_doc_paragraph` clippy lint. + +### Refactor + +- Update_msg_state: Don't avoid downgrading OutMdnRcvd to OutDelivered. +- Fix elided_named_lifetimes warning. +- set_protection_for_timestamp_sort: Do not log bubbled up errors. +- Fix clippy::needless_lifetimes warnings. +- Use `HeaderDef` constant for Chat-Disposition-Notification-To. +- Resultify get_self_fingerprint(). +- sql: Move write mutex into connection pool. + +### Tests + +- test_qr_setup_contact_svg: Stop testing for no display name. +- Always gossip if gossip_period is set to 0. +- test_aeap_flow_verified: Wait for "member added" before sending messages ([#6057](https://github.com/chatmail/core/pull/6057)). +- Make test_verified_group_member_added_recovery more reliable. +- test_aeap_flow_verified: Do not start ac1new. +- Fix `test_securejoin_after_contact_resetup` flakiness. +- Message from old setup preserves contact verification, but breaks 1:1 protection. + +## [1.147.1] - 2024-10-13 + +### Build system + +- Build Python 3.13 wheels. +- deltachat-rpc-client: Add classifiers for all supported Python versions. + +### CI + +- Update to Python 3.13. + +### Documentation + +- CONTRIBUTING.md: Add a note on deleting/changing db columns. + +### Fixes + +- Reset quota on configured address change ([#5908](https://github.com/chatmail/core/pull/5908)). +- Do not emit progress 1000 when configuration is canceled. +- Assume file extensions are 32 chars max and don't contain whitespace ([#5338](https://github.com/chatmail/core/pull/5338)). +- Re-add tokens.foreign_id column ([#6038](https://github.com/chatmail/core/pull/6038)). + +### Miscellaneous Tasks + +- cargo: Bump futures-* from 0.3.30 to 0.3.31. +- cargo: Upgrade async_zip to 0.0.17 ([#6035](https://github.com/chatmail/core/pull/6035)). + +### Refactor + +- MsgId::update_download_state: Don't fail if the message doesn't exist anymore. + +## [1.147.0] - 2024-10-05 + +### API-Changes + +- [**breaking**] Remove deprecated get_next_media() APIs. + +### Features / Changes + +- Reuse existing connections in background_fetch() if I/O is started. +- MsgId::get_info(): Report original filename as well. +- More context for the "Cannot establish guaranteed..." info message ([#6022](https://github.com/chatmail/core/pull/6022)). +- deltachat-repl: Add `fetch` command to test `background_fetch()`. +- deltachat-repl: Print send-backup QR code to the terminal. + +### Fixes + +- Do not attempt to reference info messages. +- query_row_optional: Do not treat rows with NULL as missing rows. +- Skip unconfigured folders in `background_fetch()`. +- Break out of accept() loop if there is an error transferring backup. +- Make it possible to cancel ongoing backup transfer. +- Make backup reception cancellable by stopping ongoing process. +- Smooth progress bar for backup transfer. +- Emit progress 0 if get_backup() fails. + +### Documentation + +- CONTRIBUTING.md: Add more SQL advices. + +## [1.146.0] - 2024-10-03 + +### Fixes + +- download_msg: Do not fail if the message does not exist anymore. +- Better log message for failed QR scan. + +### Features / Changes + +- Assign message to ad-hoc group with matching name and members ([#5385](https://github.com/chatmail/core/pull/5385)). +- Use Rustls instead of native TLS for HTTPS requests. + +### Miscellaneous Tasks + +- cargo: Bump anyhow from 1.0.86 to 1.0.89. +- cargo: Bump tokio-stream from 0.1.15 to 0.1.16. +- cargo: Bump thiserror from 1.0.63 to 1.0.64. +- cargo: Bump bytes from 1.7.1 to 1.7.2. +- cargo: Bump libc from 0.2.158 to 0.2.159. +- cargo: Bump tempfile from 3.10.1 to 3.13.0. +- cargo: Bump pretty_assertions from 1.4.0 to 1.4.1. +- cargo: Bump hyper-util from 0.1.7 to 0.1.9. +- cargo: Bump rustls-pki-types from 1.8.0 to 1.9.0. +- cargo: Bump quick-xml from 0.36.1 to 0.36.2. +- cargo: Bump serde from 1.0.209 to 1.0.210. +- cargo: Bump syn from 2.0.77 to 2.0.79. + +### Refactor + +- Move group name calculation out of create_adhoc_group(). +- Merge build_tls() function into wrap_tls(). + +## [1.145.0] - 2024-09-26 + +### Fixes + +- Avoid changing `delete_server_after` default for existing configurations. + +### Miscellaneous Tasks + +- Sort dependency list. + +### Refactor + +- Do not wrap shadowsocks::ProxyClientStream. + +## [1.144.0] - 2024-09-21 + +### API-Changes + +- [**breaking**] Make QR code type for proxy not specific to SOCKS5 ([#5980](https://github.com/chatmail/core/pull/5980)). + + `DC_QR_SOCKS5_PROXY` is replaced with `DC_QR_PROXY`. + +### Features / Changes + +- Make resending OutPending messages possible ([#5817](https://github.com/chatmail/core/pull/5817)). +- Don't SMTP-send messages to self-chat if BccSelf is disabled. +- HTTP(S) tunneling. +- Don't put displayname into From/To/Sender if it equals to address ([#5983](https://github.com/chatmail/core/pull/5983)). +- Use IMAP APPEND command to upload sync messages ([#5845](https://github.com/chatmail/core/pull/5845)). +- Generate 144-bit group IDs. +- smtp: More verbose SMTP connection establishment errors. +- Log unexpected message state when resending fails. + +### Fixes + +- Save QR code token regardless of whether the group exists ([#5954](https://github.com/chatmail/core/pull/5954)). +- Shorten message text in locally sent messages too ([#2281](https://github.com/chatmail/core/pull/2281)). + +### Documentation + +- CONTRIBUTING.md: Document how to format SQL statements. + +### Miscellaneous Tasks + +- Update provider database. +- cargo: Update iroh to 0.25. +- cargo: Update lazy_static to 1.5.0. +- deps: Bump async-imap from 0.10.0 to 0.10.1. + +### Refactor + +- Do not store deprecated `addr` and `is_default` into `keypairs`. +- Remove `addr` from KeyPair. +- Use `KeyPair::new()` in `create_keypair()`. + +## [1.143.0] - 2024-09-12 + +### Features / Changes + +- Automatic reconfiguration, e.g. switching to implicit TLS if STARTTLS port stops working. +- Always use preloaded DNS results. +- Add "Auto-Submitted: auto-replied" header to appropriate SecureJoin messages. +- Parallelize IMAP and SMTP connection attempts ([#5915](https://github.com/chatmail/core/pull/5915)). +- securejoin: Ignore invalid *-request-with-auth messages silently. +- ChatId::create_for_contact_with_blocked: Don't emit events on no op. +- Delete messages from a chatmail server immediately by default ([#5805](https://github.com/chatmail/core/pull/5805)) ([#5840](https://github.com/chatmail/core/pull/5840)). +- Shadowsocks support. +- Recognize t.me SOCKS5 proxy QR codes ([#5895](https://github.com/chatmail/core/pull/5895)) +- Remove old iroh 0.4 and support for old `DCBACKUP` QR codes. + +### Fixes + +- http: Set I/O timeout to 1 minute rather than whole request timeout. +- Add Auto-Submitted header in a single place. +- Do not allow quotes with "... wrote:" headers in chat messages. +- Don't sync QR code token before populating the group ([#5935](https://github.com/chatmail/core/pull/5935)). + +### Documentation + +- Document that `bcc_self` is enabled by default. + +### CI + +- Update Rust to 1.81.0. + +### Miscellaneous Tasks + +- Update provider database. +- cargo: Update iroh to 0.23.0. +- cargo: Reduce number of duplicate dependencies. +- cargo: Replace unmaintained ansi_term with nu-ansi-term. +- Replace `reqwest` with direct usage of `hyper`. + +### Refactor + +- login_param: Use Config:: constants to avoid typos in key names. +- Make Context::config_exists() crate-public. +- Get_config_bool_opt(): Return None if only default value exists. + +### Tests + +- Test that alternative port 443 works. +- Alice is (non-)bot on Bob's side after QR contact setup. + +## [1.142.12] - 2024-09-02 + +### Fixes + +- Display Config::MdnsEnabled as true by default ([#5948](https://github.com/chatmail/core/pull/5948)). + +## [1.142.11] - 2024-08-30 + +### Fixes + +- Set backward verification when observing vc-contact-confirm or `vg-member-added` ([#5930](https://github.com/chatmail/core/pull/5930)). + +## [1.142.10] - 2024-08-26 + +### Fixes + +- Only include one From: header in securejoin messages ([#5917](https://github.com/chatmail/core/pull/5917)). + +## [1.142.9] - 2024-08-24 + +### Fixes + +- Fix reading of multiline SMTP greetings ([#5911](https://github.com/chatmail/core/pull/5911)). + +### Features / Changes + +- Update preloaded DNS cache. + +## [1.142.8] - 2024-08-21 + +### Fixes + +- Do not panic on unknown CertificateChecks values. + +## [1.142.7] - 2024-08-17 + +### Fixes + +- Do not save "Automatic" into configured_imap_certificate_checks. **This fixes regression introduced in core 1.142.4. Versions 1.142.4..1.142.6 should not be used in releases.** +- Create a group unblocked for bot even if 1:1 chat is blocked ([#5514](https://github.com/chatmail/core/pull/5514)). +- Update rpgp from 0.13.1 to 0.13.2 to fix "unable to decrypt" errors when sending messages to old Delta Chat clients and using Ed25519 keys to encrypt. +- Do not request ALPN on standard ports and when using STARTTLS. + +### Features / Changes + +- jsonrpc: Add ContactObject::e2ee_avail. + +### Tests + +- Protected group for bot is auto-accepted. + +## [1.142.6] - 2024-08-15 + +### Fixes + +- Default to strict TLS checks if not configured. + +### Miscellaneous Tasks + +- deltachat-rpc-client: Fix ruff 0.6.0 warnings. + +## [1.142.5] - 2024-08-14 + +### Fixes + +- Still try to create "INBOX.DeltaChat" if couldn't create "DeltaChat" ([#5870](https://github.com/chatmail/core/pull/5870)). +- `store_seen_flags_on_imap`: Skip to next messages if couldn't select folder ([#5870](https://github.com/chatmail/core/pull/5870)). +- Increase timeout for QR generation to 60s ([#5882](https://github.com/chatmail/core/pull/5882)). + +### Documentation + +- Document new `mdns_enabled` behavior (bots do not send MDNs by default). + +### CI + +- Configure Dependabot to update GitHub Actions. + +### Miscellaneous Tasks + +- cargo: Bump regex from 1.10.5 to 1.10.6. +- cargo: Bump serde from 1.0.204 to 1.0.205. +- deps: Bump horochx/deploy-via-scp from 1.0.1 to 1.1.0. +- deps: Bump dependabot/fetch-metadata from 1.1.1 to 2.2.0. +- deps: Bump actions/setup-node from 2 to 4. +- Update provider database. + +## [1.142.4] - 2024-08-09 + +### Build system + +- Downgrade Tokio to 1.38 to fix Android compilation. +- Use `--locked` with `cargo install`. + +### Features / Changes + +- Add Config::FixIsChatmail. +- Always move outgoing auto-generated messages to the mvbox. +- Disable requesting MDNs for bots by default. +- Allow using OAuth 2 with SOCKS5. +- Allow autoconfig when SOCKS5 is enabled. +- Update provider database. +- cargo: Update iroh from 0.21 to 0.22 ([#5860](https://github.com/chatmail/core/pull/5860)). + +### CI + +- Update Rust to 1.80.1. +- Update EmbarkStudios/cargo-deny-action. + +### Documentation + +- Point to active Header Protection draft + +### Refactor + +- Derive `Default` for `CertificateChecks`. +- Merge imap_certificate_checks and smtp_certificate_checks. +- Remove param_addr_urlencoded argument from get_autoconfig(). +- Pass address to moz_autoconfigure() instead of LoginParam. + +## [1.142.3] - 2024-08-04 + +### Build system + +- cargo: Update rusqlite and libsqlite3-sys. +- Fix cargo warnings about default-features +- Do not disable "vendored" feature in the workspace. +- cargo: Bump quick-xml from 0.35.0 to 0.36.1. +- cargo: Bump uuid from 1.9.1 to 1.10.0. +- cargo: Bump tokio from 1.38.0 to 1.39.2. +- cargo: Bump env_logger from 0.11.3 to 0.11.5. +- Remove sha2 dependency. +- Remove `backtrace` dependency. +- Remove direct "quinn" dependency. + +## [1.142.2] - 2024-08-02 + +### Features / Changes + +- Try only the full email address if username is unspecified. +- Sort DNS results by successful connection timestamp ([#5818](https://github.com/chatmail/core/pull/5818)). + +### Fixes + +- Await the tasks after aborting them. +- Do not reset is_chatmail config on failed reconfiguration. +- Fix compilation on iOS. +- Reset configured_provider on reconfiguration. + +### Refactor + +- Don't update message state to `OutMdnRcvd` anymore. + +### Build system + +- Use workspace dependencies to make cargo-deny 0.15.1 happy. +- cargo: Update bytemuck from 0.14.3 to 0.16.3. +- cargo: Bump toml from 0.8.14 to 0.8.15. +- cargo: Bump serde_json from 1.0.120 to 1.0.122. +- cargo: Bump human-panic from 2.0.0 to 2.0.1. +- cargo: Bump thiserror from 1.0.61 to 1.0.63. +- cargo: Bump syn from 2.0.68 to 2.0.72. +- cargo: Bump quoted_printable from 0.5.0 to 0.5.1. +- cargo: Bump serde from 1.0.203 to 1.0.204. + +## [1.142.1] - 2024-07-30 + +### Features / Changes + +- Do not reveal sender's language in read receipts ([#5802](https://github.com/chatmail/core/pull/5802)). +- Try next DNS resolution result if TLS setup fails. +- Report first error instead of the last on connection failure. + +### Fixes + +- smtp: Use DNS cache for implicit TLS connections. +- Imex::import_backup: Unpack all blobs before importing a db ([#4307](https://github.com/chatmail/core/pull/4307)). +- Import_backup_stream: Fix progress stucking at 0. +- Sql::import: Detach backup db if any step of the import fails. +- Imex::import_backup: Ignore errors from delete_and_reset_all_device_msgs(). +- Explicitly close the database on account removal. + +### Miscellaneous Tasks + +- cargo: Update time from 0.3.34 to 0.3.36. +- cargo: Update iroh from 0.20.0 to 0.21.0. + +### Refactor + +- Add net/dns submodule. +- Pass single ALPN around instead of ALPN list. +- Replace {IMAP,SMTP,HTTP}_TIMEOUT with a single constant. +- smtp: Unify SMTP connection setup between TLS and STARTTLS. +- imap: Unify IMAP connection setup in Client::connect(). +- Move DNS resolution into IMAP and SMTP connect code. + +### CI + +- Update Rust to 1.80.0. + +## [1.142.0] - 2024-07-23 + +### API-Changes + +- deltachat-jsonrpc: Add `pinned` property to `FullChat` and `BasicChat`. +- deltachat-jsonrpc: Allow to set message quote text without referencing quoted message ([#5695](https://github.com/chatmail/core/pull/5695)). + +### Features / Changes + +- cargo: Update iroh from 0.17 to 0.20. +- iroh: Pass direct addresses from Endpoint to Gossip. +- New BACKUP2 transfer protocol. +- Use `[...]` instead of `...` for protected subject. +- Add email address and fingerprint to exported key file names ([#5694](https://github.com/chatmail/core/pull/5694)). +- Request `imap` ALPN for IMAP TLS connections and `smtp` ALPN for SMTP TLS connections. +- Limit the size of aggregated WebXDC update to 100 KiB ([#4825](https://github.com/chatmail/core/pull/4825)). +- Don't create ad-hoc group on a member removal message ([#5618](https://github.com/chatmail/core/pull/5618)). +- Don't unarchive a group on a member removal except SELF ([#5618](https://github.com/chatmail/core/pull/5618)). +- Use custom DNS resolver for HTTP(S). +- Promote fallback DNS results to cached on successful use. +- Set summary thumbnail path for WebXDCs to "webxdc-icon://last-msg-id" ([#5782](https://github.com/chatmail/core/pull/5782)). +- Do not show the address in invite QR code SVG. +- Report better error from DcKey::from_asc() ([#5539](https://github.com/chatmail/core/pull/5539)). +- Contact::create_ex: Don't send sync message if nothing changed ([#5705](https://github.com/chatmail/core/pull/5705)). + +### Fixes + +- `Message::set_quote`: Don't forget to remove `Param::ProtectQuote`. +- Randomize avatar blob filenames to work around caching. +- Correct copy-pasted DCACCOUNT parsing errors message. +- Call `send_sync_msg()` only from the SMTP loop ([#5780](https://github.com/chatmail/core/pull/5780)). +- Emit MsgsChanged if the number of unnoticed archived chats could decrease ([#5768](https://github.com/chatmail/core/pull/5768)). +- Reject message with forged From even if no valid signatures are found. + +### Refactor + +- Move key transfer into its own submodule. +- Move TempPathGuard into `tools` and use instead of `DeleteOnDrop`. +- Return error from export_backup() without logging. +- Reduce boilerplate for migration version increment. + +### Tests + +- Add test for `get_http_response` JSON-RPC call. + +### Build system + +- node: Pin node-gyp to version 10.1. + +### Miscellaneous Tasks + +- cargo: Update hashlink to remove allocator-api2 dependency. +- cargo: Update openssl to v0.10.66. +- deps: Bump openssl from 0.10.60 to 0.10.66 in /fuzz. +- cargo: Update `image` crate to 0.25.2. + +## [1.141.2] - 2024-07-09 + +### Features / Changes + +- Add `is_muted` config option. +- Parse vcards exported by protonmail ([#5723](https://github.com/chatmail/core/pull/5723)). +- Disable sending sync messages for bots ([#5705](https://github.com/chatmail/core/pull/5705)). + +### Fixes + +- Don't fail if going to send plaintext, but some peerstate is missing. +- Correctly sanitize input everywhere ([#5697](https://github.com/chatmail/core/pull/5697)). +- Do not try to register non-iOS tokens for heartbeats. +- imap: Reset new_mail if folder is ignored. +- Use and prefer Date from signed message part ([#5716](https://github.com/chatmail/core/pull/5716)). +- Distinguish between database errors and no gossip topic. +- MimeFactory::verified: Return true for self-chat. + +### Refactor + +- `MimeFactory::is_e2ee_guaranteed()`: always respect `Param::ForcePlaintext`. +- Protect from reusing migration versions ([#5719](https://github.com/chatmail/core/pull/5719)). +- Move `quota_needs_update` calculation to a separate function ([#5683](https://github.com/chatmail/core/pull/5683)). + +### Documentation + +- Document vCards in the specification ([#5724](https://github.com/chatmail/core/pull/5724)) + +### Miscellaneous Tasks + +- cargo: Bump toml from 0.8.13 to 0.8.14. +- cargo: Bump serde_json from 1.0.117 to 1.0.120. +- cargo: Bump syn from 2.0.66 to 2.0.68. +- cargo: Bump async-broadcast from 0.7.0 to 0.7.1. +- cargo: Bump url from 2.5.0 to 2.5.2. +- cargo: Bump log from 0.4.21 to 0.4.22. +- cargo: Bump regex from 1.10.4 to 1.10.5. +- cargo: Bump proptest from 1.4.0 to 1.5.0. +- cargo: Bump uuid from 1.8.0 to 1.9.1. +- cargo: Bump backtrace from 0.3.72 to 0.3.73. +- cargo: Bump quick-xml from 0.31.0 to 0.35.0. +- cargo: Update yerpc to 0.6.2. +- cargo: Update rPGP from 0.11 to 0.13. + +## [1.141.1] - 2024-06-27 + +### Fixes + +- Update quota if it's stale, not fresh ([#5683](https://github.com/chatmail/core/pull/5683)). +- sql: Assign migration adding msgs.deleted a new number. + +### Refactor + +- mimefactory: Factor out header confidentiality policy ([#5715](https://github.com/chatmail/core/pull/5715)). +- Improve logging during SMTP/IMAP configuration. + +## [1.141.0] - 2024-06-24 + +### API-Changes + +- deltachat-jsonrpc: Add `get_chat_securejoin_qr_code()`. +- api!(deltachat-rpc-client): make {Account,Chat}.get_qr_code() return no SVG + This is a breaking change, old method is renamed into `get_qr_code_svg()`. + +### Features / Changes + +- Prefer references to fully downloaded messages for chat assignment ([#5645](https://github.com/chatmail/core/pull/5645)). +- Protect From name for verified chats and To names for encrypted chats ([#5166](https://github.com/chatmail/core/pull/5166)). +- Display vCard contact name in the message summary. +- Case-insensitive search for non-ASCII messages ([#5052](https://github.com/chatmail/core/pull/5052)). +- Remove subject prefix from ad-hoc group names ([#5385](https://github.com/chatmail/core/pull/5385)). +- Replace "Unnamed group" with "👥📧" to avoid translation. +- Sync `Config::MvboxMove` across devices ([#5680](https://github.com/chatmail/core/pull/5680)). +- Don't reveal profile data to a not yet verified contact ([#5166](https://github.com/chatmail/core/pull/5166)). +- Don't reveal profile data in MDNs ([#5166](https://github.com/chatmail/core/pull/5166)). + +### Fixes + +- Fetch existing messages for bots as `InFresh` ([#4976](https://github.com/chatmail/core/pull/4976)). +- Keep tombstones for two days before deleting ([#3685](https://github.com/chatmail/core/pull/3685)). +- Housekeeping: Delete MDNs and webxdc status updates for tombstones. +- Delete user-deleted messages on the server even if they show up on IMAP later. +- Do not send sync messages if bcc_self is disabled. +- Don't generate Config sync messages for unconfigured accounts. +- Do not require the Message to render MDN. + +### CI + +- Update Rust to 1.79.0. + +### Documentation + +- Remove outdated documentation comment from `send_smtp_messages`. +- Remove misleading configuration comment. + +### Miscellaneous Tasks + +- Update curve25519-dalek 4.1.x and suppress 3.2.0 warning. +- Update provider database. + +### Refactor + +- Deduplicate dependency versions ([#5691](https://github.com/chatmail/core/pull/5691)). +- Store public key instead of secret key for peer channels. + +### Tests + +- Image drafted as Viewtype::File is sent as is. +- python: Set delete_server_after=1 ("delete immediately") for bots ([#4976](https://github.com/chatmail/core/pull/4976)). +- deltachat-rpc-client: Test that webxdc realtime data is not reordered on the sender. +- python: Wait for bot's DC_EVENT_IMAP_INBOX_IDLE before sending messages to it ([#5699](https://github.com/chatmail/core/pull/5699)). + +## [1.140.2] - 2024-06-07 + +### API-Changes + +- jsonrpc: Add set_draft_vcard(.., msg_id, contacts). + +### Fixes + +- Allow fetch_existing_msgs for bots ([#4976](https://github.com/chatmail/core/pull/4976)). +- Remove group member locally even if send_msg() fails ([#5508](https://github.com/chatmail/core/pull/5508)). +- Revert member addition if the corresponding message couldn't be sent ([#5508](https://github.com/chatmail/core/pull/5508)). +- @deltachat/stdio-rpc-server: Make local non-symlinked installation possible by using absolute paths for local dev version ([#5679](https://github.com/chatmail/core/pull/5679)). + +### Miscellaneous Tasks + +- cargo: Bump schemars from 0.8.19 to 0.8.21. +- cargo: Bump backtrace from 0.3.71 to 0.3.72. + +### Refactor + +- @deltachat/stdio-rpc-server: Use old school require instead of the experimental json import ([#5628](https://github.com/chatmail/core/pull/5628)). + +### Tests + +- Set fetch_existing_msgs for bots ([#4976](https://github.com/chatmail/core/pull/4976)). +- Don't leave protected group if some member's key is missing ([#5508](https://github.com/chatmail/core/pull/5508)). + +## [1.140.1] - 2024-06-05 + +### Fixes + +- Retry sending MDNs on temporary error. +- Set Config::IsChatmail in configure(). +- Do not miss new messages while expunging the folder. +- Log messages with `info!` instead of `println!`. + +### Documentation + +- imap: Document why CLOSE is faster than EXPUNGE. + +### Refactor + +- imap: Make select_folder() accept non-optional folder. +- Improve SMTP logs and errors. +- Remove unused `select_folder::Error` variants. + +### Tests + +- deltachat-rpc-client: re-enable `log_cli`. + +## [1.140.0] - 2024-06-04 + +### Features / Changes + +- Remove limit on number of email recipients for chatmail clients ([#5598](https://github.com/chatmail/core/pull/5598)). +- Add config option to enable iroh ([#5607](https://github.com/chatmail/core/pull/5607)). +- Map `*.wav` to Viewtype::Audio ([#5633](https://github.com/chatmail/core/pull/5633)). +- Add a db index for reactions by msg_id ([#5507](https://github.com/chatmail/core/pull/5507)). + +### Fixes + +- Set Param::Bot for messages on the sender side as well ([#5615](https://github.com/chatmail/core/pull/5615)). +- AEAP: Remove old peerstate verified_key instead of removing the whole peerstate ([#5535](https://github.com/chatmail/core/pull/5535)). +- Allow creation of groups by outgoing messages without recipients. +- Prefer `Chat-Group-ID` over references for new groups. +- Do not fail to send images with wrong extensions. + +### Build system + +- Unpin OpenSSL version and update to OpenSSL 3.3.0. + +### CI + +- Remove cargo-nextest bug workaround. + +### Documentation + +- Add vCard as supported standard. +- Create_group() does not find chats, only creates them. +- Fix a typo in test_partial_group_consistency(). + +### Refactor + +- Factor create_adhoc_group() call out of create_group(). +- Put duplicate code into `lookup_chat_or_create_adhoc_group`. + +### Tests + +- Fix logging of TestContext created using TestContext::new_alice(). +- Refactor `test_alias_*` into 8 separate tests. + +## [1.139.6] - 2024-05-25 + +### Build system + +- Update `iroh` to the git version. +- nix: Add iroh-base output hash. +- Upgrade iroh to 0.17.0. + +### Fixes + +- @deltachat/stdio-rpc-server: Do not set RUST_LOG to "info" by default. +- Acquire write lock on iroh_channels before checking for subscribe_loop. + +### Miscellaneous Tasks + +- Fix python lint. +- cargo-deny: Remove unused entry from deny.toml. + +### Refactor + +- Log IMAP connection type on connection failure. + +### Tests + +- Viewtype::File attachments are sent unchanged and preserve extensions. +- deltachat-rpc-client: Add realtime channel tests. +- deltachat-rpc-client: Regression test for double gossip subscription. + +## [1.139.5] - 2024-05-23 + +### API-Changes + +- deltachat-ffi: Make WebXdcRealtimeData data usable in CFFI. +- Add event channel overflow event. +- deltachat-rpc-client: Add EventType.WEBXDC_REALTIME_DATA constant. +- deltachat-rpc-client: Add Message.send_webxdc_realtime_advertisement(). +- deltachat-rpc-client: Add Message.send_webxdc_realtime_data(). + +### Features / Changes + +- deltachat-repl: Add start-realtime and send-realtime commands. + +### Fixes + +- peer_channels: Connect to peers that advertise to you. +- Don't recode images in `Viewtype::File` messages ([#5617](https://github.com/chatmail/core/pull/5617)). + +### Tests + +- peer_channels: Add test_parallel_connect(). +- "SecureJoin wait" state and info messages. + +## [1.139.4] - 2024-05-21 + +### Features / Changes + +- Scale up contact origins to OutgoingTo when sending a message. +- Add import_vcard() ([#5202](https://github.com/chatmail/core/pull/5202)). + +### Fixes + +- Do not log warning if iroh relay metadata is NIL. +- contact-tools: Parse_vcard: Support `\r\n` newlines. +- Make_vcard: Add authname and key for ContactId::SELF. + +### Other + +- nix: Add nextest ([#5610](https://github.com/chatmail/core/pull/5610)). + +## [1.139.3] - 2024-05-20 + +### API-Changes + +- [**breaking**] @deltachat/stdio-rpc-server: change api: don't search in path unless `options.takeVersionFromPATH` is set to `true` +- @deltachat/stdio-rpc-server: remove `DELTA_CHAT_SKIP_PATH` environment variable +- @deltachat/stdio-rpc-server: remove version check / search for dc rpc server in $PATH +- @deltachat/stdio-rpc-server: remove `options.skipSearchInPath` +- @deltachat/stdio-rpc-server: add `options.takeVersionFromPATH` +- deltachat-rpc-client: Add Account.wait_for_incoming_msg(). + +### Features / Changes + +- Replace env_logger with tracing_subscriber. + +### Fixes + +- Ignore event channel overflows. +- mimeparser: Take the last header of multiple ones with the same name. +- Db migration version 59, it contained an sql syntax error. +- Sql syntax error in db migration 27. +- Log/print exit error of deltachat-rpc-server ([#5601](https://github.com/chatmail/core/pull/5601)). +- @deltachat/stdio-rpc-server: set default options for `startDeltaChat`. +- Always convert absolute paths to relative in accounts.toml. + +### Refactor + +- receive_imf: Do not check for ContactId::UNDEFINED. +- receive_imf: Remove unnecessary check for is_mdn. +- receive_imf: Only call create_or_lookup_group() with allow_creation=true. +- Use let..else in create_or_lookup_group(). +- Stop trying to extract chat ID from Message-IDs. +- Do not try to lookup group in create_or_lookup_group(). + +## [1.139.2] - 2024-05-18 + +### Build system + +- Add repository URL to @deltachat/jsonrpc-client. + +## [1.139.1] - 2024-05-18 + +### CI + +- Set `--access public` when publishing to npm. + +## [1.139.0] - 2024-05-18 + +### Features / Changes + +- Ephemeral peer channels ([#5346](https://github.com/chatmail/core/pull/5346)). + +### Fixes + +- Save override sender displayname for outgoing messages. +- Do not mark the message as seen if it has `location.kml`. +- @deltachat/stdio-rpc-server: fix version check when deltachat-rpc-server is found in path ([#5579](https://github.com/chatmail/core/pull/5579)). +- @deltachat/stdio-rpc-server: fix local desktop development ([#5583](https://github.com/chatmail/core/pull/5583)). +- @deltachat/stdio-rpc-server: rename `shutdown` method to `close` and add `muteStdErr` option to mute the stderr output ([#5588](https://github.com/chatmail/core/pull/5588)) +- @deltachat/stdio-rpc-server: fix `convert_platform.py`: 32bit `i32` -> `ia32` ([#5589](https://github.com/chatmail/core/pull/5589)) +- @deltachat/stdio-rpc-server: fix example ([#5580](https://github.com/chatmail/core/pull/5580)) + +### API-Changes + +- deltachat-jsonrpc: Return vcard contact directly in MessageObject. +- deltachat-jsonrpc: Add api `migrate_account` and `get_blob_dir` ([#5584](https://github.com/chatmail/core/pull/5584)). +- deltachat-rpc-client: Add ViewType.VCARD constant. +- deltachat-rpc-client: Add Contact.make_vcard(). +- deltachat-rpc-client: Add Chat.send_contact(). + +### CI + +- Publish @deltachat/jsonrpc-client directly to npm. +- Check that constants are always up-to-date. + +### Build system + +- nix: Add git-cliff to flake. +- nix: Use rust-analyzer nightly + +### Miscellaneous Tasks + +- cargo: Downgrade libc from 0.2.154 to 0.2.153. + +### Tests + +- deltachat-rpc-client: Test sending vCard. + +## [1.138.5] - 2024-05-16 + +### API-Changes + +- jsonrpc: Add parse_vcard() ([#5202](https://github.com/chatmail/core/pull/5202)). +- Add Viewtype::Vcard ([#5202](https://github.com/chatmail/core/pull/5202)). +- Add make_vcard() ([#5203](https://github.com/chatmail/core/pull/5203)). + +### Build system + +- Add repository URL to deltachat-rpc-server packages. + +### Fixes + +- Parsing vCards with avatars exported by Android's "Contacts" app. + +### Miscellaneous Tasks + +- Rebuild node constants. + +### Refactor + +- contact-tools: VcardContact: rename display_name to authname. +- VcardContact: Change timestamp type to i64. + +## [1.138.4] - 2024-05-15 + +### CI + +- Run actions/setup-node before npm publish. + +## [1.138.3] - 2024-05-15 + +### CI + +- Give CI job permission to publish binaries to the release. + +## [1.138.2] - 2024-05-15 + +### API-Changes + +- deltachat-rpc-client: Add CONFIG_SYNCED constant. + +### CI + +- Add npm token to publish deltachat-rpc-server packages. + +### Features / Changes + +- Reset more settings when configuring a chatmail account. + +### Tests + +- Set configuration after configure() finishes. + +## [1.138.1] - 2024-05-14 + +### Features / Changes + +- Detect XCHATMAIL capability and expose it as `is_chatmail` config. + +### Fixes + +- Never treat message with Chat-Group-ID as a private reply. +- Always prefer Chat-Group-ID over In-Reply-To and References. +- Ignore parent message if message references itself. + +### CI + +- Set RUSTUP_WINDOWS_PATH_ADD_BIN to work around `nextest` issue . +- deltachat-rpc-server: Fix upload of npm packages to github releases ([#5564](https://github.com/chatmail/core/pull/5564)). + +### Refactor + +- Add MimeMessage.get_chat_group_id(). +- Make MimeMessage.get_header() return Option<&str>. +- sql: Make open flags immutable. +- Resultify token::lookup_or_new(). + +### Miscellaneous Tasks + +- cargo: Bump parking_lot from 0.12.1 to 0.12.2. +- cargo: Bump libc from 0.2.153 to 0.2.154. +- cargo: Bump hickory-resolver from 0.24.0 to 0.24.1. +- cargo: Bump serde_json from 1.0.115 to 1.0.116. +- cargo: Bump human-panic from 1.2.3 to 2.0.0. +- cargo: Bump brotli from 5.0.0 to 6.0.0. + +## [1.138.0] - 2024-05-13 + +### API-Changes + +- Add dc_msg_save_file() which saves file copy at the provided path ([#4309](https://github.com/chatmail/core/pull/4309)). +- Api!(jsonrpc): replace EphemeralTimer tag "variant" with "kind" + +### CI + +- Use rsync instead of 3rd party github action. +- Replace `black` with `ruff format`. +- Update Rust to 1.78.0. + +### Documentation + +- Fix references in Message.set_location() documentation. +- Remove Doxygen markup from Message.has_location(). +- Add `location` module documentation. + +### Features / Changes + +- Delete expired path locations in ephemeral loop. +- Delete orphaned POI locations during housekeeping. +- Parsing vCards for contacts sharing ([#5482](https://github.com/chatmail/core/pull/5482)). +- contact-tools: Support parsing profile images from "PHOTO:data:image/jpeg;base64,...". +- contact-tools: Add make_vcard(). +- Do not add location markers to messages with non-POI location. +- Make one-to-one chats read-only the first seconds of a SecureJoin ([#5512](https://github.com/chatmail/core/pull/5512)). + +### Fixes + +- Message::set_file_from_bytes(): Set Param::Filename. +- Do not fail to send encrypted quotes to unencrypted chats. +- Never prepend subject to message text when bot receives it. +- Interrupt location loop when new location is stored. +- Correct message viewtype before recoding image blob ([#5496](https://github.com/chatmail/core/pull/5496)). +- Delete POI location when disappearing message expires. +- Delete non-POI locations after `delete_device_after`, not immediately. +- Update special chats icons even if they are blocked ([#5509](https://github.com/chatmail/core/pull/5509)). +- Use ChatIdBlocked::lookup_by_contact() instead of ChatId's method when applicable. + +### Miscellaneous Tasks + +- cargo: Bump quote from 1.0.35 to 1.0.36. +- cargo: Bump base64 from 0.22.0 to 0.22.1. +- cargo: Bump serde from 1.0.197 to 1.0.200. +- cargo: Bump async-channel from 2.2.0 to 2.2.1. +- cargo: Bump thiserror from 1.0.58 to 1.0.59. +- cargo: Bump anyhow from 1.0.81 to 1.0.82. +- cargo: Bump chrono from 0.4.37 to 0.4.38. +- cargo: Bump imap-proto from 0.16.4 to 0.16.5. +- cargo: Bump syn from 2.0.57 to 2.0.60. +- cargo: Bump mailparse from 0.14.1 to 0.15.0. +- cargo: Bump schemars from 0.8.16 to 0.8.19. + +### Other + +- Build ts docs with ci + nix. +- Push docs to delta.chat instead of codespeak +- Implement jsonrpc-docs build in github action +- Rm unneeded rust install from ts docs ci +- Correct folder for js.jsonrpc docs +- Add npm install to upload-docs.yml +- Add : to upload-docs.yml +- Upload-docs npm run => npm run build +- Rm leading slash +- Rm npm install +- Merge pull request #5515 from deltachat/dependabot/cargo/quote-1.0.36 +- Merge pull request #5522 from deltachat/dependabot/cargo/chrono-0.4.38 +- Merge pull request #5523 from deltachat/dependabot/cargo/mailparse-0.15.0 +- Add webxdc internal integration commands in jsonrpc ([#5541](https://github.com/chatmail/core/pull/5541)) +- Limit quote replies ([#5543](https://github.com/chatmail/core/pull/5543)) +- Stdio jsonrpc server npm package ([#5332](https://github.com/chatmail/core/pull/5332)) + +### Refactor + +- python: Fix ruff 0.4.2 warnings. +- Move `delete_poi_location` to location module and document it. +- Remove allow_keychange. + +### Tests + +- Explain test_was_seen_recently false-positive and give workaround instructions ([#5474](https://github.com/chatmail/core/pull/5474)). +- Test that member is added even if "Member added" is lost. +- Test that POIs are deleted when ephemeral message expires. +- Test ts build on branch + + +## [1.137.4] - 2024-04-24 + +### API-Changes + +- [**breaking**] Remove `Stream` implementation for `EventEmitter`. +- Experimental Webxdc Integration API, Maps Integration ([#5461](https://github.com/chatmail/core/pull/5461)). + +### Features / Changes + +- Add progressive backoff for failing IMAP connection attempts ([#5443](https://github.com/chatmail/core/pull/5443)). +- Replace event channel with broadcast channel. +- Mark contact request messages as seen on IMAP. + +### Fixes + +- Convert images to RGB8 (without alpha) before encoding into JPEG to fix sending of large RGBA images. +- Don't set `is_bot` for webxdc status updates ([#5445](https://github.com/chatmail/core/pull/5445)). +- Do not fail if Autocrypt Setup Message has no encryption preference to fix key transfer from K-9 Mail to Delta Chat. +- Use only CRLF in Autocrypt Setup Message. +- python: Use cached message object if `dc_get_msg()` returns `NULL`. +- python: `Message::is_outgoing`: Don't reload message from db. +- python: `_map_ffi_event`: Always check if `get_message_by_id()` returned None. +- node: Undefine `NAPI_EXPERIMENTAL` to fix build with new clang. + +### Build system + +- nix: Add `imap-tools` as `deltachat-rpc-client` dependency. +- nix: Add `./deltachat-contact-tools` to sources. +- nix: Update nix flake. +- deps: Update rustls to 0.21.11. + +### Documentation + +- Update references to SecureJoin protocols. +- Fix broken references in documentation comments. + +### Refactor + +- imap: remove `RwLock` from `ratelimit`. +- deltachat-ffi: Remove unused `ResultNullableExt`. +- Remove duplicate clippy exceptions. +- Group `use` at the top of the test modules. + +## [1.137.3] - 2024-04-16 + +### API-Changes + +- [**breaking**] Remove reactions ffi; all implementations use jsonrpc. +- Don't load trashed messages with `Message::load_from_db`. +- Add `ChatListChanged` and `ChatListItemChanged` events ([#4476](https://github.com/chatmail/core/pull/4476)). +- deltachat-rpc-client: Add `check_qr` and `set_config_from_qr` APIs. +- deltachat-rpc-client: Add `Account.create_chat()`. +- deltachat-rpc-client: Add `Message.wait_until_delivered()`. +- deltachat-rpc-client: Add `Chat.send_file()`. +- deltachat-rpc-client: Add `Account.wait_for_reactions_changed()`. +- deltachat-rpc-client: Return Message from `Message.send_reaction()`. +- deltachat-rpc-client: Add `Account.bring_online()`. +- deltachat-rpc-client: Add `ACFactory.get_accepted_chat()`. + +### Features / Changes + +- Port `direct_imap.py` into deltachat-rpc-client. + +### Fixes + +- Do not emit `MSGS_CHANGED` event for outgoing hidden messages. +- `Message::get_summary()` must not return reaction summary. +- Fix emitting `ContactsChanged` events on "recently seen" status change ([#5377](https://github.com/chatmail/core/pull/5377)). +- deltachat-jsonrpc: block in `inner_get_backup_qr`. +- Add tolerance to `MemberListTimestamp` ([#5366](https://github.com/chatmail/core/pull/5366)). +- Keep webxdc instance for `delete_device_after` period after a status update ([#5365](https://github.com/chatmail/core/pull/5365)). +- Don't try to do `fetch_move_delete()` if Trash is needed but not yet configured. +- Assign messages to chats based on not fully downloaded references. +- Do not create ad-hoc groups from partial downloads. +- deltachat-rpc-client: construct Thread with `target` keyword argument. +- Format error context in `Message::load_from_db`. + +### Build system + +- cmake: adapt target install path if env var `CARGO_BUILD_TARGET` is set. +- nix: Use stable Rust in flake.nix devshell. + +### CI + +- Use cargo-nextest instead of cargo-test. +- Run doc tests with cargo test --workspace --doc ([#5459](https://github.com/chatmail/core/pull/5459)). +- Typos in CI files ([#5453](https://github.com/chatmail/core/pull/5453)). + +### Documentation + +- Add badge. +- Add 'Ubuntu Touch' to the list of 'frontend projects' + +### Refactor + +- Do not ignore `Contact::get_by_id` errors in `get_encrinfo`. +- deltachat-rpc-client: Use `list`, `set` and `tuple` instead of `typing`. +- Use `clone_from()` ([#5451](https://github.com/chatmail/core/pull/5451)). +- Do not check for `is_trash()` in `get_last_reaction_if_newer_than()`. +- Split off functional contact tools into its own crate ([#5444](https://github.com/chatmail/core/pull/5444)) +- Fix nightly clippy warnings. + +### Tests + +- Test withdrawing group join QR codes. +- `display_chat()`: Don't add day markers. +- Move reaction tests to JSON-RPC. +- node: Increase 'static tests' timeout to 5 minutes. + +## [1.137.2] - 2024-04-05 + +### API-Changes + +- [**breaking**] Increase Minimum Supported Rust Version to 1.77.0. + +### Features / Changes + +- Show reactions in summaries ([#5387](https://github.com/chatmail/core/pull/5387)). + +### Tests + +- Test reactions for forwarded messages + +### Refactor + +- `is_probably_private_reply`: Remove reaction-specific code. +- Use Rust 1.77.0 support for recursion in async functions. + +### Miscellaneous Tasks + +- cargo: Bump rustyline from 13.0.0 to 14.0.0. +- Update chrono from 0.4.34 to 0.4.37. +- Update from brotli 3.4.0 to brotli 4.0.0. +- Upgrade `h2` from 0.4.3 to 0.4.4. +- Upgrade `image` from 0.24.9 to 0.25.1. +- cargo: Bump fast-socks5 from 0.9.5 to 0.9.6. + +## [1.137.1] - 2024-04-03 + +### CI + +- Remove android builds for `x86` and `x86_64`. + +## [1.137.0] - 2024-04-02 + +### API-Changes + +- [**breaking**] Remove data from `DC_EVENT_INCOMING_MSG_BUNCH`. +- [**breaking**] Remove unused `dc_accounts_all_work_done()` ([#5384](https://github.com/chatmail/core/pull/5384)). +- deltachat-rpc-client: Add futures. + +### Build system + +- cmake: Build outside the source tree. +- nix: Add outputs for Android binaries. +- Add `repository` to Cargo.toml. +- python: Remove `setuptools_scm` dependency. +- Add development shell ([#5390](https://github.com/chatmail/core/pull/5390)). + +### CI + +- Update to Rust 1.77.0. +- Build deltachat-rpc-server for Android. +- Shorter names for deltachat-rpc-server jobs. + +### Features / Changes + +- Do not include provider hostname in `Message-ID`. +- Include 3 recent Message-IDs in `References` header. +- Include more entries into DNS fallback cache. + +### Fixes + +- Preserve upper-/lowercase of links parsed by `dehtml()` ([#5362](https://github.com/chatmail/core/pull/5362)). +- Rescan folders after changing `Config::SentboxWatch`. +- Do not ignore `Contact::get_by_id()` error in `from_field_to_contact_id()`. +- Put overridden sender name into message info. +- Don't send selfavatar in `SecureJoin` messages before contact verification ([#5354](https://github.com/chatmail/core/pull/5354)). +- Always set correct `chat_id` for `DC_EVENT_REACTIONS_CHANGED` ([#5419](https://github.com/chatmail/core/pull/5419)). + +### Refactor + +- Remove `MessageObject::from_message_id()`. +- jsonrpc: Add `msg_id` and `account_id` to `get_message()` errors. +- Cleanup `jobs` and `Params` relicts. + +### Tests + +- `Test_mvbox_sentbox_threads`: Check that sentbox gets configured after setting `sentbox_watch` ([#5105](https://github.com/chatmail/core/pull/5105)). +- Remove flaky time check from `test_list_from()`. +- Add failing test for #5418 (wrong `DC_EVENT_REACTIONS_CHANGED`) + +### Miscellaneous Tasks + +- Add `result` to .gitignore. +- cargo: Bump thiserror from 1.0.57 to 1.0.58. +- cargo: Bump tokio from 1.36.0 to 1.37.0. +- cargo: Bump pin-project from 1.1.4 to 1.1.5. +- cargo: Bump strum from 0.26.1 to 0.26.2. +- cargo: Bump uuid from 1.7.0 to 1.8.0. +- cargo: Bump toml from 0.8.10 to 0.8.12. +- cargo: Bump tokio-stream from 0.1.14 to 0.1.15. +- cargo: Bump smallvec from 1.13.1 to 1.13.2. +- cargo: Bump async-smtp from 0.9.0 to 0.9.1. +- cargo: Bump strum_macros from 0.26.1 to 0.26.2. +- cargo: Bump serde_json from 1.0.114 to 1.0.115. +- cargo: Bump anyhow from 1.0.80 to 1.0.81. +- cargo: Bump syn from 2.0.52 to 2.0.57. +- cargo: Bump futures-lite from 2.2.0 to 2.3.0. +- cargo: Bump axum from 0.7.4 to 0.7.5. +- cargo: Bump reqwest from 0.11.24 to 0.12.2. +- cargo: Bump backtrace from 0.3.69 to 0.3.71. +- cargo: Bump regex from 1.10.3 to 1.10.4. +- cargo: Update aho-corasick from 1.1.2 to 1.1.3. +- Update deny.toml. + +## [1.136.6] - 2024-03-19 + +### Build system + +- Add description to deltachat-rpc-server wheels. +- Read version from Cargo.toml in wheel-rpc-server.py. + +### CI + +- Update actions/cache from v3 to v4. +- Automate publishing of deltachat-rpc-server to PyPI. + +### Documentation + +- deltachat-rpc-server: Update deltachat-rpc-client URL. + +### Miscellaneous Tasks + +- Nix flake update. + +## [1.136.5] - 2024-03-18 + +### Features / Changes + +- Nicer summaries: prefer emoji over names +- Add `save_mime_headers` to debug info ([#5350](https://github.com/chatmail/core/pull/5350)) + +### Fixes + +- Terminate ephemeral and location loop immediately on channel close. +- Update MemberListTimestamp when sending a group message. +- On iOS, use FILE (default) instead of MEMORY ([#5349](https://github.com/chatmail/core/pull/5349)). +- Add white background to recoded avatars ([#3787](https://github.com/chatmail/core/pull/3787)). + +### Build system + +- Add README to deltachat-rpc-client Python packages. + +### Documentation + +- deltachat-rpc-client: Document that 0 is a special value of `set_ephemeral_timer()`. + +### Tests + +- Test that reordering of Member added message results in square bracket error. + +## [1.136.4] - 2024-03-11 + +### Build system + +- nix: Make .#libdeltachat buildable on macOS. +- Build deltachat-rpc-server wheels with nix. + +### CI + +- Add workflow for automatic publishing of deltachat-rpc-client. + +### Fixes + +- Remove duplicate CHANGELOG entries for 1.135.1. + +## [1.136.3] - 2024-03-09 + +### Features / Changes + +- Start IMAP loop for sentbox only if it is configured ([#5105](https://github.com/chatmail/core/pull/5105)). + +### Fixes + +- Remove leading whitespace from Subject ([#5106](https://github.com/chatmail/core/pull/5106)). +- Create new Peerstate for unencrypted message with already known Autocrypt key, but a new address. + +### Build system + +- nix: Cleanup cross-compilation code. +- nix: Include SystemConfiguration framework on darwin systems. + +### CI + +- Wait for `build_windows` task before trying to publish it. +- Remove artifacts from npm package. + +### Refactor + +- Don't parse Autocrypt header for outgoing messages ([#5259](https://github.com/chatmail/core/pull/5259)). +- Remove `deduplicate_peerstates()`. +- Fix 2024-03-05 nightly clippy warnings. + +### Miscellaneous Tasks + +- deps: Bump mio from 0.8.8 to 0.8.11 in /fuzz. +- RPC client: Add missing constants ([#5110](https://github.com/chatmail/core/pull/5110)). + +## [1.136.2] - 2024-03-05 + +### Build system + +- Downgrade `cc` to 1.0.83 to fix build for Android. + +### CI + +- Update setup-node action. + +## [1.136.1] - 2024-03-05 + +### Build system + +- Revert to OpenSSL 3.1. +- Restore MSRV 1.70.0. + +### Miscellaneous Tasks + +- Update node constants. + +## [1.136.0] - 2024-03-04 + +### Features / Changes + +- Recognise Trash folder by name ([#5275](https://github.com/chatmail/core/pull/5275)). +- Send Chat-Group-Avatar as inline base64 ([#5253](https://github.com/chatmail/core/pull/5253)). +- Self-Reporting: Report number of protected/encrypted/unencrypted chats ([#5292](https://github.com/chatmail/core/pull/5292)). + +### Fixes + +- Don't send sync messages on self-{status,avatar} update from self-sent messages ([#5289](https://github.com/chatmail/core/pull/5289)). +- imap: Allow `maybe_network` to interrupt connection ratelimit. +- imap: Set connectivity to "connecting" only after ratelimit. +- Remove `Group-ID` from `Message-ID`. +- Prioritize protected `Message-ID` over `X-Microsoft-Original-Message-ID`. + +### API-Changes + +- Make `store_self_keypair` private. +- Add `ContextBuilder.build()` to build Context without opening. +- `dc_accounts_set_push_device_token` and `dc_get_push_state` APIs for iOS push notifications. + +### Build system + +- Tag armv6 wheels with tags accepted by PyPI. +- Unpin OpenSSL. +- Remove deprecated `unmaintained` field from deny.toml. +- Do not vendor OpenSSL when cross-compiling ([#5316](https://github.com/chatmail/core/pull/5316)). +- Increase MSRV to 1.74.0. + +### CI + +- Upgrade setup-python GitHub Action. +- Update to Rust 1.76 and fix clippy warnings. +- Build Python docs with Nix. +- Upload python docs without GH actions. +- Upload cffi docs without GH actions. +- Build c.delta.chat docs with nix. + +### Other + +- refactor: move more methods from Imap into Session. +- Add deltachat-time to sources. + +### Refactor + +- Remove Session from Imap structure. +- Merge ImapConfig into Imap. +- Get rid of ImapActionResult. +- Build contexts using ContextBuilder. +- Do not send `Secure-Join-Group` in `vg-request`. + +### Tests + +- Fix `test_verified_oneonone_chat_broken_by_device_change()` ([#5280](https://github.com/chatmail/core/pull/5280)). +- `get_protected_chat()`: Use FFIEventTracker instead of `dc_wait_next_msgs()` ([#5207](https://github.com/chatmail/core/pull/5207)). +- Fixup `tests/test_3_offline.py::TestOfflineAccountBasic::test_wrong_db`. +- Fix pytest compat ([#5317](https://github.com/chatmail/core/pull/5317)). + +## [1.135.1] - 2024-02-20 + +### Features / Changes + +- Sync self-avatar across devices ([#4893](https://github.com/chatmail/core/pull/4893)). +- Sync Config::Selfstatus across devices ([#4893](https://github.com/chatmail/core/pull/4893)). +- Remove webxdc sending limit. + +### Fixes + +- Never encrypt `{vc,vg}-request` SecureJoin messages. +- Apply Autocrypt headers if timestamp is unchanged. +- `Context::get_info`: Report displayname as "displayname" (w/o underscore). + +### Tests + +- Mock `SystemTime::now()` for the tests. +- Add a test on protection message sort timestamp ([#5088](https://github.com/chatmail/core/pull/5088)). + +### Build system + +- Add flake.nix. +- Add footer template for git-cliff. + +### CI + +- Update GitHub Actions `actions/upload-artifact`, `actions/download-artifact`, `actions/checkout`. +- Build deltachat-repl for Windows with nix. +- Build deltachat-rpc-server with nix. +- Try to upload deltachat-rpc-server only on release. +- Fixup node-package.yml after artifact actions upgrade. +- Update to actions/checkout@v4. +- Replace download-artifact v1 with v4. + +### Refactor + +- `create_keypair`: Remove unnecessary `map_err`. +- Return error with a cause when failing to export keys. +- Rename incorrectly named variables in `create_keypair`. + +## [1.135.0] - 2024-02-13 + +### Features / Changes + +- Add wildcard pattern support to provider database. +- Add device message about outgoing undecryptable messages ([#5164](https://github.com/chatmail/core/pull/5164)). +- Context::set_config(): Restart IO scheduler if needed ([#5111](https://github.com/chatmail/core/pull/5111)). +- Server_sent_unsolicited_exists(): Log folder name. +- Cache system time instead of looking at the clock several times in a row. +- Basic self-reporting ([#5129](https://github.com/chatmail/core/pull/5129)). + +### Fixes + +- Dehtml: Don't just truncate text when trying to decode ([#5223](https://github.com/chatmail/core/pull/5223)). +- Mark the gossip keys from the message as verified, not the ones from the db ([#5247](https://github.com/chatmail/core/pull/5247)). +- Guarantee immediate message deletion if delete_server_after == 0 ([#5201](https://github.com/chatmail/core/pull/5201)). +- Never allow a message timestamp to be a lot in the future ([#5249](https://github.com/chatmail/core/pull/5249)). +- Imap::configure_mvbox: Do select_with_uidvalidity() before return. +- ImapSession::select_or_create_folder(): Don't fail if folder is created in parallel. +- Emit ConfigSynced event on the second device. +- Create mvbox on setting mvbox_move. +- Use SystemTime instead of Instant everywhere. +- Restore database rows removed in previous release; this ensures compatibility when adding second device or importing backup and not all devices run the new core ([#5254](https://github.com/chatmail/core/pull/5254)) + +### Miscellaneous Tasks + +- cargo: Bump image from 0.24.7 to 0.24.8. +- cargo: Bump chrono from 0.4.31 to 0.4.33. +- cargo: Bump futures-lite from 2.1.0 to 2.2.0. +- cargo: Bump pin-project from 1.1.3 to 1.1.4. +- cargo: Bump iana-time-zone from yanked 0.1.59 to 0.1.60. +- cargo: Bump smallvec from 1.11.2 to 1.13.1. +- cargo: Bump base64 from 0.21.5 to 0.21.7. +- cargo: Bump regex from 1.10.2 to 1.10.3. +- cargo: Bump libc from 0.2.151 to 0.2.153. +- cargo: Bump reqwest from 0.11.23 to 0.11.24. +- cargo: Bump axum from 0.7.3 to 0.7.4. +- cargo: Bump uuid from 1.6.1 to 1.7.0. +- cargo: Bump fast-socks5 from 0.9.2 to 0.9.5. +- cargo: Bump serde_json from 1.0.111 to 1.0.113. +- cargo: Bump syn from 2.0.46 to 2.0.48. +- cargo: Bump serde from 1.0.194 to 1.0.196. +- cargo: Bump toml from 0.8.8 to 0.8.10. +- cargo: Update to strum 0.26. +- Cargo update. +- scripts: Do not install deltachat-rpc-client twice. + +### Other + +- Update welcome image, thanks @paulaluap +- Merge pull request #5243 from deltachat/dependabot/cargo/pin-project-1.1.4 +- Merge pull request #5241 from deltachat/dependabot/cargo/futures-lite-2.2.0 +- Merge pull request #5236 from deltachat/dependabot/cargo/chrono-0.4.33 +- Merge pull request #5235 from deltachat/dependabot/cargo/image-0.24.8 + + +### Refactor + +- Resultify token::exists. + +### Tests + +- Delete_server_after="1" should cause immediate message deletion ([#5201](https://github.com/chatmail/core/pull/5201)). + +## [1.134.0] - 2024-01-31 + +### API-Changes + +- [**breaking**] JSON-RPC: device message api now requires `Option` instead of `String` for the message ([#5211](https://github.com/chatmail/core/pull/5211)). +- CFFI: add `dc_accounts_background_fetch` and event `DC_EVENT_ACCOUNTS_BACKGROUND_FETCH_DONE`. +- JSON-RPC: add `accounts_background_fetch`. + +### Features / Changes + +- `Qr::check_qr()`: Accept i.delta.chat invite links ([#5217](https://github.com/chatmail/core/pull/5217)). +- Add support for IMAP METADATA, fetching `/shared/comment` and `/shared/admin` and displaying it in account info. + +### Fixes + +- Add tolerance for macOS and iOS changing `#` to `%23`. +- Do not drop unknown report attachments, such as TLS reports. +- Treat only "Auto-Submitted: auto-generated" messages as bot-sent ([#5213](https://github.com/chatmail/core/pull/5213)). +- `Chat::resend_msgs`: Guarantee strictly increasing time in the `Date` header. +- Delete resent messages on receiver side ([#5155](https://github.com/chatmail/core/pull/5155)). +- Fix iOS build issue. + +### CI + +- Add/remove necessary newlines to fix Python lint. + +### Tests + +- `test_import_export_online_all`: Send the message to the existing address to avoid errors ([#5220](https://github.com/chatmail/core/pull/5220)). + +## [1.133.2] - 2024-01-24 + +### Fixes + +- Downgrade OpenSSL from 3.2.0 to 3.1.4 ([#5206](https://github.com/chatmail/core/issues/5206)) +- No new chats for MDNs with alias ([#5196](https://github.com/chatmail/core/issues/5196)) ([#5199](https://github.com/chatmail/core/pull/5199)). + +## [1.133.1] - 2024-01-21 + +### API-Changes + +- Add `is_bot` to cffi and jsonrpc ([#5197](https://github.com/chatmail/core/pull/5197)). + +### Features / Changes + +- Add system message when provider does not allow unencrypted messages ([#5195](https://github.com/chatmail/core/pull/5195)). + +### Fixes + +- `Chat::send_msg`: Remove encryption-related params from already sent message. This allows to send received encrypted `dc_msg_t` object to unencrypted chat, e.g. in a Python bot. +- Set message download state to Failure on IMAP errors. This avoids partially downloaded messages getting stuck in "Downloading..." state without actually being in a download queue. +- BCC-to-self even if server deletion is set to "at once". This is a workaround for SMTP servers which do not return response in time, BCC-self works as a confirmation that message was sent out successfully and does not need more retries. +- node: Run tests with native ESM modules instead of `esm` ([#5194](https://github.com/chatmail/core/pull/5194)). +- Use Quoted-Printable MIME encoding for the text part ([#3986](https://github.com/chatmail/core/pull/3986)). + +### Tests + +- python: Add `get_protected_chat` to testplugin.py. + +## [1.133.0] - 2024-01-14 + +### Features / Changes + +- Securejoin protocol implementation refinements + - Track forward and backward verification separately ([#5089](https://github.com/chatmail/core/pull/5089)) to avoid inconsistent states. + - Mark 1:1 chat as verified for Bob early. 1:1 chat with Alice is verified as soon as Alice's key is verified rather than at the end of the protocol. +- Put Message-ID into hidden headers and take it from there on receiver ([#4798](https://github.com/chatmail/core/pull/4798)). This works around servers which generate their own Message-ID and overwrite the one generated by Delta Chat. +- deltachat-repl: Enable INFO logging by default and add timestamps. +- Add `ConfigSynced` (`DC_EVENT_CONFIG_SYNCED`) event which is emitted when configuration is changed via synchronization message or synchronization message for configuration is sent. UI may refresh elements based on the configuration key which is a part of the event. +- Sync contact creation/rename across devices ([#5163](https://github.com/chatmail/core/pull/5163)). +- Encrypt MDNs ([#5175](https://github.com/chatmail/core/pull/5175)). +- Only try to configure non-strict TLS checks if explicitly set ([#5181](https://github.com/chatmail/core/pull/5181)). + +### Build system + +- Use released version of iroh 0.4.2 for "setup second device" feature. + +### CI + +- Update to Rust 1.75.0. +- Downgrade `chai` from 4.4.0 to 4.3.10. + +### Documentation + +- Add a link to autoconfig RFC draft. +- Update securejoin link in `standards.md` from to . +- Restore "Constants" page in Doxygen >=1.9.8 + +### Fixes + +- imap: Limit the rate of LOGIN attempts rather than connection attempts. This is to avoid having to wait for rate limiter right after switching from a bad or offline network to a working network while still guarding against reconnection loop. +- Do not ignore `peerstate.save_to_db()` errors. +- securejoin: Mark 1:1s as protected regardless of the Config::VerifiedOneOnOneChats. +- Delete received outgoing messages from SMTP queue ([#5115](https://github.com/chatmail/core/pull/5115)). +- imap: Fail fast on `LIST` errors to avoid busy loop when connection is lost. +- Split SMTP jobs already in `chat::create_send_msg_jobs()` ([#5115](https://github.com/chatmail/core/pull/5115)). +- Do not remove contents from unencrypted [Schleuder](https://schleuder.org/) mailing lists messages. +- Reset message error when scheduling resending ([#5119](https://github.com/chatmail/core/pull/5119)). +- Emit events more reliably when starting and stopping I/O ([#5101](https://github.com/chatmail/core/pull/5101)). +- Fix timestamp of chat protection info message for correct message ordering after restoring a backup ([#5088](https://github.com/chatmail/core/pull/5088)). + +### Refactor + +- sql: Recreate `config` table with UNIQUE constraint. +- sql: Recreate `keypairs` table to remove unused `addr` and `created` fields and move `is_default` flag to `config` table. +- Send `Secure-Join-Fingerprint` only in `*-request-with-auth`. + +### Tests + +- Test joining non-protected group. +- Test that read receipts don't degrade encryption. +- Test that changing default private key breaks backward verification. +- Test recovery from lost vc-contact-confirm. +- Use `wait_for_incoming_msg_event()` more. + +## [1.132.1] - 2023-12-12 + +### Features / Changes + +- Add "From:" to protected headers for signed-only messages. +- Sync user actions for ad-hoc groups across devices ([#5065](https://github.com/chatmail/core/pull/5065)). + +### Fixes + +- Add padlock to empty part if the whole message is empty. +- Renew IDLE timeout on keepalives and reduce it to 5 minutes. +- connectivity: Return false from `all_work_done()` immediately after connecting (iOS notification fix). + +### API-Changes + +- deltachat-jsonrpc-client: add `Account.{import,export}_self_keys`. + +### CI + +- Update to Rust 1.74.1. + +## [1.132.0] - 2023-12-06 + +### Features / Changes + +- Increase TCP timeouts from 30 to 60 seconds. + +### Fixes + +- Don't sort message creating a protected group over a protection message ([#4963](https://github.com/chatmail/core/pull/4963)). +- Do not lock accounts.toml on iOS. +- Protect groups even if some members are not verified and add `test_securejoin_after_contact_resetup` regression test. + +## [1.131.9] - 2023-12-02 + +### API-Changes + +- Remove `dc_get_http_response()`, `dc_http_response_get_mimetype()`, `dc_http_response_get_encoding()`, `dc_http_response_get_blob()`, `dc_http_response_get_size()`, `dc_http_response_unref()` and `dc_http_response_t` from cffi. +- Deprecate CFFI APIs `dc_send_reaction()`, `dc_get_msg_reactions()`, `dc_reactions_get_contacts()`, `dc_reactions_get_by_contact_id()`, `dc_reactions_unref` and `dc_reactions_t`. +- Make `Contact.is_verified()` return bool. + +### Build system + +- Switch from fork of iroh to iroh 0.4.2 pre-release. + +### Features / Changes + +- Send `Chat-Verified` headers in 1:1 chats. +- Ratelimit IMAP connections ([#4940](https://github.com/chatmail/core/pull/4940)). +- Remove receiver limit on `.xdc` size. +- Don't affect MimeMessage with "From" and secured headers from encrypted unsigned messages. +- Sync `Config::{MdnsEnabled,ShowEmails}` across devices ([#4954](https://github.com/chatmail/core/pull/4954)). +- Sync `Config::Displayname` across devices ([#4893](https://github.com/chatmail/core/pull/4893)). +- `Chat::rename_ex`: Don't send sync message if usual message is sent. + +### Fixes + +- Lock the database when INSERTing a webxdc update, avoid "Database is locked" errors. +- Use keyring with all private keys when decrypting a message ([#5046](https://github.com/chatmail/core/pull/5046)). + +### Tests + +- Make Result-returning tests produce a line number. +- Add `test_utils::sync()`. +- Test inserting lots of webxdc updates. +- Split `test_sync_alter_chat()` into smaller tests. + +## [1.131.8] - 2023-11-27 + +### Features / Changes + +- webxdc: Add unique IDs to status updates sent outside and deduplicate based on IDs. + +### Fixes + +- Allow IMAP servers not returning UIDNEXT on SELECT and STATUS such as mail.163.com. +- Use the correct securejoin strings used in the UI, remove old TODO ([#5047](https://github.com/chatmail/core/pull/5047)). +- Do not emit events about webxdc update events logged into debug log webxdc. + +### Tests + +- Check that `receive_status_update` has forward compatibility and unique webxdc IDs will be ignored by previous Delta Chat versions. + +## [1.131.7] - 2023-11-24 + +### Fixes + +- Revert "fix: check UIDNEXT with a STATUS command before going IDLE". This attempts to fix mail.163.com which has broken STATUS command. + +## [1.131.6] - 2023-11-21 + +### Fixes + +- Fail fast if IMAP FETCH cannot be parsed instead of getting stuck in infinite loop. + +### Documentation + +- Generate deltachat-rpc-client documentation and publish it to . + +## [1.131.5] - 2023-11-20 + +### API-Changes + +- deltachat-rpc-client: Add `Message.get_sender_contact()`. +- Turn `ContactAddress` into an owned type. + +### Features / Changes + +- Lowercase addresses in Autocrypt and Autocrypt-Gossip headers. +- Lowercase the address in member added/removed messages. +- Lowercase `addr` when it is set. +- Do not replace the message with an error in square brackets when the sender is not a member of the protected group. + +### Fixes + +- `Chat::sync_contacts()`: Fetch contact addresses in a single query. +- `Chat::rename_ex()`: Sync improved chat name to other devices. +- Recognize `Chat-Group-Member-Added` of self case-insensitively. +- Compare verifier addr to peerstate addr case-insensitively. + +### Tests + +- Port [Secure-Join](https://securejoin.readthedocs.io/) tests to JSON-RPC. + +### CI + +- Test with Rust 1.74. + + +## [1.131.4] - 2023-11-16 + +### Documentation + +- Document DC_DOWNLOAD_UNDECIPHERABLE. + +### Fixes + +- Always add "Member added" as system message. + +## [1.131.3] - 2023-11-15 + +### Fixes + +- Update async-imap to 0.9.4 which does not ignore EOF on FETCH. +- Reset gossiped timestamp on securejoin. +- sync: Ignore unknown sync items to provide forward compatibility and avoid creating empty message bubbles. +- sync: Skip sync when chat name is set to the current one. +- Return connectivity HTML with an error when IO is stopped. + +## [1.131.2] - 2023-11-14 + +### API-Changes + +- deltachat-rpc-client: add `Account.get_chat_by_contact()`. + +### Features / Changes + +- Do not post "... verified" messages on QR scan success. +- Never drop better message from `apply_group_changes()`. + +### Fixes + +- Assign MDNs to the trash chat early to prevent received MDNs from creating or unblocking 1:1 chats. +- Allow to securejoin groups when 1:1 chat with the inviter is a contact request. +- Add "setup changed" message for verified key before the message. +- Ignore special chats when calculating similar chats. + +## [1.131.1] - 2023-11-13 + +### Fixes + +- Do not skip actual message parts when group change messages are inserted. + +## [1.131.0] - 2023-11-13 + +### Features / Changes + +- Sync chat contacts across devices ([#4953](https://github.com/chatmail/core/pull/4953)). +- Sync creating broadcast lists across devices ([#4953](https://github.com/chatmail/core/pull/4953)). +- Sync Chat::name across devices ([#4953](https://github.com/chatmail/core/pull/4953)). +- Multi-device broadcast lists ([#4953](https://github.com/chatmail/core/pull/4953)). + +### Fixes + +- Encode chat name in the `List-ID` header to avoid SMTPUTF8 errors. +- Ignore errors from generating sync messages. +- `Context::execute_sync_items`: Ignore all errors ([#4817](https://github.com/chatmail/core/pull/4817)). +- Allow to send unverified securejoin messages to protected chats ([#4982](https://github.com/chatmail/core/pull/4982)). + +## [1.130.0] - 2023-11-10 + +### API-Changes + +- Emit JoinerProgress(1000) event when Bob verifies Alice. +- JSON-RPC: add `ContactObject.is_profile_verified` property. +- Hide `ChatId::get_for_contact()` from public API. + +### Features / Changes + +- Add secondary verified key. +- Add info messages about implicitly added members. +- Treat reset state as encryption not preferred. +- Grow sleep durations on errors in Imap::fake_idle() ([#4424](https://github.com/chatmail/core/pull/4424)). + +### Fixes + +- Mark 1:1 chat as protected when joining a group. +- Raise lower auto-download limit to 160k. +- Remove `Reporting-UA` from read receipts. +- Do not apply group changes to special chats. Avoid adding members to the trash chat. +- imap: make `UidGrouper` robust against duplicate UIDs. +- Do not return hidden chat from `dc_get_chat_id_by_contact_id`. +- Smtp_loop(): Don't grow timeout if interrupted early ([#4833](https://github.com/chatmail/core/pull/4833)). + +### Refactor + +- imap: Do not FETCH right after `scan_folders()`. +- deltachat-rpc-client: Use `itertools` instead of `Lock` for thread-safe request ID generation. + +### Tests + +- Remove unused `--liveconfig` option. +- Test chatlist can load for corrupted chats ([#4979](https://github.com/chatmail/core/pull/4979)). + +### Miscellaneous Tasks + +- Update provider-db ([#4949](https://github.com/chatmail/core/pull/4949)). + +## [1.129.1] - 2023-11-06 + +### Fixes + +- Update tokio-imap to fix Outlook STATUS parsing bug. +- deltachat-rpc-client: Add the Lock around request ID. +- `apply_group_changes`: Don't implicitly delete members locally, add absent ones instead ([#4934](https://github.com/chatmail/core/pull/4934)). +- Partial messages do not change group state ([#4900](https://github.com/chatmail/core/pull/4900)). + +### Tests + +- Group chats device synchronisation. + +## [1.129.0] - 2023-11-06 + +### API-Changes + +- Add JSON-RPC `get_chat_id_by_contact_id` API ([#4918](https://github.com/chatmail/core/pull/4918)). +- [**breaking**] Remove deprecated `get_verifier_addr`. + +### Features / Changes + +- Sync chat `Blocked` state, chat visibility, chat mute duration and contact blocked status across devices ([#4817](https://github.com/chatmail/core/pull/4817)). +- Add 'group created instructions' as info message ([#4916](https://github.com/chatmail/core/pull/4916)). +- Add hardcoded fallback DNS cache. + +### Fixes + +- Switch to `EncryptionPreference::Mutual` on a receipt of encrypted+signed message ([#4707](https://github.com/chatmail/core/pull/4707)). +- imap: Check UIDNEXT with a STATUS command before going IDLE. +- Allow to change verified key via "member added" message. +- json-rpc: Return verifier even if the contact is not "verified" (Autocrypt key does not equal Secure-Join key). + +### Documentation + +- Refine `Contact::get_verifier_id` and `Contact::is_verified` documentation ([#4922](https://github.com/chatmail/core/pull/4922)). +- Contact profile view should not use `dc_contact_is_verified()`. +- Remove documentation for non-existing `dc_accounts_new` `os_name` param. + +### Refactor + +- Remove unused or useless code paths in Secure-Join ([#4897](https://github.com/chatmail/core/pull/4897)). +- Improve error handling in Secure-Join code. +- Add hostname to "no DNS resolution results" error message. +- Accept `&str` instead of `Option` in idle(). + +## [1.128.0] - 2023-11-02 + +### Build system +- [**breaking**] Upgrade nodejs version to 18 ([#4903](https://github.com/chatmail/core/pull/4903)). + +### Features / Changes + +- deltachat-rpc-client: Add `Account.wait_for_incoming_msg_event()`. +- Decrease ratelimit for .testrun.org subdomains. + +### Fixes + +- Do not fail securejoin due to unrelated pending bobstate ([#4896](https://github.com/chatmail/core/pull/4896)). +- Allow other verified group recipients to be unverified, only check the sender verification. +- Remove not working attempt to recover from verified key changes. + +## [1.127.2] - 2023-10-29 + +### API-Changes + +- [**breaking**] Jsonrpc `misc_set_draft` now requires setting the viewtype. +- jsonrpc: Add `get_message_info_object`. + +### Tests + +- deltachat-rpc-client: Move pytest option from pyproject.toml to tox.ini and set log level. +- deltachat-rpc-client: Test securejoin. +- Increase pytest timeout to 10 minutes. +- Compile deltachat-rpc-server in debug mode for tests. + +## [1.127.1] - 2023-10-27 + +### API-Changes + +- jsonrpc: add `.is_protection_broken` to `FullChat` and `BasicChat`. +- jsonrpc: Add `id` to `ProviderInfo`. + +## [1.127.0] - 2023-10-26 + +### API-Changes + +- [**breaking**] `dc_accounts_new` API is changed. Unused `os_name` argument is removed and `writable` argument is added. +- jsonrpc: Add `resend_messages`. +- [**breaking**] Remove unused function `is_verified_ex()` ([#4551](https://github.com/chatmail/core/pull/4551)) +- [**breaking**] Make `MsgId.delete_from_db()` private. +- [**breaking**] deltachat-jsonrpc: use `kind` as a tag for all union types +- json-rpc: Force stickers to be sent as stickers ([#4819](https://github.com/chatmail/core/pull/4819)). +- Add mailto parse api ([#4829](https://github.com/chatmail/core/pull/4829)). +- [**breaking**] Remove unused `DC_STR_PROTECTION_(EN)ABLED` strings +- [**breaking**] Remove unused `dc_set_chat_protection()` +- Hide `DcSecretKey` trait from the API. +- Verified 1:1 chats ([#4315](https://github.com/chatmail/core/pull/4315)). Disabled by default, enable with `verified_one_on_one_chats` config. +- Add api `chat::Chat::is_protection_broken` +- Add `dc_chat_is_protection_broken()` C API. + +### CI + +- Run Rust tests with `RUST_BACKTRACE` set. +- Replace `master` branch with `main`. Run CI only on `main` branch pushes. +- Test `deltachat-rpc-client` on Windows. + +### Documentation + +- Document how logs and error messages should be formatted in `CONTRIBUTING.md`. +- Clarify transitive behaviour of `dc_contact_is_verfified()`. +- Document `configured_addr`. + +### Features / Changes + +- Add lockfile to account manager ([#4314](https://github.com/chatmail/core/pull/4314)). +- Don't show a contact as verified if their key changed since the verification ([#4574](https://github.com/chatmail/core/pull/4574)). +- deltachat-rpc-server: Add `--openrpc` option to print OpenRPC specification for JSON-RPC API. This specification can be used to generate JSON-RPC API clients. +- Track whether contact is a bot or not ([#4821](https://github.com/chatmail/core/pull/4821)). +- Replace `Config::SendSyncMsgs` with `SyncMsgs` ([#4817](https://github.com/chatmail/core/pull/4817)). + +### Fixes + +- Don't create 1:1 chat as protected for contact who doesn't prefer to encrypt ([#4538](https://github.com/chatmail/core/pull/4538)). +- Allow to save a draft if the verification is broken ([#4542](https://github.com/chatmail/core/pull/4542)). +- Fix info-message orderings of verified 1:1 chats ([#4545](https://github.com/chatmail/core/pull/4545)). +- Fix example; this was changed some time ago, see https://docs.webxdc.org/spec.html#sendupdate +- `receive_imf`: Update peerstate from db after handling Securejoin handshake ([#4600](https://github.com/chatmail/core/pull/4600)). +- Sort old incoming messages below all outgoing ones ([#4621](https://github.com/chatmail/core/pull/4621)). +- Do not mark non-verified group chats as verified when using securejoin. +- `receive_imf`: Set protection only for Chattype::Single ([#4597](https://github.com/chatmail/core/pull/4597)). +- Return from `dc_get_chatlist(DC_GCL_FOR_FORWARDING)` only chats where we can send ([#4616](https://github.com/chatmail/core/pull/4616)). +- Clear VerifiedOneOnOneChats config on backup ([#4615](https://github.com/chatmail/core/pull/4615)). +- Try removal of accounts multiple times with timeouts in case the database file is blocked (restore `try_many_times` workaround). + +### Build system + +- Remove examples/simple.rs. +- Increase MSRV to 1.70.0. +- Update dependencies. +- Switch to iroh 0.4.x fork with updated dependencies. + +## [1.126.1] - 2023-10-24 + +### Fixes + +- Do not hardcode version in deltachat-rpc-server source package. +- Do not interrupt IMAP loop from `get_connectivity_html()`. + +### Features / Changes + +- imap: Buffer `STARTTLS` command. + +### Build system + +- Build `deltachat-rpc-server` binary for aarch64 macOS. +- Build `deltachat-rpc-server` wheels for macOS and Windows. + +### Refactor + +- Remove job queue. + +### Miscellaneous Tasks + +- cargo: Update `ahash` to make `cargo-deny` happy. + +## [1.126.0] - 2023-10-22 + +### API-Changes + +- Allow to filter by unread in `chatlist:try_load` ([#4824](https://github.com/chatmail/core/pull/4824)). +- Add `misc_send_draft()` to JSON-RPC API ([#4839](https://github.com/chatmail/core/pull/4839)). + +### Features / Changes + +- [**breaking**] Make broadcast lists create their own chat ([#4644](https://github.com/chatmail/core/pull/4644)). + - This means that UIs need to ask for the name when creating a broadcast list, similar to . +- Add self-address to backup filename ([#4820](https://github.com/chatmail/core/pull/4820)) + +### CI + +- Build Python wheels for deltachat-rpc-server. + +### Build system + +- Strip release binaries. +- Workaround OpenSSL crate expecting libatomic to be available. + +### Fixes + +- Set `soft_heap_limit` on SQLite database. +- imap: Fallback to `STATUS` if `SELECT` did not return UIDNEXT. + +## [1.125.0] - 2023-10-14 + +### API-Changes + +- [**breaking**] deltachat-rpc-client: Replace `asyncio` with threads. +- Validate boolean values passed to `set_config`. Attempts to set values other than `0` and `1` will result in an error. + +### CI + +- Reduce required Python version for deltachat-rpc-client from 3.8 to 3.7. + +### Features / Changes + +- Add developer option to disable IDLE. + +### Fixes + +- `deltachat-rpc-client`: Run `deltachat-rpc-server` in its own process group. This prevents reception of `SIGINT` by the server when the bot is terminated with `^C`. +- python: Don't automatically set the displayname to "bot" when setting log level. +- Don't update `timestamp`, `timestamp_rcvd`, `state` when replacing partially downloaded message ([#4700](https://github.com/chatmail/core/pull/4700)). +- Assign encrypted partially downloaded group messages to 1:1 chat ([#4757](https://github.com/chatmail/core/pull/4757)). +- Return all contacts from `Contact::get_all` for bots ([#4811](https://github.com/chatmail/core/pull/4811)). +- Set connectivity status to "connected" during fake idle. +- Return verifier contacts regardless of their origin. +- Don't try to send more MDNs if there's a temporary SMTP error ([#4534](https://github.com/chatmail/core/pull/4534)). + +### Refactor + +- deltachat-rpc-client: Close stdin instead of sending `SIGTERM`. +- deltachat-rpc-client: Remove print() calls. Standard `logging` package is for logging instead. + +### Tests + +- deltachat-rpc-client: Enable logs in pytest. + +## [1.124.1] - 2023-10-05 + +### Fixes + +- Remove footer from reactions on the receiver side ([#4780](https://github.com/chatmail/core/pull/4780)). + +### CI + +- Pin `urllib3` version to `<2`. ([#4788](https://github.com/chatmail/core/issues/4788)) + +## [1.124.0] - 2023-10-04 + +### API-Changes + +- [**breaking**] Return `DC_CONTACT_ID_SELF` from `dc_contact_get_verifier_id()` for directly verified contacts. +- Deprecate `dc_contact_get_verifier_addr`. +- python: use `dc_contact_get_verifier_id()`. `get_verifier()` returns a Contact rather than an address now. +- Deprecate `get_next_media()`. +- Ignore public key argument in `dc_preconfigure_keypair()`. Public key is extracted from the private key. + +### Fixes + +- Wrap base64-encoded parts to 76 characters. +- Require valid email addresses in `dc_provider_new_from_email[_with_dns]`. +- Do not trash messages with attachments and no text when `location.kml` is attached ([#4749](https://github.com/chatmail/core/issues/4749)). +- Initialise `last_msg_id` to the highest known row id. This ensures bots migrated from older version to `dc_get_next_msgs()` API do not process all previous messages from scratch. +- Do not put the status footer into reaction MIME parts. +- Ignore special chats in `get_similar_chat_ids()`. This prevents trash chat from showing up in similar chat list ([#4756](https://github.com/chatmail/core/issues/4756)). +- Cap percentage in connectivity layout to 100% ([#4765](https://github.com/chatmail/core/pull/4765)). +- Add Let's Encrypt root certificate to `reqwest`. This should allow scanning `DCACCOUNT` QR-codes on older Android phones when the server has a Let's Encrypt certificate. +- deltachat-rpc-client: Increase stdio buffer to 64 MiB to avoid Python bots crashing when trying to load large messages via a JSON-RPC call. +- Add `protected-headers` directive to Content-Type of encrypted messages with attachments ([#2302](https://github.com/chatmail/core/issues/2302)). This makes Thunderbird show encrypted Subject for Delta Chat messages. +- webxdc: Reset `document.update` on forwarding. This fixes the test `test_forward_webxdc_instance()`. + +### Features / Changes + +- Remove extra members from the local list in sake of group membership consistency ([#3782](https://github.com/chatmail/core/issues/3782)). +- deltachat-rpc-client: Log exceptions when long-running tasks die. + +### Build + +- Build wheels for Python 3.12 and PyPy 3.10. + +## [1.123.0] - 2023-09-22 + +### API-Changes + +- Make it possible to import secret key from a file with `DC_IMEX_IMPORT_SELF_KEYS`. +- [**breaking**] Make `dc_jsonrpc_blocking_call` accept JSON-RPC request. + +### Fixes + +- `lookup_chat_by_reply()`: Skip not fully downloaded and undecipherable messages ([#4676](https://github.com/chatmail/core/pull/4676)). +- `lookup_chat_by_reply()`: Skip undecipherable parent messages created by older versions ([#4676](https://github.com/chatmail/core/pull/4676)). +- imex: Use "default" in the filename of the default key. + +### Miscellaneous Tasks + +- Update OpenSSL from 3.1.2 to 3.1.3. + +## [1.122.0] - 2023-09-12 + +### API-Changes + +- jsonrpc: Return only chat IDs for similar chats. + +### Fixes + +- Reopen all connections on database passpharse change. +- Do not block new group chats if 1:1 chat is blocked. +- Improve group membership consistency algorithm ([#3782](https://github.com/chatmail/core/pull/3782))([#4624](https://github.com/chatmail/core/pull/4624)). +- Forbid membership changes from possible non-members ([#3782](https://github.com/chatmail/core/pull/3782)). +- `ChatId::parent_query()`: Don't filter out OutPending and OutFailed messages. + +### Build system + +- Update to OpenSSL 3.0. +- Bump webpki from 0.22.0 to 0.22.1. +- python: Add link to Mastodon into projects.urls. + +### Features / Changes + +- Add RSA-4096 key generation support. + +### Refactor + +- pgp: Add constants for encryption algorithm and hash. + +## [1.121.0] - 2023-09-06 + +### API-Changes + +- Add `dc_context_change_passphrase()`. +- Add `Message.set_file_from_bytes()` API. +- Add experimental API to get similar chats. + +### Build system + +- Build node packages on Ubuntu 18.04 instead of Debian 10. + This reduces the requirement for glibc version from 2.28 to 2.27. + +### Fixes + +- Allow membership changes by a MUA if we're not in the group ([#4624](https://github.com/chatmail/core/pull/4624)). +- Save mime headers for messages not signed with a known key ([#4557](https://github.com/chatmail/core/pull/4557)). +- Return from `dc_get_chatlist(DC_GCL_FOR_FORWARDING)` only chats where we can send ([#4616](https://github.com/chatmail/core/pull/4616)). +- Do not allow dots at the end of email addresses. +- deltachat-rpc-client: Remove `aiodns` optional dependency from required dependencies. + `aiodns` depends on `pycares` which [fails to install in Termux](https://github.com/saghul/aiodns/issues/98). + +## [1.120.0] - 2023-08-28 + +### API-Changes + +- jsonrpc: Add `resend_messages`. + +### Fixes + +- Update async-imap to 0.9.1 to fix memory leak. +- Delete messages from SMTP queue only on user demand ([#4579](https://github.com/chatmail/core/pull/4579)). +- Do not send images without transparency as stickers ([#4611](https://github.com/chatmail/core/pull/4611)). +- `prepare_msg_blob()`: do not use the image if it has Exif metadata but the image cannot be recoded. + +### Refactor + +- Hide accounts.rs constants from public API. +- Hide pgp module from public API. + +### Build system + +- Update to Zig 0.11.0. +- Update to Rust 1.72.0. + +### CI + +- Run on push to stable branch. + +### Miscellaneous Tasks + +- python: Fix lint errors. +- python: Fix `ruff` 0.0.286 warnings. +- Fix beta clippy warnings. + +## [1.119.1] - 2023-08-06 + +Bugfix release attempting to fix the [iOS build error](https://github.com/chatmail/core/issues/4610). + +### Features / Changes + +- Guess message viewtype from "application/octet-stream" attachment extension ([#4378](https://github.com/chatmail/core/pull/4378)). + +### Fixes + +- Update `xattr` from 1.0.0 to 1.0.1 to fix UnsupportedPlatformError import. + +### Tests + +- webxdc: Ensure unknown WebXDC update properties do not result in an error. + +## [1.119.0] - 2023-08-03 + +### Fixes + +- imap: Avoid IMAP move loops when DeltaChat folder is aliased. +- imap: Do not resync IMAP after initial configuration. + +- webxdc: Accept WebXDC updates in mailing lists. +- webxdc: Base64-encode WebXDC updates to prevent corruption of large unencrypted WebXDC updates. +- webxdc: Delete old webxdc status updates during housekeeping. + +- Return valid MsgId from `receive_imf()` when the message is replaced. +- Emit MsgsChanged event with correct chat id for replaced messages. + +- deltachat-rpc-server: Update tokio-tar to fix backup import. + +### Features / Changes + +- deltachat-rpc-client: Add `MSG_DELETED` constant. +- Make `dc_msg_get_filename()` return the original attachment filename ([#4309](https://github.com/chatmail/core/pull/4309)). + +### API-Changes + +- deltachat-rpc-client: Add `Account.{import,export}_backup` methods. +- deltachat-jsonrpc: Make `MessageObject.text` non-optional. + +### Documentation + +- Update default value for `show_emails` in `dc_set_config()` documentation. + +### Refactor + +- Improve IMAP logs. + +### Tests + +- Add basic import/export test for async python. +- Add `test_webxdc_download_on_demand`. +- Add tests for deletion of webxdc status-updates. + +## [1.118.0] - 2023-07-07 + +### API-Changes + +- [**breaking**] Remove `Contact::load_from_db()` in favor of `Contact::get_by_id()`. +- Add `Contact::get_by_id_optional()` API. +- [**breaking**] Make `Message.text` non-optional. +- [**breaking**] Replace `message::get_msg_info()` with `MsgId.get_info()`. +- Move `handle_mdn` and `handle_ndn` to mimeparser and make them private. + Previously `handle_mdn` was erroneously exposed in the public API. +- python: flatten the API of `deltachat` module. + +### Fixes + +- Use different member added/removal messages locally and on the network. +- Update tokio to 1.29.1 to fix core panic after sending 29 offline messages ([#4414](https://github.com/chatmail/core/issues/4414)). +- Make SVG avatar image work on more platforms (use `xlink:href`). +- Preserve indentation when converting plaintext to HTML. +- Do not run simplify() on dehtml() output. +- Rewrite member added/removed messages even if the change is not allowed PR ([#4529](https://github.com/chatmail/core/pull/4529)). + +### Documentation + +- Document how to regenerate Node.js constants before the release. + +### Build system + +- git-cliff: Do not fail if commit.footers is undefined. + +### Other + +- Dependency updates. +- Update MPL 2.0 license text. +- Add LICENSE file to deltachat-rpc-client. +- deltachat-rpc-client: Add Trove classifiers. +- python: Change bindings status to production/stable. + +### Tests + +- Add `make-python-testenv.sh` script. + +## [1.117.0] - 2023-06-15 + +### Features + +- New group membership update algorithm. + + New algorithm improves group consistency + in cases of missing messages, + restored old backups and replies from classic MUAs. + +- Add `DC_EVENT_MSG_DELETED` event. + + This event notifies the UI about the message + being deleted from the messagelist, e.g. when the message expires + or the user deletes it. + +### Fixes + +- Emit `DC_EVENT_MSGS_CHANGED` without IDs when the message expires. + + Specifying msg IDs that cannot be loaded in the event payload + results in an error when the UI tries to load the message. + Instead, emit an event without IDs + to make the UI reload the whole messagelist. + +- Ignore address case when comparing the `To:` field to `Autocrypt-Gossip:`. + + This bug resulted in failure to propagate verification + if the contact list already contained a new verified group member + with a non-lowercase address. + +- dehtml: skip links with empty text. + + Links like `` in HTML mails are now skipped + instead of being converted to a link without a label like `[](https://delta.chat/)`. + +- dehtml: Do not insert unnecessary newlines when parsing `

` tags. + +- Update from yanked `libc` 0.2.145 to 0.2.146. +- Update to async-imap 0.9.0 to remove deprecated `ouroboros` dependency. + +### API-Changes + +- Emit `DC_EVENT_MSGS_CHANGED` per chat when messages are deleted. + + Previously a single event with zero chat ID was emitted. + +- python: make `Contact.is_verified()` return bool. + +- rust: add API endpoint `get_status_update` ([#4468](https://github.com/chatmail/core/pull/4468)). + +- rust: make `WebxdcManifest` type public. + +### Build system + +- Use Rust 1.70.0 to compile deltachat-rpc-server releases. +- Disable unused `brotli` feature `ffi-api` and use 1 codegen-units for release builds to reduce the size of the binaries. + +### CI + +- Run `cargo check` with musl libc. +- concourse: Install devpi in a virtual environment. +- Remove [mergeable](https://mergeable.us/) configuration. + +### Documentation + +- README: mark napi.rs bindings as experimental. CFFI bindings are not legacy and are the recommended Node.js bindings currently. +- CONTRIBUTING: document how conventional commits interact with squash merges. + +### Refactor + +- Rename `MimeMessage.header` into `MimeMessage.headers`. + +- Derive `Default` trait for `WebxdcManifest`. + +### Tests + +- Regression test for case-sensitive comparison of gossip header to contact address. +- Multiple new group consistency tests in Rust. +- python: Replace legacy `tmpdir` fixture with `tmp_path`. + +## [1.116.0] - 2023-06-05 + +### API-Changes + +- Add `dc_jsonrpc_blocking_call()`. + +### Changes + +- Generate OpenRPC definitions for JSON-RPC. +- Add more context to message loading errors. + +### Fixes + +- Build deltachat-node prebuilds on Debian 10. + +### Documentation + +- Document release process in `RELEASE.md`. +- Add contributing guidelines `CONTRIBUTING.md`. +- Update instructions for python devenv. +- python: Document pytest fixtures. + +### Tests + +- python: Make `test_mdn_asymmetric` less flaky. +- Make `test_group_with_removed_message_id` less flaky. +- Add golden tests infrastructure ([#4395](https://github.com/chatmail/core/pull/4395)). + +### Build system + +- git-cliff: Changelog generation improvements. +- `set_core_version.py`: Expect release date in the changelog. + +### CI + +- Require Python 3.8 for deltachat-rpc-client. +- mergeable: Allow PR titles to start with "ci" and "build". +- Remove incorrect comment. +- dependabot: Use `chore` prefix for dependency updates. +- Remove broken `node-delete-preview.yml` workflow. +- Add top comments to GH Actions workflows. +- Run node.js lint on Windows. +- Update clippy to 1.70.0. + +### Miscellaneous Tasks + +- Remove release.toml. +- gitattributes: Configure LF line endings for JavaScript files. +- Update dependencies + +## [1.112.10] - 2023-06-01 + +### Fixes + +- Disable `fetch_existing_msgs` setting by default. +- Update `h2` to fix RUSTSEC-2023-0034. + +## [1.115.0] - 2023-05-12 + +### JSON-RPC API Changes + +- Sort reactions in descending order ([#4388](https://github.com/chatmail/core/pull/4388)). +- Add API to get reactions outside the message snapshot. +- `get_chatlist_items_by_entries` now takes only chatids instead of `ChatListEntries`. +- `get_chatlist_entries` now returns `Vec` of chatids instead of `ChatListEntries`. +- `JSONRPCReactions.reactions` is now a `Vec` with unique reactions and their count, sorted in descending order. +- `Event`: `context_id` property is now called `contextId`. +- Expand `MessageSearchResult`: + - Always include `chat_name`(not an option anymore). + - Add `author_id`, `chat_type`, `chat_color`, `is_chat_protected`, `is_chat_contact_request`, `is_chat_archived`. + - `author_name` now contains the overridden sender name. +- `ChatListItemFetchResult` gets new properties: `summary_preview_image`, `last_message_type` and `last_message_id` +- New `MessageReadReceipt` type and `get_message_read_receipts(account_id, message_id)` jsonrpc method. + +### API Changes + +- New rust API `send_webxdc_status_update_struct` to send a `StatusUpdateItem`. +- Add `get_msg_read_receipts(context, msg_id)` - get the contacts that send read receipts for a message. + +### Features / Changes + +- Build deltachat-rpc-server releases for x86\_64 macOS. +- Generate changelogs using git-cliff ([#4393](https://github.com/chatmail/core/pull/4393), [#4396](https://github.com/chatmail/core/pull/4396)). +- Improve SMTP logging. +- Do not cut incoming text if "bot" config is set. + +### Fixes + +- JSON-RPC: typescript client: fix types of events in event emitter ([#4373](https://github.com/chatmail/core/pull/4373)). +- Fetch at most 100 existing messages even if EXISTS was not received ([#4383](https://github.com/chatmail/core/pull/4383)). +- Don't put a double dot at the end of error messages ([#4398](https://github.com/chatmail/core/pull/4398)). +- Recreate `smtp` table with AUTOINCREMENT `id` ([#4390](https://github.com/chatmail/core/pull/4390)). +- Do not return an error from `send_msg_to_smtp` if retry limit is exceeded. +- Make the bots automatically accept group chat contact requests ([#4377](https://github.com/chatmail/core/pull/4377)). +- Delete `smtp` rows when message sending is canceled ([#4391](https://github.com/chatmail/core/pull/4391)). + +### Refactor + +- Iterate over `msg_ids` without .iter(). + +## [1.112.9] - 2023-05-12 + +### Fixes + +- Fetch at most 100 existing messages even if EXISTS was not received. +- Delete `smtp` rows when message sending is canceled. + +### Changes + +- Improve SMTP logging. + +## [1.114.0] - 2023-04-24 + +### Changes +- JSON-RPC: Use long polling instead of server-sent notifications to retrieve events. + This better corresponds to JSON-RPC 2.0 server-client distinction + and is expected to simplify writing new bindings + because dispatching events can be done on higher level. +- JSON-RPC: TS: Client now has a mandatory argument whether you want to start listening for events. + +### Fixes +- JSON-RPC: do not print to stdout on failure to find an account. + + +## [1.113.0] - 2023-04-18 + +### Added +- New JSON-RPC API `can_send()`. +- New `dc_get_next_msgs()` and `dc_wait_next_msgs()` C APIs. + New `get_next_msgs()` and `wait_next_msgs()` JSON-RPC API. + These APIs can be used by bots to get all unprocessed messages + in the order of their arrival and wait for them without relying on events. +- New Python bindings API `Account.wait_next_incoming_message()`. +- New Python bindings APIs `Message.is_from_self()` and `Message.is_from_device()`. + +### Changes +- Increase MSRV to 1.65.0. #4236 +- Remove upper limit on the attachment size. #4253 +- Update rPGP to 0.10.1. #4236 +- Compress HTML emails stored in the `mime_headers` column of the database. +- Strip BIDI characters in system messages, files, group names and contact names. #3479 +- Use release date instead of the provider database update date in `maybe_add_time_based_warnings()`. +- Gracefully terminate `deltachat-rpc-server` on Ctrl+C (`SIGINT`), `SIGTERM` and EOF. +- Async Python API `get_fresh_messages_in_arrival_order()` is deprecated + in favor of `get_next_msgs()` and `wait_next_msgs()`. +- Remove metadata from avatars and JPEG images before sending. #4037 +- Recode PNG and other supported image formats to JPEG if they are > 500K in size. #4037 + +### Fixes +- Don't let blocking be bypassed using groups. #4316 +- Show a warning if quota list is empty. #4261 +- Do not reset status on other devices when sending signed reaction messages. #3692 +- Update `accounts.toml` atomically. +- Fix python bindings README documentation on installing the bindings from source. +- Remove confusing log line "ignoring unsolicited response Recent(…)". #3934 + +## [1.112.8] - 2023-04-20 + +### Changes +- Add `get_http_response` JSON-RPC API. +- Add C API to get HTTP responses. + +## [1.112.7] - 2023-04-17 + +### Fixes + +- Updated `async-imap` to v0.8.0 to fix erroneous EOF detection in long IMAP responses. + +## [1.112.6] - 2023-04-04 + +### Changes + +- Add a device message after backup transfer #4301 + +### Fixed + +- Updated `iroh` from 0.4.0 to 0.4.1 to fix transfer of large accounts with many blob files. + +## [1.112.5] - 2023-04-02 + +### Fixes + +- Run SQL database migrations after receiving a backup from the network. #4287 + +## [1.112.4] - 2023-03-31 + +### Fixes +- Fix call to `auditwheel` in `scripts/run_all.sh`. + +## [1.112.3] - 2023-03-30 + +### Fixes +- `transfer::get_backup` now frees ongoing process when canceled. #4249 + +## [1.112.2] - 2023-03-30 + +### Changes +- Update iroh, remove `default-net` from `[patch.crates-io]` section. +- transfer backup: Connect to multiple provider addresses concurrently. This should speed up connection time significantly on the getter side. #4240 +- Make sure BackupProvider is canceled on drop (or `dc_backup_provider_unref`). The BackupProvider will now always finish with an IMEX event of 1000 or 0, previously it would sometimes finished with 1000 (success) when it really was 0 (failure). #4242 + +### Fixes +- Do not return media from trashed messages in the "All media" view. #4247 + +## [1.112.1] - 2023-03-27 + +### Changes +- Add support for `--version` argument to `deltachat-rpc-server`. #4224 + It can be used to check the installed version without starting the server. + +### Fixes +- deltachat-rpc-client: fix bug in `Chat.send_message()`: invalid `MessageData` field `quotedMsg` instead of `quotedMsgId` +- `receive_imf`: Mark special messages as seen. Exactly: delivery reports, webxdc status updates. #4230 + + +## [1.112.0] - 2023-03-23 + +### Changes +- Increase MSRV to 1.64. #4167 +- Core takes care of stopping and re-starting IO itself where needed, + e.g. during backup creation. + It is no longer needed to call `dc_stop_io()`. + `dc_start_io()` can now be called at any time without harm. #4138 +- Pick up system's light/dark mode in generated message HTML. #4150 +- More accurate `maybe_add_bcc_self` device message text. #4175 +- "Full message view" not needed because of footers that go to contact status. #4151 +- Support non-persistent configuration with `DELTACHAT_*` env. #4154 +- Print deltachat-repl errors with causes. #4166 + +### Fixes +- Fix segmentation fault if `dc_context_unref()` is called during + background process spawned by `dc_configure()` or `dc_imex()` + or `dc_jsonrpc_instance_t` is unreferenced + during handling the JSON-RPC request. #4153 +- Delete expired messages using multiple SQL requests. #4158 +- Do not emit "Failed to run incremental vacuum" warnings on success. #4160 +- Ability to send backup over network and QR code to setup second device #4007 +- Disable buffering during STARTTLS setup. #4190 +- Add `DC_EVENT_IMAP_INBOX_IDLE` event to wait until the account + is ready for testing. + It is used to fix race condition between fetching + existing messages and starting the test. #4208 + + +## [1.111.0] - 2023-03-05 + +### Changes +- Make smeared timestamp generation non-async. #4075 +- Set minimum TLS version to 1.2. #4096 +- Run `cargo-deny` in CI. #4101 +- Check provider database with CI. #4099 +- Switch to DEFERRED transactions #4100 + +### Fixes +- Do not block async task executor while decrypting the messages. #4079 +- Housekeeping: delete the blobs backup dir #4123 + +### API-Changes +- jsonrpc: add more advanced API to send a message. #4097 +- jsonrpc: add get webxdc blob API `getWebxdcBlob` #4070 + + +## 1.110.0 + +### Changes +- use transaction in `Contact::add_or_lookup()` #4059 +- Organize the connection pool as a stack rather than a queue to ensure that + connection page cache is reused more often. + This speeds up tests by 28%, real usage will have lower speedup. #4065 +- Use transaction in `update_blocked_mailinglist_contacts`. #4058 +- Remove `Sql.get_conn()` interface in favor of `.call()` and `.transaction()`. #4055 +- Updated provider database. +- Disable DKIM-Checks again #4076 +- Switch from "X.Y.Z" and "py-X.Y.Z" to "vX.Y.Z" tags. #4089 +- mimeparser: handle headers from the signed part of unencrypted signed message #4013 + +### Fixes +- Start SQL transactions with IMMEDIATE behaviour rather than default DEFERRED one. #4063 +- Fix a problem with Gmail where (auto-)deleted messages would get archived instead of deleted. + Move them to the Trash folder for Gmail which auto-deletes trashed messages in 30 days #3972 +- Clear config cache after backup import. This bug sometimes resulted in the import to seemingly work at first. #4067 +- Update timestamps in `param` columns with transactions. #4083 + +### API-Changes + + +## 1.109.0 + +### Changes +- deltachat-rpc-client: use `dataclass` for `Account`, `Chat`, `Contact` and `Message` #4042 + +### Fixes +- deltachat-rpc-server: do not block stdin while processing the request. #4041 + deltachat-rpc-server now reads the next request as soon as previous request handler is spawned. +- Enable `auto_vacuum` on all SQL connections. #2955 +- Replace `r2d2` connection pool with an own implementation. #4050 #4053 #4043 #4061 + This change improves reliability + by closing all database connections immediately when the context is closed. + +### API-Changes + +- Remove `MimeMessage::from_bytes()` public interface. #4033 +- BREAKING Types: jsonrpc: `get_messages` now returns a map with `MessageLoadResult` instead of failing completely if one of the requested messages could not be loaded. #4038 +- Add `dc_msg_set_subject()`. C-FFI #4057 +- Mark python bindings as supporting typing according to PEP 561 #4045 + + +## 1.108.0 + +### Changes +- Use read/write timeouts instead of per-command timeouts for SMTP #3985 +- Cache DNS results for SMTP connections #3985 +- Prefer TLS over STARTTLS during autoconfiguration #4021 +- Use SOCKS5 configuration for HTTP requests #4017 +- Show non-deltachat emails by default for new installations #4019 +- Re-enabled SMTP pipelining after disabling it in #4006 + +### Fixes +- Fix Securejoin for multiple devices on a joining side #3982 +- python: handle NULL value returned from `dc_get_msg()` #4020 + Account.`get_message_by_id` may return `None` in this case. + +### API-Changes +- Remove bitflags from `get_chat_msgs()` interface #4022 + C interface is not changed. + Rust and JSON-RPC API have `flags` integer argument + replaced with two boolean flags `info_only` and `add_daymarker`. +- jsonrpc: add API to check if the message is sent by a bot #3877 + + +## 1.107.1 + +### Changes +- Log server security (TLS/STARTTLS/plain) type #4005 + +### Fixes +- Disable SMTP pipelining #4006 + + +## 1.107.0 + +### Changes +- Pipeline SMTP commands #3924 +- Cache DNS results for IMAP connections #3970 + +### Fixes +- Securejoin: Fix adding and handling Autocrypt-Gossip headers #3914 +- fix verifier-by addr was empty string instead of None #3961 +- Emit DC_EVENT_MSGS_CHANGED for DC_CHAT_ID_ARCHIVED_LINK when the number of archived chats with + unread messages increases #3959 +- Fix Peerstate comparison #3962 +- Log SOCKS5 configuration for IMAP like already done for SMTP #3964 +- Fix SOCKS5 usage for IMAP #3965 +- Exit from recently seen loop on interrupt channel errors to avoid busy looping #3966 + +### API-Changes +- jsonrpc: add verified-by information to `Contact`-Object +- Remove `attach_selfavatar` config #3951 + +### Changes +- add debug logging support for webxdcs #3296 + +## 1.106.0 + +### Changes +- Only send IncomingMsgBunch if there are more than 0 new messages #3941 + +### Fixes +- fix: only send contact changed event for recently seen if it is relevant (not too old to matter) #3938 +- Immediately save `accounts.toml` if it was modified by a migration from absolute paths to relative paths #3943 +- Do not treat invalid email addresses as an exception #3942 +- Add timeouts to HTTP requests #3948 + +## 1.105.0 + +### Changes +- Validate signatures in try_decrypt() even if the message isn't encrypted #3859 +- Don't parse the message again after detached signatures validation #3862 +- Move format=flowed support to a separate crate #3869 +- cargo: bump quick-xml from 0.23.0 to 0.26.0 #3722 +- Add fuzzing tests #3853 +- Add mappings for some file types to Viewtype / MIME type #3881 +- Buffer IMAP client writes #3888 +- move `DC_CHAT_ID_ARCHIVED_LINK` to the top of chat lists + and make `dc_get_fresh_msg_cnt()` work for `DC_CHAT_ID_ARCHIVED_LINK` #3918 +- make `dc_marknoticed_chat()` work for `DC_CHAT_ID_ARCHIVED_LINK` #3919 +- Update provider database + +### API-Changes +- jsonrpc: add python API for webxdc updates #3872 +- jsonrpc: add fresh message count to ChatListItemFetchResult::ArchiveLink +- Add ffi functions to retrieve `verified by` information #3786 +- resultify `Message::get_filebytes()` #3925 + +### Fixes +- Do not add an error if the message is encrypted but not signed #3860 +- Do not strip leading spaces from message lines #3867 +- Fix uncaught exception in JSON-RPC tests #3884 +- Fix STARTTLS connection and add a test for it #3907 +- Trigger reconnection when failing to fetch existing messages #3911 +- Do not retry fetching existing messages after failure, prevents infinite reconnection loop #3913 +- Ensure format=flowed formatting is always reversible on the receiver side #3880 + + +## 1.104.0 + +### Changes +- Don't use deprecated `chrono` functions #3798 +- Document accounts manager #3837 +- If a classical-email-user sends an email to a group and adds new recipients, + add the new recipients as group members #3781 +- Remove `pytest-async` plugin #3846 +- Only send the message about ephemeral timer change if the chat is promoted #3847 +- Use relative paths in `accounts.toml` #3838 + +### Fixes +- Set read/write timeouts for IMAP over SOCKS5 #3833 +- Treat attached PGP keys as peer keys with mutual encryption preference #3832 +- fix migration of old databases #3842 +- Fix cargo clippy and doc errors after Rust update to 1.66 #3850 +- Don't send GroupNameChanged message if the group name doesn't change in terms of + `improve_single_line_input()` #3852 +- Prefer encryption for the peer if the message is encrypted or signed with the known key #3849 + + +## 1.103.0 + +### Changes +- Disable Autocrypt & Authres-checking for mailing lists, + because they don't work well with mailing lists #3765 +- Refactor: Remove the remaining AsRef #3669 +- Add more logging to `fetch_many_msgs` and refactor it #3811 +- Small speedup #3780 +- Log the reason when the message cannot be sent to the chat #3810 +- Add IMAP server ID line to the context info only when it is known #3814 +- Remove autogenerated typescript files #3815 +- Move functions that require an IMAP session from `Imap` to `Session` + to reduce the number of code paths where IMAP session may not exist. + Drop connection on error instead of trying to disconnect, + potentially preventing IMAP task from getting stuck. #3812 + +### API-Changes +- Add Python API to send reactions #3762 +- jsonrpc: add message errors to MessageObject #3788 +- jsonrpc: Add async Python client #3734 + +### Fixes +- Make sure malformed messages will never block receiving further messages anymore #3771 +- strip leading/trailing whitespace from "Chat-Group-Name{,-Changed}:" headers content #3650 +- Assume all Thunderbird users prefer encryption #3774 +- refactor peerstate handling to ensure no duplicate peerstates #3776 +- Fetch messages in order of their INTERNALDATE (fixes reactions for Gmail f.e.) #3789 +- python: do not pass NULL to ffi.gc if the context can't be created #3818 +- Add read/write timeouts to IMAP sockets #3820 +- Add connection timeout to IMAP sockets #3828 +- Disable read timeout during IMAP IDLE #3826 +- Bots automatically accept mailing lists #3831 + +## 1.102.0 + +### Changes + +- If an email has multiple From addresses, handle this as if there was + no From address, to prevent from forgery attacks. Also, improve + handling of emails with invalid From addresses in general #3667 + +### API-Changes + +### Fixes +- fix detection of "All mail", "Trash", "Junk" etc folders. #3760 +- fetch messages sequentially to fix reactions on partially downloaded messages #3688 +- Fix a bug where one malformed message blocked receiving any further messages #3769 + + +## 1.101.0 + +### Changes +- add `configured_inbox_folder` to account info #3748 +- `dc_delete_contact()` hides contacts if referenced #3751 +- add IMAP UIDs to message info #3755 + +### Fixes +- improve IMAP logging, in particular fix incorrect "IMAP IDLE protocol + timed out" message on network error during IDLE #3749 +- pop Recently Seen Loop event out of the queue when it is in the past + to avoid busy looping #3753 +- fix build failures by going back to standard `async_zip` #3747 + + +## 1.100.0 + +### API-Changes +- jsonrpc: add `miscSaveSticker` method + +### Changes +- add JSON-RPC stdio server `deltachat-rpc-server` and use it for JSON-RPC tests #3695 +- update rPGP from 0.8 to 0.9 #3737 +- jsonrpc: typescript client: use npm released deltachat fork of the tiny emitter package #3741 +- jsonrpc: show sticker image in quote #3744 + + + +## 1.99.0 + +### API-Changes +- breaking jsonrpc: changed function naming + - `autocryptInitiateKeyTransfer` -> `initiateAutocryptKeyTransfer` + - `autocryptContinueKeyTransfer` -> `continueAutocryptKeyTransfer` + - `chatlistGetFullChatById` -> `getFullChatById` + - `messageGetMessage` -> `getMessage` + - `messageGetMessages` -> `getMessages` + - `messageGetNotificationInfo` -> `getMessageNotificationInfo` + - `contactsGetContact` -> `getContact` + - `contactsCreateContact` -> `createContact` + - `contactsCreateChatByContactId` -> `createChatByContactId` + - `contactsBlock` -> `blockContact` + - `contactsUnblock` -> `unblockContact` + - `contactsGetBlocked` -> `getBlockedContacts` + - `contactsGetContactIds` -> `getContactIds` + - `contactsGetContacts` -> `getContacts` + - `contactsGetContactsByIds` -> `getContactsByIds` + - `chatGetMedia` -> `getChatMedia` + - `chatGetNeighboringMedia` -> `getNeighboringChatMedia` + - `webxdcSendStatusUpdate` -> `sendWebxdcStatusUpdate` + - `webxdcGetStatusUpdates` -> `getWebxdcStatusUpdates` + - `messageGetWebxdcInfo` -> `getWebxdcInfo` +- jsonrpc: changed method signature + - `miscSendTextMessage(accountId, text, chatId)` -> `miscSendTextMessage(accountId, chatId, text)` +- jsonrpc: add `SystemMessageType` to `Message` +- cffi: add missing `DC_INFO_` constants +- Add DC_EVENT_INCOMING_MSG_BUNCH event #3643 +- Python bindings: Make get_matching() only match the + whole event name, e.g. events.get_matching("DC_EVENT_INCOMING_MSG") + won't match DC_EVENT_INCOMING_MSG_BUNCH anymore #3643 + + +- Rust: Introduce a ContextBuilder #3698 + +### Changes +- allow sender timestamp to be in the future, but not too much +- Disable the new "Authentication-Results/DKIM checking" security feature + until we have tested it a bit #3728 +- refactorings #3706 + +### Fixes +- `dc_search_msgs()` returns unaccepted requests #3694 +- emit "contacts changed" event when the contact is no longer "seen recently" #3703 +- do not allow peerstate reset if DKIM check failed #3731 + + +## 1.98.0 + +### API-Changes +- jsonrpc: typescript client: export constants under `C` enum, similar to how its exported from `deltachat-node` #3681 +- added reactions support #3644 +- jsonrpc: reactions: added reactions to `Message` type and the `sendReaction()` method #3686 + +### Changes +- simplify `UPSERT` queries #3676 + +### Fixes + + +## 1.97.0 + +### API-Changes +- jsonrpc: add function: #3641, #3645, #3653 + - `getChatContacts()` + - `createGroupChat()` + - `createBroadcastList()` + - `setChatName()` + - `setChatProfileImage()` + - `downloadFullMessage()` + - `lookupContactIdByAddr()` + - `sendVideochatInvitation()` + - `searchMessages()` + - `messageIdsToSearchResults()` + - `setChatVisibility()` + - `getChatEphemeralTimer()` + - `setChatEphemeralTimer()` + - `getLocations()` + - `getAccountFileSize()` + - `estimateAutoDeletionCount()` + - `setStockStrings()` + - `exportSelfKeys()` + - `importSelfKeys()` + - `sendSticker()` + - `changeContactName()` + - `deleteContact()` + - `joinSecurejoin()` + - `stopIoForAllAccounts()` + - `startIoForAllAccounts()` + - `startIo()` + - `stopIo()` + - `exportBackup()` + - `importBackup()` + - `getMessageHtml()` #3671 + - `miscGetStickerFolder` and `miscGetStickers` #3672 +- breaking: jsonrpc: remove function `messageListGetMessageIds()`, it is replaced by `getMessageIds()` and `getMessageListItems()` the latter returns a new `MessageListItem` type, which is the now preferred way of using the message list. +- jsonrpc: add type: #3641, #3645 + - `MessageSearchResult` + - `Location` +- jsonrpc: add `viewType` to quoted message(`MessageQuote` type) in `Message` object type #3651 + + +### Changes +- Look at Authentication-Results. Don't accept Autocrypt key changes + if they come with negative authentication results while this contact + sent emails with positive authentication results in the past. #3583 +- jsonrpc in cffi also sends events now #3662 +- jsonrpc: new format for events and better typescript autocompletion +- Join all "[migration] vXX" log messages into one + +### Fixes +- share stock string translations across accounts created by the same account manager #3640 +- suppress welcome device messages after account import #3642 +- fix unix timestamp used for daymarker #3660 + +## 1.96.0 + +### Changes +- jsonrpc js client: + - Change package name from `deltachat-jsonrpc-client` to `@deltachat/jsonrpc-client` + - remove relative file dependency to it from `deltachat-node` (because it did not work anyway and broke the nix build of desktop) + - ci: add github ci action to upload it to our download server automatically on release + +## 1.95.0 + +### API-Changes +- jsonrpc: add `mailingListAddress` property to `FullChat` #3607 +- jsonrpc: add `MessageNotificationInfo` & `messageGetNotificationInfo()` #3614 +- jsonrpc: add `chat_get_neighboring_media` function #3610 + +### Changes +- added `dclogin:` scheme to allow configuration from a qr code + (data inside qrcode, contrary to `dcaccount:` which points to an API to create an account) #3541 +- truncate incoming messages by lines instead of just length #3480 +- emit separate `DC_EVENT_MSGS_CHANGED` for each expired message, + and `DC_EVENT_WEBXDC_INSTANCE_DELETED` when a message contains a webxdc #3605 +- enable `bcc_self` by default #3612 + + +## 1.94.0 + +### API-Changes +- breaking change: replace `dc_accounts_event_emitter_t` with `dc_event_emitter_t` #3422 + + Type `dc_accounts_event_emitter_t` is removed. + `dc_accounts_get_event_emitter()` returns `dc_event_emitter_t` now, so + `dc_get_next_event()` should be used instead of `dc_accounts_get_next_event` + and `dc_event_emitter_unref()` should be used instead of + `dc_accounts_event_emitter_unref`. +- add `dc_contact_was_seen_recently()` #3560 +- Fix `get_connectivity_html` and `get_encrinfo` futures not being Send. See rust-lang/rust#101650 for more information +- jsonrpc: add functions: #3586, #3587, #3590 + - `deleteChat()` + - `getChatEncryptionInfo()` + - `getChatSecurejoinQrCodeSvg()` + - `leaveGroup()` + - `removeContactFromChat()` + - `addContactToChat()` + - `deleteMessages()` + - `getMessageInfo()` + - `getBasicChatInfo()` + - `marknoticedChat()` + - `getFirstUnreadMessageOfChat()` + - `markseenMsgs()` + - `forwardMessages()` + - `removeDraft()` + - `getDraft()` + - `miscSendMsg()` + - `miscSetDraft()` + - `maybeNetwork()` + - `getConnectivity()` + - `getContactEncryptionInfo()` + - `getConnectivityHtml()` +- jsonrpc: add `is_broadcast` property to `ChatListItemFetchResult` #3584 +- jsonrpc: add `was_seen_recently` property to `ChatListItemFetchResult`, `FullChat` and `Contact` #3584 +- jsonrpc: add `webxdc_info` property to `Message` #3588 +- python: move `get_dc_event_name()` from `deltachat` to `deltachat.events` #3564 +- jsonrpc: add `webxdc_info`, `parent_id` and `download_state` property to `Message` #3588, #3590 +- jsonrpc: add `BasicChat` object as a leaner alternative to `FullChat` #3590 +- jsonrpc: add `last_seen` property to `Contact` #3590 +- breaking! jsonrpc: replace `Message.quoted_text` and `Message.quoted_message_id` with `Message.quote` #3590 +- add separate stock strings for actions done by contacts to make them easier to translate #3518 +- `dc_initiate_key_transfer()` is non-blocking now. #3553 + UIs don't need to display a button to cancel sending Autocrypt Setup Message with + `dc_stop_ongoing_process()` anymore. + +### Changes +- order contact lists by "last seen"; + this affects `dc_get_chat_contacts()`, `dc_get_contacts()` and `dc_get_blocked_contacts()` #3562 +- add `internet_access` flag to `dc_msg_get_webxdc_info()` #3516 +- `DC_EVENT_WEBXDC_INSTANCE_DELETED` is emitted when a message containing a webxdc gets deleted #3592 + +### Fixes +- do not emit notifications for blocked chats #3557 +- Show attached .eml files correctly #3561 +- Auto accept contact requests if `Config::Bot` is set for a client #3567 +- Don't prepend the subject to chat messages in mailinglists +- fix `set_core_version.py` script to also update version in `deltachat-jsonrpc/typescript/package.json` #3585 +- Reject webxdc-updates from contacts who are not group members #3568 + + +## 1.93.0 + +### API-Changes +- added a JSON RPC API, accessible through a WebSocket server, the CFFI bindings and the Node.js bindings #3463 #3554 #3542 +- JSON RPC methods in CFFI #3463: + - `dc_jsonrpc_instance_t* dc_jsonrpc_init(dc_accounts_t* account_manager);` + - `void dc_jsonrpc_unref(dc_jsonrpc_instance_t* jsonrpc_instance);` + - `void dc_jsonrpc_request(dc_jsonrpc_instance_t* jsonrpc_instance, char* request);` + - `char* dc_jsonrpc_next_response(dc_jsonrpc_instance_t* jsonrpc_instance);` +- node: JSON RPC methods #3463: + - `AccountManager.prototype.startJsonRpcHandler(callback: ((response: string) => void)): void` + - `AccountManager.prototype.jsonRpcRequest(message: string): void` + +### Changes +- use [pathlib](https://docs.python.org/3/library/pathlib.html) in provider update script #3543 +- `dc_get_chat_media()` can return media globally #3528 +- node: add `getMailinglistAddr()` #3524 +- avoid duplicate encoded-words package and test `cargo vendor` in ci #3549 +- python: don't raise an error if addr changes #3530 +- improve coverage script #3530 + +### Fixes +- improved error handling for account setup from qrcode #3474 +- python: enable certificate checks in cloned accounts #3443 + + +## 1.92.0 + +### API-Changes +- add `dc_chat_get_mailinglist_addr()` #3520 + + +## 1.91.0 + +### Added +- python bindings: extra method to get an account running + +### Changes +- refactorings #3437 + +### Fixes +- mark "group image changed" as system message on receiver side #3517 + + +## 1.90.0 + +### Changes +- handle drafts from mailto links in scanned QR #3492 +- do not overflow ratelimiter leaky bucket #3496 +- (AEAP) Add device message after you changed your address #3505 +- (AEAP) Revert #3491, instead only replace contacts in verified groups #3510 +- improve python bindings and tests #3502 #3503 + +### Fixes +- don't squash text parts of NDN into attachments #3497 +- do not treat non-failed DSNs as NDNs #3506 + + +## 1.89.0 + +### Changes + +- (AEAP) When one of your contacts changed their address, they are + only replaced in the chat where you got a message from them + for now #3491 + +### Fixes +- replace musl libc name resolution errors with a better message #3485 +- handle updates for not yet downloaded webxdc instances #3487 + + +## 1.88.0 + +### Changes +- Implemented "Automatic e-mail address Porting" (AEAP). You can + configure a new address in DC now, and when receivers get messages + they will automatically recognize your moving to a new address. #3385 +- switch from `async-std` to `tokio` as the async runtime #3449 +- upgrade to `pgp@0.8.0` #3467 +- add IMAP ID extension support #3468 +- configure DeltaChat folder by selecting it, so it is configured even if not LISTed #3371 +- build PyPy wheels #6683 +- improve default error if NDN does not provide an error #3456 +- increase ratelimit from 3 to 6 messages per 60 seconds #3481 + +### Fixes +- mailing list: remove square-brackets only for first name #3452 +- do not use footers from mailinglists as the contact status #3460 +- don't ignore KML parsing errors #3473 + + +## 1.87.0 + +### Changes +- limit the rate of MDN sending #3402 +- ignore ratelimits for bots #3439 +- remove `msgs_mdns` references to deleted messages during housekeeping #3387 +- format message lines starting with `>` as quotes #3434 +- node: remove `split2` dependency #3418 +- node: add git installation info to readme #3418 +- limit the rate of webxdc update sending #3417 + +### Fixes +- set a default error if NDN does not provide an error #3410 +- python: avoid exceptions when messages/contacts/chats are compared with `None` +- node: wait for the event loop to stop before destroying contexts #3431 #3451 +- emit configuration errors via event on failure #3433 +- report configure and imex success/failure after freeing ongoing process #3442 + +### API-Changes +- python: added `Message.get_status_updates()` #3416 +- python: added `Message.send_status_update()` #3416 +- python: added `Message.is_webxdc()` #3416 +- python: added `Message.is_videochat_invitation()` #3416 +- python: added support for "videochat" and "webxdc" view types to `Message.new_empty()` #3416 + + +## 1.86.0 + +### API-Changes +- python: added optional `closed` parameter to `Account` constructor #3394 +- python: added optional `passphrase` parameter to `Account.export_all()` and `Account.import_all()` #3394 +- python: added `Account.open()` #3394 +- python: added `Chat.is_single()` #3394 +- python: added `Chat.is_mailinglist()` #3394 +- python: added `Chat.is_broadcast()` #3394 +- python: added `Chat.is_multiuser()` #3394 +- python: added `Chat.is_self_talk()` #3394 +- python: added `Chat.is_device_talk()` #3394 +- python: added `Chat.is_pinned()` #3394 +- python: added `Chat.pin()` #3394 +- python: added `Chat.unpin()` #3394 +- python: added `Chat.archive()` #3394 +- python: added `Chat.unarchive()` #3394 +- python: added `Message.get_summarytext()` #3394 +- python: added optional `closed` parameter to `ACFactory.get_unconfigured_account()` (pytest plugin) #3394 +- python: added optional `passphrase` parameter to `ACFactory.get_pseudo_configured_account()` (pytest plugin) #3394 + +### Changes +- clean up series of webxdc info messages; + `DC_EVENT_MSGS_CHANGED` is emitted on changes of existing info messages #3395 +- update provider database #3399 +- refactorings #3375 #3403 #3398 #3404 + +### Fixes +- do not reset our database if imported backup cannot be decrypted #3397 +- node: remove `npx` from build script, this broke flathub build #3396 + + +## 1.85.0 + +### Changes +- refactorings #3373 #3345 #3380 #3382 +- node: move split2 to devDependencies +- python: build Python 3.10 wheels #3392 +- update Rust dependencies + +### Fixes +- delete outgoing MDNs found in the Sent folder on Gmail #3372 +- fix searching one-to-one chats #3377 +- do not add legacy info-messages on resending webxdc #3389 + + +## 1.84.0 + +### Changes +- refactorings #3354 #3347 #3353 #3346 + +### Fixes +- do not unnecessarily SELECT folders if there are no operations planned on + them #3333 +- trim chat encryption info #3350 +- fix failure to decrypt first message to self after key synchronization + via Autocrypt Setup Message #3352 +- Keep pgp key when you change your own email address #3351 +- Do not ignore Sent and Spam folders on Gmail #3369 +- handle decryption errors explicitly and don't get confused by encrypted mail attachments #3374 + + +## 1.83.0 + +### Fixes +- fix node prebuild & package ci #3337 + + +## 1.82.0 + +### API-Changes +- re-add removed `DC_MSG_ID_MARKER1` as in use on iOS #3330 + +### Changes +- refactorings #3328 + +### Fixes +- fix node package ci #3331 +- fix race condition in ongoing process (import/export, configuration) allocation #3322 + + +## 1.81.0 + +### API-Changes +- deprecate unused `marker1before` argument of `dc_get_chat_msgs` + and remove `DC_MSG_ID_MARKER1` constant #3274 + +### Changes +- now the node-bindings are also part of this repository 🎉 #3283 +- support `source_code_url` from Webxdc manifests #3314 +- support Webxdc document names and add `document` to `dc_msg_get_webxdc_info()` #3317 #3324 +- improve chat encryption info, make it easier to find contacts without keys #3318 +- improve error reporting when creating a folder fails #3325 +- node: remove unmaintained coverage scripts +- send normal messages with higher priority than MDNs #3243 +- make Scheduler stateless #3302 +- abort instead of unwinding on panic #3259 +- improve python bindings #3297 #3298 +- improve documentation #3307 #3306 #3309 #3319 #3321 +- refactorings #3304 #3303 #3323 + +### Fixes +- node: throw error when getting context with an invalid account id +- node: throw error when instantiating a wrapper class on `null` (Context, Message, Chat, ChatList and so on) +- use same contact-color if email address differ only in upper-/lowercase #3327 +- repair encrypted mails "mixed up" by Google Workspace "Append footer" function #3315 + + +## 1.80.0 + +### Changes +- update provider database #3284 +- improve python bindings, tests and ci #3287 #3286 #3287 #3289 #3290 #3292 + +### Fixes +- fix escaping in generated QR-code-SVG #3295 + + +## 1.79.0 + +### Changes +- Send locations in the background regardless of SMTP loop activity #3247 +- refactorings #3268 +- improve tests and ci #3266 #3271 + +### Fixes +- simplify `dc_stop_io()` and remove potential panics and race conditions #3273 +- fix correct message escaping consisting of a dot in SMTP protocol #3265 + + +## 1.78.0 + +### API-Changes +- replaced stock string `DC_STR_ONE_MOMENT` by `DC_STR_NOT_CONNECTED` #3222 +- add `dc_resend_msgs()` #3238 +- `dc_provider_new_from_email()` does no longer do an DNS lookup for checking custom domains, + this is done by `dc_provider_new_from_email_with_dns()` now #3256 + +### Changes +- introduce multiple self addresses with the "configured" address always being the primary one #2896 +- Further improve finding the correct server after logging in #3208 +- `get_connectivity_html()` returns HTML as non-scalable #3213 +- add update-serial to `DC_EVENT_WEBXDC_STATUS_UPDATE` #3215 +- Speed up message receiving via IMAP a bit #3225 +- mark messages as seen on IMAP in batches #3223 +- remove Received: based draft detection heuristic #3230 +- Use pkgconfig for building Python package #2590 +- don't start io on unconfigured context #2664 +- do not assign group IDs to ad-hoc groups #2798 +- dynamic libraries use dylib extension on Darwin #3226 +- refactorings #3217 #3219 #3224 #3235 #3239 #3244 #3254 +- improve documentation #3214 #3220 #3237 +- improve tests and ci #3212 #3233 #3241 #3242 #3252 #3250 #3255 #3260 + +### Fixes +- Take `delete_device_after` into account when calculating ephemeral loop timeout #3211 #3221 +- Fix a bug where a blocked contact could send a contact request #3218 +- Make sure, videochat-room-names are always URL-safe #3231 +- Try removing account folder multiple times in case of failure #3229 +- Ignore messages from all spam folders if there are many #3246 +- Hide location-only messages instead of displaying empty bubbles #3248 + + +## 1.77.0 + +### API changes +- change semantics of `dc_get_webxdc_status_updates()` second parameter + and remove update-id from `DC_EVENT_WEBXDC_STATUS_UPDATE` #3081 + +### Changes +- add more SMTP logging #3093 +- place common headers like `From:` before the large `Autocrypt:` header #3079 +- keep track of securejoin joiner status in database to survive restarts #2920 +- remove never used `SentboxMove` option #3111 +- improve speed by caching config values #3131 #3145 +- optimize `markseen_msgs` #3141 +- automatically accept chats with outgoing messages #3143 +- `dc_receive_imf` refactorings #3154 #3156 #3159 +- add index to speedup deletion of expired ephemeral messages #3155 +- muted chats stay archived on new messages #3184 +- support `min_api` from Webxdc manifests #3206 +- do not read whole webxdc file into memory #3109 +- improve tests, refactorings #3073 #3096 #3102 #3108 #3139 #3128 #3133 #3142 #3153 #3151 #3174 #3170 #3148 #3179 #3185 +- improve documentation #2983 #3112 #3103 #3118 #3120 + +### Fixes +- speed up loading of chat messages by a factor of 20 #3171 #3194 #3173 +- fix an issue where the app crashes when trying to export a backup #3195 +- hopefully fix a bug where outgoing messages appear twice with Amazon SES #3077 +- do not delete messages without Message-IDs as duplicates #3095 +- assign replies from a different email address to the correct chat #3119 +- assign outgoing private replies to the correct chat #3177 +- start ephemeral timer when seen status is synchronized via IMAP #3122 +- do not create empty contact requests with "setup changed" messages; + instead, send a "setup changed" message into all chats we share with the peer #3187 +- do not delete duplicate messages on IMAP immediately to accidentally deleting + the last copy #3138 +- clear more columns when message expires due to `delete_device_after` setting #3181 +- do not try to use stale SMTP connections #3180 +- slightly improve finding the correct server after logging in #3207 +- retry message sending automatically if loop is not interrupted #3183 +- fix a bug where sometimes the file extension of a long filename containing a dot was cropped #3098 + + +## 1.76.0 + +### Changes +- move messages in batches #3058 +- delete messages in batches #3060 +- python: remove arbitrary timeouts from tests #3059 +- refactorings #3026 + +### Fixes +- avoid archived, fresh chats #3053 +- Also resync UIDs in folders that are not configured #2289 +- treat "NO" IMAP response to MOVE and COPY commands as an error #3058 +- Fix a bug where messages in the Spam folder created contact requests #3015 +- Fix a bug where drafts disappeared after some days #3067 +- Parse MS Exchange read receipts and mark the original message as read #3075 +- do not retry message sending infinitely in case of permanent SMTP failure #3070 +- set message state to failed when retry limit is exceeded #3072 + + +## 1.75.0 + +### Changes +- optimize `delete_expired_imap_messages()` #3047 + + +## 1.74.0 + +### Fixes +- avoid reconnection loop when message without Message-ID is marked as seen #3044 + + +## 1.73.0 + +### API changes +- added `only_fetch_mvbox` config #3028 + +### Changes +- don't watch Sent folder by default #3025 +- use webxdc app name in chatlist/quotes/replies etc. #3027 +- make it possible to cancel message sending by removing the message #3034, + this was previously removed in 1.71.0 #2939 +- synchronize Seen flags only on watched folders to speed up + folder scanning #3041 +- remove direct dependency on `byteorder` crate #3031 +- refactorings #3023 #3013 +- update provider database #3043 +- improve documentation #3017 #3018 #3021 + +### Fixes +- fix splitting off text from webxdc messages #3032 +- call slow `delete_expired_imap_messages()` less often #3037 +- make synchronization of Seen status more robust in case unsolicited FETCH + result without UID is returned #3022 +- fetch Inbox before scanning folders to ensure iOS does + not kill the app before it gets to fetch the Inbox in background #3040 + + +## 1.72.0 + +### Fixes +- run migrations on backup import #3006 + + +## 1.71.0 + +### API Changes +- added APIs to handle database passwords: `dc_context_new_closed()`, `dc_context_open()`, + `dc_context_is_open()` and `dc_accounts_add_closed_account()` #2956 #2972 +- use second parameter of `dc_imex` to provide backup passphrase #2980 +- added `DC_MSG_WEBXDC`, `dc_send_webxdc_status_update()`, + `dc_get_webxdc_status_updates()`, `dc_msg_get_webxdc_blob()`, `dc_msg_get_webxdc_info()` + and `DC_EVENT_WEBXDC_STATUS_UPDATE` #2826 #2971 #2975 #2977 #2979 #2993 #2994 #2998 #3001 #3003 +- added `dc_msg_get_parent()` #2984 +- added `dc_msg_force_plaintext()` API for bots #2847 +- allow removing quotes on drafts `dc_msg_set_quote(msg, NULL)` #2950 +- removed `mvbox_watch` option; watching is enabled when `mvbox_move` is enabled #2906 +- removed `inbox_watch` option #2922 +- deprecated `os_name` in `dc_context_new()`, pass `NULL` or an empty string #2956 + +### Changes +- start making it possible to write to mailing lists #2736 +- add `hop_info` to `dc_get_info()` #2751 #2914 #2923 +- add information about whether the database is encrypted or not to `dc_get_info()` #3000 +- selfstatus now defaults to empty #2951 #2960 +- validate detached cryptographic signatures as used eg. by Thunderbird #2865 +- do not change the draft's `msg_id` on updates and sending #2887 +- add `imap` table to keep track of message UIDs #2909 #2938 +- replace `SendMsgToSmtp` jobs which stored outgoing messages in blobdir with `smtp` SQL table #2939 #2996 +- sql: enable `auto_vacuum=INCREMENTAL` #2931 +- sql: build rusqlite with sqlcipher #2934 +- synchronize Seen status across devices #2942 +- `dc_preconfigure_keypair` now takes ascii armored keys instead of base64 #2862 +- put removed member in Bcc instead of To in the message about removal #2864 +- improve group updates #2889 +- re-write the blob filename creation loop #2981 +- update provider database (11 Jan 2022) #2959 +- python: allow timeout for internal configure tracker API #2967 +- python: remove API deprecated in Python 3.10 #2907 +- refactorings #2932 #2957 #2947 +- improve tests #2863 #2866 #2881 #2908 #2918 #2901 #2973 +- improve documentation #2880 #2886 #2895 +- improve ci #2919 #2926 #2969 #2999 + +### Fixes +- fix leaving groups #2929 +- fix unread count #2861 +- make `add_parts()` not early-exit #2879 +- recognize MS Exchange read receipts as read receipts #2890 +- create parent directory if creating a new file fails #2978 +- save "configured" flag later #2974 +- improve log #2928 +- `dc_receive_imf`: don't fail on invalid address in the To field #2940 + + +## 1.70.0 + +### Fixes +- fix: do not abort Param parsing on unknown keys #2856 +- fix: execute `Chat-Group-Member-Removed:` even when arriving disordered #2857 + + +## 1.69.0 + +### Fixes +- fix group-related system messages in multi-device setups #2848 +- fix "Google Workspace" (former "G Suite") issues related to bad resolvers #2852 + + +## 1.68.0 + +### Fixes +- fix chat assignment when forwarding #2843 +- fix layout issues with the generated QR code svg #2842 + + +## 1.67.0 + +### API changes +- `dc_get_securejoin_qr_svg(chat_id)` added #2815 +- added stock-strings `DC_STR_SETUP_CONTACT_QR_DESC` and `DC_STR_SECURE_JOIN_GROUP_QR_DESC` + + +## 1.66.0 + +### API changes +- `dc_contact_get_last_seen()` added #2823 +- python: `Contact.last_seen` added #2823 +- removed `DC_STR_NEWGROUPDRAFT`, we don't set draft after creating group anymore #2805 + +### Changes +- python: add cutil.from_optional_dc_charpointer() #2824 +- refactorings #2807 #2822 #2825 + + +## 1.65.0 + +### Changes +- python: add mypy support and some type hints #2809 + +### Fixes +- do not disable ephemeral timer when downloading a message partially #2811 +- apply existing ephemeral timer also to partially downloaded messages; + after full download, the ephemeral timer starts over #2811 +- replace user-visible error on verification failure with warning; + the error is logged to the corresponding chat anyway #2808 + + +## 1.64.0 + +### Fixes +- add 'waiting for being added to the group' only for group-joins, + not for setup-contact #2797 +- prioritize In-Reply-To: and References: headers over group IDs when assigning + messages to chats to fix incorrect assignment of Delta Chat replies to + classic email threads #2795 + + +## 1.63.0 + +### API changes +- `dc_get_last_error()` added #2788 + +### Changes +- Optimize Autocrypt gossip #2743 + +### Fixes +- fix permanently hiding of one-to-one chats after secure-join #2791 + + +## 1.62.0 + +### API Changes +- `dc_join_securejoin()` now always returns immediately; + the returned chat may not allow sending (`dc_chat_can_send()` returns false) + which may change as usual on `DC_EVENT_CHAT_MODIFIED` #2508 #2767 +- introduce multi-device-sync-messages; + as older cores display them as files in self-chat, + they are currently only sent if config option `send_sync_msgs` is set #2669 +- add `DC_EVENT_SELFAVATAR_CHANGED` #2742 + +### Changes +- use system DNS instead of google for MX queries #2780 +- improve error logging #2758 +- improve tests #2764 #2781 +- improve ci #2770 +- refactorings #2677 #2728 #2740 #2729 #2766 #2778 + +### Fixes +- add Let's Encrypt certificate to core as it may be missing older devices #2752 +- prioritize certificate setting from user over the one from provider-db #2749 +- fix "QR process failed" error #2725 +- do not update quota in endless loop #2726 + + +## 1.61.0 + +### API Changes +- download-on-demand added: `dc_msg_get_download_state()`, `dc_download_full_msg()` + and `download_limit` config option #2631 #2696 +- `dc_create_broadcast_list()` and chat type `DC_CHAT_TYPE_BROADCAST` added #2707 #2722 +- allow ui-specific configs using `ui.`-prefix in key (`dc_set_config(context, "ui.*", value)`) #2672 +- new strings from `DC_STR_PARTIAL_DOWNLOAD_MSG_BODY` + to `DC_STR_PART_OF_TOTAL_USED` #2631 #2694 #2707 #2723 +- emit warnings and errors from account manager with account-id 0 #2712 + +### Changes +- notify about incoming contact requests #2690 +- messages are marked as read on first read receipt #2699 +- quota warning reappears after import, rewarning at 95% #2702 +- lock strict TLS if certificate checks are automatic #2711 +- always check certificates strictly when connecting over SOCKS5 in Automatic mode #2657 +- `Accounts` is not cloneable anymore #2654 #2658 +- update chat/contact data only when there was no newer update #2642 +- better detection of mailing list names #2665 #2685 +- log all decisions when applying ephemeral timer to chats #2679 +- connectivity view now translatable #2694 #2723 +- improve Doxygen documentation #2647 #2668 #2684 #2688 #2705 +- refactorings #2656 #2659 #2677 #2673 #2678 #2675 #2663 #2692 #2706 +- update provider database #2618 + +### Fixes +- ephemeral timer rollback protection #2693 #2709 +- recreate configured folders if they are deleted #2691 +- ignore MDNs sent to self #2674 +- recognize NDNs that put headers into "message/global-headers" part #2598 +- avoid `dc_get_contacts()` returning duplicate contact ids #2591 +- do not leak group names on forwarding messages #2719 +- in case of smtp-errors, iterate over all addresses to fix ipv6/v4 problems #2720 +- fix pkg-config file #2660 +- fix "QR process failed" error #2725 + + +## 1.60.0 + +### Added +- add device message to warn about QUOTA #2621 +- add SOCKS5 support #2474 #2620 + +### Changes +- don't emit multiple events with the same import/export progress number #2639 +- reduce message length limit to 5000 chars #2615 + +### Fixes +- keep event emitter from closing when there are no accounts #2636 + + +## 1.59.0 + +### Added +- add quota information to `dc_get_connectivity_html()` + +### Changes +- refactorings #2592 #2570 #2581 +- add 'device chat about' to now existing status #2613 +- update provider database #2608 + +### Fixes +- provider database supports socket=PLAIN and dotless domains now #2604 #2608 +- add migrated accounts to events emitter #2607 +- fix forwarding quote-only mails #2600 +- do not set WantsMdn param for outgoing messages #2603 +- set timestamps for system messages #2593 +- do not treat gmail labels as folders #2587 +- avoid timing problems in `dc_maybe_network_lost()` #2551 +- only set smtp to "connected" if the last message was actually sent #2541 + + +## 1.58.0 + +### Fixes +- move WAL file together with database + and avoid using data if the database was not closed correctly before #2583 + + +## 1.57.0 + +### API Changes + +- breaking change: removed deaddrop chat #2514 #2563 + + Contact request chats are not merged into a single virtual + "deaddrop" chat anymore. Instead, they are shown in the chatlist the + same way as other chats, but sending of messages to them is not + allowed and MDNs are not sent automatically until the chat is + "accepted" by the user. + + New API: + - `dc_chat_is_contact_request()`: returns true if chat is a contact + request. In this case an option to accept the chat via + `dc_accept_chat()` should be shown in the UI. + - `dc_accept_chat()`: unblock the chat or accept contact request + - `dc_block_chat()`: block the chat, currently works only for mailing + lists. + + Removed API: + - `dc_create_chat_by_msg_id()`: deprecated 2021-02-07 in favor of + `dc_decide_on_contact_request()` + - `dc_marknoticed_contact()`: deprecated 2021-02-07 in favor of + `dc_decide_on_contact_request()` + - `dc_decide_on_contact_request()`: this call requires a message ID + from deaddrop chat as input. As deaddrop chat is removed, this + call can't be used anymore. + - `dc_msg_get_real_chat_id()`: use `dc_msg_get_chat_id()` instead, the + only difference between these calls was in handling of deaddrop + chat + - removed `DC_CHAT_ID_DEADDROP` and `DC_STR_DEADDROP` constants + +- breaking change: removed `DC_EVENT_ERROR_NETWORK` and `DC_STR_SERVER_RESPONSE` + Instead, there is a new api `dc_get_connectivity()` + and `dc_get_connectivity_html()`; + `DC_EVENT_CONNECTIVITY_CHANGED` is emitted on changes + +- breaking change: removed `dc_accounts_import_account()` + Instead you need to add an account and call `dc_imex(DC_IMEX_IMPORT_BACKUP)` + on its context + +- update account api, 2 new methods: + `int dc_all_work_done (dc_context_t* context);` + `int dc_accounts_all_work_done (dc_accounts_t* accounts);` + +- add api to check if a message was `Auto-Submitted` + cffi: `int dc_msg_is_bot (const dc_msg_t* msg);` + python: `Message.is_bot()` + +- `dc_context_t* dc_accounts_get_selected_account (dc_accounts_t* accounts);` + now returns `NULL` if there is no selected account + +- added `dc_accounts_maybe_network_lost()` for systems core cannot find out + connectivity loss on its own (eg. iOS) #2550 + +### Added +- use Auto-Submitted: auto-generated header to identify bots #2502 +- allow sending stickers via repl tool +- chat: make `get_msg_cnt()` and `get_fresh_msg_cnt()` work for deaddrop chat #2493 +- withdraw/revive own qr-codes #2512 +- add Connectivity view (a better api for getting the connection status) #2319 #2549 #2542 + +### Changes +- updated spec: new `Chat-User-Avatar` usage, `Chat-Content: sticker`, structure, copyright year #2480 +- update documentation #2548 #2561 #2569 +- breaking: `Accounts::create` does not also create an default account anymore #2500 +- remove "forwarded" from stickers, as the primary way of getting stickers + is by asking a bot and then forwarding them currently #2526 +- mimeparser: use mailparse to parse RFC 2231 filenames #2543 +- allow email addresses without dot in the domain part #2112 +- allow installing lib and include under different prefixes #2558 +- remove counter from name provided by `DC_CHAT_ID_ARCHIVED_LINK` #2566 +- improve tests #2487 #2491 #2497 +- refactorings #2492 #2503 #2504 #2506 #2515 #2520 #2567 #2575 #2577 #2579 +- improve ci #2494 +- update provider-database #2565 + +### Removed +- remove `dc_accounts_import_account()` api #2521 +- remove `DC_EVENT_ERROR_NETWORK` and `DC_STR_SERVER_RESPONSE` #2319 + +### Fixes +- allow stickers with gif-images #2481 +- fix database migration #2486 +- do not count hidden messages in get_msg_cnt(). #2493 +- improve drafts detection #2489 +- fix panic when removing last, selected account from account manager #2500 +- set_draft's message-changed-event returns now draft's msg id instead of 0 #2304 +- avoid hiding outgoing classic emails #2505 +- fixes for message timestamps #2517 +- do not process names, avatars, location XMLs, message signature etc. + for duplicate messages #2513 +- fix `can_send` for users not in group #2479 +- fix receiving events for accounts added by `dc_accounts_add_account()` #2559 +- fix which chats messages are assigned to #2465 +- fix: don't create chats when MDNs are received #2578 + + +## 1.56.0 + +- fix downscaling images #2469 + +- fix outgoing messages popping up in selfchat #2456 + +- securejoin: display error reason if there is any #2470 + +- do not allow deleting contacts with ongoing chats #2458 + +- fix: ignore drafts folder when scanning #2454 + +- fix: scan folders also when inbox is not watched #2446 + +- more robust In-Reply-To parsing #2182 + +- update dependencies #2441 #2438 #2439 #2440 #2447 #2448 #2449 #2452 #2453 #2460 #2464 #2466 + +- update provider-database #2471 + +- refactorings #2459 #2457 + +- improve tests and ci #2445 #2450 #2451 + + +## 1.55.0 + +- fix panic when receiving some HTML messages #2434 + +- fix downloading some messages multiple times #2430 + +- fix formatting of read receipt texts #2431 + +- simplify SQL error handling #2415 + +- explicit rust API for creating chats with blocked status #2282 + +- debloat the binary by using less AsRef arguments #2425 + + +## 1.54.0 + +- switch back from `sqlx` to `rusqlite` due to performance regressions #2380 #2381 #2385 #2387 + +- global search performance improvement #2364 #2365 #2366 + +- improve SQLite performance with `PRAGMA synchronous=normal` #2382 + +- python: fix building of bindings against system-wide install of `libdeltachat` #2383 #2385 + +- python: list `requests` as a requirement #2390 + +- fix creation of many delete jobs when being offline #2372 + +- synchronize status between devices #2386 + +- deaddrop (contact requests) chat improvements #2373 + +- add "Forwarded:" to notification and chatlist summaries #2310 + +- place user avatar directly into `Chat-User-Avatar` header #2232 #2384 + +- improve tests #2360 #2362 #2370 #2377 #2387 + +- cleanup #2359 #2361 #2374 #2376 #2379 #2388 + + +## 1.53.0 + +- fix sqlx performance regression #2355 2356 + +- add a `ci_scripts/coverage.sh` #2333 #2334 + +- refactorings and tests #2348 #2349 #2350 + +- improve python bindings #2332 #2326 + + +## 1.52.0 + +- database library changed from rusqlite to sqlx #2089 #2331 #2336 #2340 + +- add alias support: UIs should check for `dc_msg_get_override_sender_name()` + also in single-chats now and display divergent names and avatars #2297 + +- parse blockquote-tags for better quote detection #2313 + +- ignore unknown classical emails from spam folder #2311 + +- support "Mixed Up†encryption repairing #2321 + +- fix single chat search #2344 + +- fix nightly clippy and rustc errors #2341 + +- update dependencies #2350 + +- improve ci #2342 + +- improve python bindings #2332 #2326 + + +## 1.51.0 + +- breaking change: You have to call `dc_stop_io()`/`dc_start_io()` + before/after `dc_imex(DC_IMEX_EXPORT_BACKUP)`: + fix race condition and db corruption + when a message was received during backup #2253 + +- save subject for messages: new api `dc_msg_get_subject()`, + when quoting, use the subject of the quoted message as the new subject, + instead of the last subject in the chat #2274 #2283 + +- new apis to get full or html message, + `dc_msg_has_html()` and `dc_get_msg_html()` #2125 #2151 #2264 #2279 + +- new chat type and apis for the new mailing list support, + `DC_CHAT_TYPE_MAILINGLIST`, `dc_msg_get_real_chat_id()`, + `dc_msg_get_override_sender_name()` #1964 #2181 #2185 #2195 #2211 #2210 #2240 + #2241 #2243 #2258 #2259 #2261 #2267 #2270 #2272 #2290 + +- new api `dc_decide_on_contact_request()`, + deprecated `dc_create_chat_by_msg_id()` and `dc_marknoticed_contact()` #1964 + +- new flag `DC_GCM_INFO_ONLY` for api `dc_get_chat_msgs()` #2132 + +- new api `dc_get_chat_encrinfo()` #2186 + +- new api `dc_contact_get_status()`, returning the recent footer #2218 #2307 + +- improve contact name update rules, + add api `dc_contact_get_auth_name()` #2206 #2212 #2225 + +- new api for bots: `dc_msg_set_html()` #2153 + +- new api for bots: `dc_msg_set_override_sender_name()` #2231 + +- api removed: `dc_is_io_running()` #2139 + +- api removed: `dc_contact_get_first_name()` #2165 #2171 + +- improve compatibility with providers changing the Message-ID + (as Outlook.com) #2250 #2265 + +- correctly show emails that were sent to an alias and then bounced + +- implement Consistent Color Generation (XEP-0392), + that results in contact colors be be changed #2228 #2229 #2239 + +- fetch recent existing messages + and create corresponding chats after configure #2106 + +- improve e-mail compatibility + by scanning all folders from time to time #2067 #2152 #2158 #2184 #2215 #2224 + +- better support videochat-services not supporting random rooms #2191 + +- export backups as .tar files #2023 + +- scale avatars based on media_quality, fix avatar rotation #2063 + +- compare ephemeral timer to parent message to deal with reordering better #2100 + +- better ephemeral system messages #2183 + +- read quotes out of html messages #2104 + +- prepend subject to messages with attachments, if needed #2111 + +- run housekeeping at least once a day #2114 + +- resolve MX domain only once per OAuth2 provider #2122 + +- configure provider based on MX record #2123 #2134 + +- make transient bad destination address error permanent + after n tries #2126 #2202 + +- enable strict TLS for known providers by default #2121 + +- improve and harden secure join #2154 #2161 #2251 + +- update `dc_get_info()` to return more information #2156 + +- prefer In-Reply-To/References + over group-id stored in Message-ID #2164 #2172 #2173 + +- apply gossiped encryption preference to new peerstates #2174 + +- fix: do not return quoted messages from the trash chat #2221 + +- fix: allow emojis for location markers #2177 + +- fix encoding of Chat-Group-Name-Changed messages that could even lead to + messages not being delivered #2141 + +- fix error when no temporary directory is available #1929 + +- fix marking read receipts as seen #2117 + +- fix read-notification for mixed-case addresses #2103 + +- fix decoding of attachment filenames #2080 #2094 #2102 + +- fix downloading ranges of message #2061 + +- fix parsing quoted encoded words in From: header #2193 #2204 + +- fix import/export race condition #2250 + +- fix: exclude muted chats from notified-list #2269 #2275 + +- fix: update uid_next if the server rewind it #2288 + +- fix: return error on fingerprint mismatch on qr-scan #2295 + +- fix ci #2217 #2226 #2244 #2245 #2249 #2277 #2286 + +- try harder on backup opening #2148 + +- trash messages more thoroughly #2273 + +- nicer logging #2284 + +- add CMakeLists.txt #2260 + +- switch to rust 1.50, update toolchains, deps #2150 #2155 #2165 #2107 #2262 #2271 + +- improve python bindings #2113 #2115 #2133 #2214 + +- improve documentation #2143 #2160 #2175 #2146 + +- refactorings #2110 #2136 #2135 #2168 #2178 #2189 #2190 #2198 #2197 #2201 #2196 + #2200 #2230 #2262 #2203 + +- update provider-database #2299 + + +## 1.50.0 + +- do not fetch emails in between inbox_watch disabled and enabled again #2087 + +- fix: do not fetch from INBOX if inbox_watch is disabled #2085 + +- fix: do not use STARTTLS when PLAIN connection is requested + and do not allow downgrade if STARTTLS is not available #2071 + + +## 1.49.0 + +- add timestamps to image and video filenames #2068 + +- forbid quoting messages from another context #2069 + +- fix: preserve quotes in messages with attachments #2070 + + +## 1.48.0 + +- `fetch_existing` renamed to `fetch_existing_msgs` and disabled by default + #2035 #2042 + +- skip fetch existing messages/contacts if config-option `bot` set #2017 + +- always log why a message is sorted to trash #2045 + +- display a quote if top posting is detected #2047 + +- add ephemeral task cancellation to `dc_stop_io()`; + before, there was no way to quickly terminate pending ephemeral tasks #2051 + +- when saved-messages chat is deleted, + a device-message about recreation is added #2050 + +- use `max_smtp_rcpt_to` from provider-db, + sending messages to many recipients in configurable chunks #2056 + +- fix handling of empty autoconfigure files #2027 + +- fix adding saved messages to wrong chats on multi-device #2034 #2039 + +- fix hang on android4.4 and other systems + by adding a workaround to executer-blocking-handling bug #2040 + +- fix secret key export/import roundtrip #2048 + +- fix mistakenly unarchived chats #2057 + +- fix outdated-reminder test that fails only 7 days a year, + including halloween :) #2059 + +- improve python bindings #2021 #2036 #2038 + +- update provider-database #2037 + + +## 1.47.0 + +- breaking change: `dc_update_device_chats()` removed; + this is now done automatically during configure + unless the new config-option `bot` is set #1957 + +- breaking change: split `DC_EVENT_MSGS_NOTICED` off `DC_EVENT_MSGS_CHANGED` + and remove `dc_marknoticed_all_chats()` #1942 #1981 + +- breaking change: remove unused starring options #1965 + +- breaking change: `DC_CHAT_TYPE_VERIFIED_GROUP` replaced by + `dc_chat_is_protected()`; also single-chats may be protected now, this may + happen over the wire even if the UI do not offer an option for that #1968 + +- breaking change: split quotes off message text, + UIs should use at least `dc_msg_get_quoted_text()` to show quotes now #1975 + +- new api for quote handling: `dc_msg_set_quote()`, `dc_msg_get_quoted_text()`, + `dc_msg_get_quoted_msg()` #1975 #1984 #1985 #1987 #1989 #2004 + +- require quorum to enable encryption #1946 + +- speed up and clean up account creation #1912 #1927 #1960 #1961 + +- configure now collects recent contacts and fetches last messages + unless disabled by `fetch_existing` config-option #1913 #2003 + EDIT: `fetch_existing` renamed to `fetch_existing_msgs` in 1.48.0 #2042 + +- emit `DC_EVENT_CHAT_MODIFIED` on contact rename + and set contact-id on `DC_EVENT_CONTACTS_CHANGED` #1935 #1936 #1937 + +- add `dc_set_chat_protection()`; the `protect` parameter in + `dc_create_group_chat()` will be removed in an upcoming release; + up to then, UIs using the "verified group" paradigm + should not use `dc_set_chat_protection()` #1968 #2014 #2001 #2012 #2007 + +- remove unneeded `DC_STR_COUNT` #1991 + +- mark all failed messages as failed when receiving an NDN #1993 + +- check some easy cases for bad system clock and outdated app #1901 + +- fix import temporary directory usage #1929 + +- fix forcing encryption for reset peers #1998 + +- fix: do not allow to save drafts in non-writeable chats #1997 + +- fix: do not show HTML if there is no content and there is an attachment #1988 + +- fix recovering offline/lost connections, fixes background receive bug #1983 + +- fix ordering of accounts returned by `dc_accounts_get_all()` #1909 + +- fix whitespace for summaries #1938 + +- fix: improve sentbox name guessing #1941 + +- fix: avoid manual poll impl for accounts events #1944 + +- fix encoding newlines in param as a preparation for storing quotes #1945 + +- fix: internal and ffi error handling #1967 #1966 #1959 #1911 #1916 #1917 #1915 + +- fix ci #1928 #1931 #1932 #1933 #1934 #1943 + +- update provider-database #1940 #2005 #2006 + +- update dependencies #1919 #1908 #1950 #1963 #1996 #2010 #2013 + + +## 1.46.0 + +- breaking change: `dc_configure()` report errors in + `DC_EVENT_CONFIGURE_PROGRESS`: capturing error events is no longer working + #1886 #1905 + +- breaking change: removed `DC_LP_{IMAP|SMTP}_SOCKET*` from `server_flags`; + added `mail_security` and `send_security` using `DC_SOCKET` enum #1835 + +- parse multiple servers in Mozilla autoconfig #1860 + +- try multiple servers for each protocol #1871 + +- do IMAP and SMTP configuration in parallel #1891 + +- configuration cleanup and speedup #1858 #1875 #1889 #1904 #1906 + +- secure-join cleanup, testing, fixing #1876 #1877 #1887 #1888 #1896 #1899 #1900 + +- do not reset peerstate on encrypted messages, + ignore reordered autocrypt headers #1885 #1890 + +- always sort message replies after parent message #1852 + +- add an index to significantly speed up `get_fresh_msg_cnt()` #1881 + +- improve mimetype guessing for PDF and many other formats #1857 #1861 + +- improve accepting invalid html #1851 + +- improve tests, cleanup and ci #1850 #1856 #1859 #1861 #1884 #1894 #1895 + +- tweak HELO command #1908 + +- make `dc_accounts_get_all()` return accounts sorted #1909 + +- fix KML coordinates precision used for location streaming #1872 + +- fix cancelling import/export #1855 + + +## 1.45.0 + +- add `dc_accounts_t` account manager object and related api functions #1784 + +- add capability to import backups as .tar files, + which will become the default in a subsequent release #1749 + +- try various server domains on configuration #1780 #1838 + +- recognize .tgs files as stickers #1826 + +- remove X-Mailer debug header #1819 + +- improve guessing message types from extension #1818 + +- fix showing unprotected subjects in encrypted messages #1822 + +- fix threading in interaction with non-delta-clients #1843 + +- fix handling if encryption degrades #1829 + +- fix webrtc-servers names set by the user #1831 + +- update provider database #1828 + +- update async-imap to fix Oauth2 #1837 + +- optimize jpeg assets with trimage #1840 + +- add tests and documentations #1809 #1820 + + +## 1.44.0 + +- fix peerstate issues #1800 #1805 + +- fix a crash related to muted chats #1803 + +- fix incorrect dimensions sometimes reported for images #1806 + +- fixed `dc_chat_get_remaining_mute_duration` function #1807 + +- handle empty tags (e.g. `
`) in HTML mails #1810 + +- always translate the message about disappearing messages timer change #1813 + +- improve footer detection in plain text email #1812 + +- update device chat icon to fix warnings in iOS logs #1802 + +- fix deletion of multiple messages #1795 + + +## 1.43.0 + +- improve using own jitsi-servers #1785 + +- fix smtp-timeout tweaks for larger mails #1797 + +- more bug fixes and updates #1794 #1792 #1789 #1787 + + +## 1.42.0 + +- new qr-code type `DC_QR_WEBRTC` #1779 + +- tweak smtp-timeout for larger mails #1782 + +- optimize read-receipts #1765 + +- improve tests #1769 + +- bug fixes #1766 #1772 #1773 #1775 #1776 #1777 + + +## 1.41.0 + +- new apis to initiate video chats #1718 #1735 + +- new apis `dc_msg_get_ephemeral_timer()` + and `dc_msg_get_ephemeral_timestamp()` + +- new api `dc_chatlist_get_summary2()` #1771 + +- improve IMAP handling #1703 #1704 + +- improve ephemeral messages #1696 #1705 + +- mark location-messages as auto-generated #1715 + +- multi-device avatar-sync #1716 #1717 + +- improve python bindings #1732 #1733 #1738 #1769 + +- Allow http scheme for DCACCOUNT urls #1770 + +- more fixes #1702 #1706 #1707 #1710 #1719 #1721 + #1723 #1734 #1740 #1744 #1748 #1760 #1766 #1773 #1765 + +- refactorings #1712 #1714 #1757 + +- update toolchains and dependencies #1726 #1736 #1737 #1742 #1743 #1746 + + +## 1.40.0 + +- introduce ephemeral messages #1540 #1680 #1683 #1684 #1691 #1692 + +- `DC_MSG_ID_DAYMARKER` gets timestamp attached #1677 #1685 + +- improve idle #1690 #1688 + +- fix message processing issues by sequential processing #1694 + +- refactorings #1670 #1673 + + +## 1.39.0 + +- fix handling of `mvbox_watch`, `sentbox_watch`, `inbox_watch` #1654 #1658 + +- fix potential panics, update dependencies #1650 #1655 + + +## 1.38.0 + +- fix sorting, esp. for multi-device + + +## 1.37.0 + +- improve ndn heuristics #1630 + +- get oauth2 authorizer from provider-db #1641 + +- removed linebreaks and spaces from generated qr-code #1631 + +- more fixes #1633 #1635 #1636 #1637 + + +## 1.36.0 + +- parse ndn (network delivery notification) reports + and report failed messages as such #1552 #1622 #1630 + +- add oauth2 support for gsuite domains #1626 + +- read image orientation from exif before recoding #1619 + +- improve logging #1593 #1598 + +- improve python and bot bindings #1583 #1609 + +- improve imap logout #1595 + +- fix sorting #1600 #1604 + +- fix qr code generation #1631 + +- update rustcrypto releases #1603 + +- refactorings #1617 + + +## 1.35.0 + +- enable strict-tls from a new provider-db setting #1587 + +- new subject 'Message from USER' for one-to-one chats #1395 + +- recode images #1563 + +- improve reconnect handling #1549 #1580 + +- improve importing addresses #1544 + +- improve configure and folder detection #1539 #1548 + +- improve test suite #1559 #1564 #1580 #1581 #1582 #1584 #1588: + +- fix ad-hoc groups #1566 + +- preventions against being marked as spam #1575 + +- refactorings #1542 #1569 + + +## 1.34.0 + +- new api for io, thread and event handling #1356, + see the example atop of `deltachat.h` to get an overview + +- LOTS of speed improvements due to async processing #1356 + +- enable WAL mode for sqlite #1492 + +- process incoming messages in bulk #1527 + +- improve finding out the sent-folder #1488 + +- several bug fixes + + +## 1.33.0 + +- let `dc_set_muted()` also mute one-to-one chats #1470 + +- fix a bug that led to load and traffic if the server does not use sent-folder + #1472 + + +## 1.32.0 + +- fix endless loop when trying to download messages with bad RFC Message-ID, + also be more reliable on similar errors #1463 #1466 #1462 + +- fix bug with comma in contact request #1438 + +- do not refer to hidden messages on replies #1459 + +- improve error handling #1468 #1465 #1464 + + +## 1.31.0 + +- always describe the context of the displayed error #1451 + +- do not emit `DC_EVENT_ERROR` when message sending fails; + `dc_msg_get_state()` and `dc_get_msg_info()` are sufficient #1451 + +- new config-option `media_quality` #1449 + +- try over if writing message to database fails #1447 + + +## 1.30.0 + +- expunge deleted messages #1440 + +- do not send `DC_EVENT_MSGS_CHANGED|INCOMING_MSG` on hidden messages #1439 + + +## 1.29.0 + +- new config options `delete_device_after` and `delete_server_after`, + each taking an amount of seconds after which messages + are deleted from the device and/or the server #1310 #1335 #1411 #1417 #1423 + +- new api `dc_estimate_deletion_cnt()` to estimate the effect + of `delete_device_after` and `delete_server_after` + +- use Ed25519 keys by default, these keys are much shorter + than RSA keys, which results in saving traffic and speed improvements #1362 + +- improve message ellipsizing #1397 #1430 + +- emit `DC_EVENT_ERROR_NETWORK` also on smtp-errors #1378 + +- do not show badly formatted non-delta-messages as empty #1384 + +- try over SMTP on potentially recoverable error 5.5.0 #1379 + +- remove device-chat from forward-to-chat-list #1367 + +- improve group-handling #1368 + +- `dc_get_info()` returns uptime (how long the context is in use) + +- python improvements and adaptions #1408 #1415 + +- log to the stdout and stderr in tests #1416 + +- refactoring, code improvements #1363 #1365 #1366 #1370 #1375 #1389 #1390 #1418 #1419 + +- removed api: `dc_chat_get_subtitle()`, `dc_get_version_str()`, `dc_array_add_id()` + +- removed events: `DC_EVENT_MEMBER_ADDED`, `DC_EVENT_MEMBER_REMOVED` + + +## 1.28.0 + +- new flag DC_GCL_FOR_FORWARDING for dc_get_chatlist() + that will sort the "saved messages" chat to the top of the chatlist #1336 +- mark mails as being deleted from server in dc_empty_server() #1333 +- fix interaction with servers that do not allow folder creation on root-level; + use path separator as defined by the email server #1359 +- fix group creation if group was created by non-delta clients #1357 +- fix showing replies from non-delta clients #1353 +- fix member list on rejoining left groups #1343 +- fix crash when using empty groups #1354 +- fix potential crash on special names #1350 + + +## 1.27.0 + +- handle keys reliably on armv7 #1327 + + +## 1.26.0 + +- change generated key type back to RSA as shipped versions + have problems to encrypt to Ed25519 keys + +- update rPGP to encrypt reliably to Ed25519 keys; + one of the next versions can finally use Ed25519 keys then + + +## 1.25.0 + +- save traffic by downloading only messages that are really displayed #1236 + +- change generated key type to Ed25519, these keys are much shorter + than RSA keys, which results in saving traffic and speed improvements #1287 + +- improve key handling #1237 #1240 #1242 #1247 + +- mute handling, apis are dc_set_chat_mute_duration() + dc_chat_is_muted() and dc_chat_get_remaining_mute_duration() #1143 + +- pinning chats, new apis are dc_set_chat_visibility() and + dc_chat_get_visibility() #1248 + +- add dc_provider_new_from_email() api that queries the new, integrated + provider-database #1207 + +- account creation by scanning a qr code + in the DCACCOUNT scheme (https://mailadm.readthedocs.io), + new api is dc_set_config_from_qr() #1249 + +- if possible, dc_join_securejoin(), returns the new chat-id immediately + and does the handshake in background #1225 + +- update imap and smtp dependencies #1115 + +- check for MOVE capability before using MOVE command #1263 + +- allow inline attachments from RFC 2183 #1280 + +- fix updating names from incoming mails #1298 + +- fix error messages shown on import #1234 + +- directly attempt to re-connect if the smtp connection is maybe stale #1296 + +- improve adding group members #1291 + +- improve rust-api #1261 + +- cleanup #1302 #1283 #1282 #1276 #1270-#1274 #1267 #1258-#1260 + #1257 #1239 #1231 #1224 + +- update spec #1286 #1291 + + +## 1.0.0-beta.24 + +- fix oauth2/gmail bug introduced in beta23 (not used in releases) #1219 + +- fix panic when receiving eg. cyrillic filenames #1216 + +- delete all consumed secure-join handshake messagess #1209 #1212 + +- Rust-level cleanups #1218 #1217 #1210 #1205 + +- python-level cleanups #1204 #1202 #1201 + + +## 1.0.0-beta.23 + +- #1197 fix imap-deletion of messages + +- #1171 Combine multiple MDNs into a single mail, reducing traffic + +- #1155 fix to not send out gossip always, reducing traffic + +- #1160 fix reply-to-encrypted determination + +- #1182 Add "Auto-Submitted: auto-replied" header to MDNs + +- #1194 produce python wheels again, fix c/py.delta.chat + master-deployment + +- rust-level housekeeping and improvements #1161 #1186 #1185 #1190 #1194 #1199 #1191 #1190 #1184 and more + +- #1063 clarify licensing + +- #1147 use mailparse 0.10.2 + + +## 1.0.0-beta.22 + +- #1095 normalize email lineends to CRLF + +- #1095 enable link-time-optimization, saves eg. on android 11 mb + +- #1099 fix import regarding devicechats + +- #1092 improve logging + +- #1096 #1097 #1094 #1090 #1091 internal cleanups + +## 1.0.0-beta.21 + +- #1078 #1082 ensure RFC compliance by producing 78 column lines for + encoded attachments. + +- #1080 don't recreate and thus break group membership if an unknown + sender (or mailer-daemon) sends a message referencing the group chat + +- #1081 #1079 some internal cleanups + +- update imap-proto dependency, to fix yandex/oauth + +## 1.0.0-beta.20 + +- #1074 fix OAUTH2/gmail +- #1072 fix group members not appearing in contact list +- #1071 never block interrupt_idle (thus hopefully also not on maybe_network()) +- #1069 reduce smtp-timeout to 30 seconds +- #1066 #1065 avoid unwrap in dehtml, make literals more readable + +## 1.0.0-beta.19 + +- #1058 timeout smtp-send if it doesn't complete in 15 minutes + +- #1059 trim down logging + +## 1.0.0-beta.18 + +- #1056 avoid panicking when we couldn't read imap-server's greeting + message + +- #1055 avoid panicking when we don't have a selected folder + +- #1052 #1049 #1051 improve logging to add thread-id/name and + file/lineno to each info/warn message. + +- #1050 allow python bindings to initialize Account with "os_name". + + +## 1.0.0-beta.17 + +- #1044 implement avatar recoding to 192x192 in core to keep file sizes small. + +- #1024 fix #1021 SQL/injection malformed Chat-Group-Name breakage + +- #1036 fix smtp crash by pulling in a fixed async-smtp + +- #1039 fix read-receipts appearing as normal messages when you change + MDN settings + +- #1040 do not panic on SystemTimeDifference + +- #1043 avoid potential crashes in malformed From/Chat-Disposition... headers + +- #1045 #1041 #1038 #1035 #1034 #1029 #1025 various cleanups and doc + improvements + +## 1.0.0-beta.16 + +- alleviate login problems with providers which only + support RSA1024 keys by switching back from Rustls + to native-tls, by using the new async-email/async-native-tls + crate from @dignifiedquire. thanks @link2xt. + +- introduce per-contact profile images to send out + own profile image heuristically, and fix sending + out of profile images in "in-prepare" groups. + this also extends the Chat-spec that is maintained + in core to specify Chat-Group-Image and Chat-Group-Avatar + headers. thanks @r10s and @hpk42. + +- fix merging of protected headers from the encrypted + to the unencrypted parts, now not happening recursively + anymore. thanks @hpk and @r10s + +- fix/optimize autocrypt gossip headers to only get + sent when there are more than 2 people in a chat. + thanks @link2xt + +- fix displayname to use the authenticated name + when available (displayname as coming from contacts + themselves). thanks @simon-laux + +- introduce preliminary support for offline autoconfig + for nauta provider. thanks @hpk42 @r10s + +## 1.0.0-beta.15 + +- fix #994 attachment appeared doubled in chats (and where actually + downloaded after smtp-send). @hpk42 + +## 1.0.0-beta.14 + +- fix packaging issue with our rust-email fork, now we are tracking + master again there. hpk42 + +## 1.0.0-beta.13 + +- fix #976 -- unicode-issues in display-name of email addresses. @hpk42 + +- fix #985 group add/remove member bugs resulting in broken groups. @hpk42 + +- fix hanging IMAP connections -- we now detect with a 15second timeout + if we cannot terminate the IDLE IMAP protocol. @hpk42 @link2xt + +- fix incoming multipart/mixed containing html, to show up as + attachments again. Fixes usage for simplebot which sends html + files for users to interact with the bot. @adbenitez @hpk42 + +- refinements to internal autocrypt-handling code, do not send + prefer-encrypt=nopreference as it is the default if no attribute + is present. @linkxt + +- simplify, modularize and rustify several parts + of dc-core (general WIP). @link2xt @flub @hpk42 @r10s + +- use async-email/async-smtp to handle SMTP connections, might + fix connection/reconnection issues. @link2xt + +- more tests and refinements for dealing with blobstorage @flub @hpk42 + +- use a dedicated build-server for CI testing of core PRs + + +## 1.0.0-beta.12 + +- fix python bindings to use core for copying attachments to blobdir + and fix core to actually do it. @hpk42 + +## 1.0.0-beta.11 + +- trigger reconnect more often on imap error states. Should fix an + issue observed when trying to empty a folder. @hpk42 + +- un-split qr tests: we fixed qr-securejoin protocol flakiness + last weeks. @hpk42 + +## 1.0.0-beta.10 + +- fix grpid-determination from in-reply-to and references headers. @hpk42 + +- only send Autocrypt-gossip headers on encrypted messages. @dignifiedquire + +- fix reply-to-encrypted message to also be encrypted. @hpk42 + +- remove last unsafe code from dc_receive_imf :) @hpk42 + +- add experimental new dc_chat_get_info_json FFI/API so that desktop devs + can play with using it. @jikstra + +- fix encoding of subjects and attachment-filenames @hpk42 + @dignifiedquire . + +## 1.0.0-beta.9 + +- historic: we now use the mailparse crate and lettre-email to generate mime + messages. This got rid of mmime completely, the C2rust generated port of the libetpan + mime-parse -- IOW 22KLocs of cumbersome code removed! see + https://github.com/chatmail/core/pull/904#issuecomment-561163330 + many thanks @dignifiedquire for making everybody's life easier + and @jonhoo (from rust-imap fame) for suggesting to use the mailparse crate :) + +- lots of improvements and better error handling in many rust modules + thanks @link2xt @flub @r10s, @hpk42 and @dignifiedquire + +- @r10s introduced a new device chat which has an initial + welcome message. See + https://c.delta.chat/classdc__context__t.html#a1a2aad98bd23c1d21ee42374e241f389 + for the main new FFI-API. + +- fix moving self-sent messages, thanks @r10s, @flub, @hpk42 + +- fix flakiness/sometimes-failing verified/join-protocols, + thanks @flub, @r10s, @hpk42 + +- fix reply-to-encrypted message to keep encryption + +- new DC_EVENT_SECUREJOIN_MEMBER_ADDED event + +- many little fixes and rustifications (@link2xt, @flub, @hpk42) + + +## 1.0.0-beta.8 + +- now uses async-email/async-imap as the new base + which makes imap-idle interruptible and thus fixes + several issues around the imap thread being in zombie state . + thanks @dignifiedquire, @hpk42 and @link2xt. + +- fixes imap-protocol parsing bugs that lead to infinitely + repeated crashing while trying to receive messages with + a subject that contained non-utf8. thanks @link2xt + +- fixed logic to find encryption subkey -- previously + delta chat would use the primary key for encryption + (which works with RSA but not ECC). thanks @link2xt + +- introduce a new device chat where core and UIs can + add "device" messages. Android uses it for an initial + welcome message. thanks @r10s + +- fix time smearing (when two message are virtually send + in the same second, there would be misbehaviour because + we didn't persist smeared time). thanks @r10s + +- fix double-dotted extensions like .html.zip or .tar.gz + to not mangle them when creating blobfiles. thanks @flub + +- fix backup/exports where the wrong sql file would be modified, + leading to problems when exporting twice. thanks @hpk42 + +- several other little fixes and improvements + + +## 1.0.0-beta.7 + +- fix location-streaming #782 + +- fix display of messages that could not be decrypted #785 + +- fix smtp MAILER-DAEMON bug #786 + +- fix a logging of durations #783 + +- add more error logging #779 + +- do not panic on some bad utf-8 mime #776 + +## 1.0.0-beta.6 + +- fix chatlist.get_msg_id to return id, instead of wrongly erroring + +## 1.0.0-beta.5 + +- fix dc_get_msg() to return empty messages when asked for special ones + +## 1.0.0-beta.4 + +- fix more than one sending of autocrypt setup message + +- fix recognition of mailto-address-qr-codes, add tests + +- tune down error to warning when adding self to chat + +## 1.0.0-beta.3 + +- add back `dc_empty_server()` #682 + +- if `show_emails` is set to `DC_SHOW_EMAILS_ALL`, + email-based contact requests are added to the chatlist directly + +- fix IMAP hangs #717 and cleanups + +- several rPGP fixes + +- code streamlining and rustifications + + +## 1.0.0-beta.2 + +- https://c.delta.chat docs are now regenerated again through our CI + +- several rPGP cleanups, security fixes and better multi-platform support + +- reconnect on io errors and broken pipes (imap) + +- probe SMTP with real connection not just setup + +- various imap/smtp related fixes + +- use to_string_lossy in most places instead of relying on valid utf-8 + encodings + +- rework, rustify and test autoconfig-reading and parsing + +- some rustifications/boolifications of c-ints + + +## 1.0.0-beta.1 + +- first beta of the Delta Chat Rust core library. many fixes of crashes + and other issues compared to 1.0.0-alpha.5. + +- Most code is now "rustified" and does not do manual memory allocation anymore. + +- The `DC_EVENT_GET_STRING` event is not used anymore, removing the last + event where the core requested a return value from the event callback. + + Please now use `dc_set_stock_translation()` API for core messages + to be properly localized. + +- Deltachat FFI docs are automatically generated and available here: + https://c.delta.chat + +- New events ImapMessageMoved and ImapMessageDeleted + +For a full list of changes, please see our closed Pull Requests: + +https://github.com/chatmail/core/pulls?q=is%3Apr+is%3Aclosed + +[1.111.0]: https://github.com/chatmail/core/compare/v1.110.0...v1.111.0 +[1.112.0]: https://github.com/chatmail/core/compare/v1.111.0...v1.112.0 +[1.112.1]: https://github.com/chatmail/core/compare/v1.112.0...v1.112.1 +[1.112.2]: https://github.com/chatmail/core/compare/v1.112.1...v1.112.2 +[1.112.3]: https://github.com/chatmail/core/compare/v1.112.2...v1.112.3 +[1.112.4]: https://github.com/chatmail/core/compare/v1.112.3...v1.112.4 +[1.112.5]: https://github.com/chatmail/core/compare/v1.112.4...v1.112.5 +[1.112.6]: https://github.com/chatmail/core/compare/v1.112.5...v1.112.6 +[1.112.7]: https://github.com/chatmail/core/compare/v1.112.6...v1.112.7 +[1.112.8]: https://github.com/chatmail/core/compare/v1.112.7...v1.112.8 +[1.112.9]: https://github.com/chatmail/core/compare/v1.112.8...v1.112.9 +[1.112.10]: https://github.com/chatmail/core/compare/v1.112.9...v1.112.10 +[1.113.0]: https://github.com/chatmail/core/compare/v1.112.9...v1.113.0 +[1.114.0]: https://github.com/chatmail/core/compare/v1.113.0...v1.114.0 +[1.115.0]: https://github.com/chatmail/core/compare/v1.114.0...v1.115.0 +[1.116.0]: https://github.com/chatmail/core/compare/v1.115.0...v1.116.0 +[1.117.0]: https://github.com/chatmail/core/compare/v1.116.0...v1.117.0 +[1.118.0]: https://github.com/chatmail/core/compare/v1.117.0...v1.118.0 +[1.119.0]: https://github.com/chatmail/core/compare/v1.118.0...v1.119.0 +[1.119.1]: https://github.com/chatmail/core/compare/v1.119.0...v1.119.1 +[1.120.0]: https://github.com/chatmail/core/compare/v1.119.1...v1.120.0 +[1.121.0]: https://github.com/chatmail/core/compare/v1.120.0...v1.121.0 +[1.122.0]: https://github.com/chatmail/core/compare/v1.121.0...v1.122.0 +[1.123.0]: https://github.com/chatmail/core/compare/v1.122.0...v1.123.0 +[1.124.0]: https://github.com/chatmail/core/compare/v1.123.0...v1.124.0 +[1.124.1]: https://github.com/chatmail/core/compare/v1.124.0...v1.124.1 +[1.125.0]: https://github.com/chatmail/core/compare/v1.124.1...v1.125.0 +[1.126.0]: https://github.com/chatmail/core/compare/v1.125.0...v1.126.0 +[1.126.1]: https://github.com/chatmail/core/compare/v1.126.0...v1.126.1 +[1.127.0]: https://github.com/chatmail/core/compare/v1.126.1...v1.127.0 +[1.127.1]: https://github.com/chatmail/core/compare/v1.127.0...v1.127.1 +[1.127.2]: https://github.com/chatmail/core/compare/v1.127.1...v1.127.2 +[1.128.0]: https://github.com/chatmail/core/compare/v1.127.2...v1.128.0 +[1.129.0]: https://github.com/chatmail/core/compare/v1.128.0...v1.129.0 +[1.129.1]: https://github.com/chatmail/core/compare/v1.129.0...v1.129.1 +[1.130.0]: https://github.com/chatmail/core/compare/v1.129.1...v1.130.0 +[1.131.0]: https://github.com/chatmail/core/compare/v1.130.0...v1.131.0 +[1.131.1]: https://github.com/chatmail/core/compare/v1.131.0...v1.131.1 +[1.131.2]: https://github.com/chatmail/core/compare/v1.131.1...v1.131.2 +[1.131.3]: https://github.com/chatmail/core/compare/v1.131.2...v1.131.3 +[1.131.4]: https://github.com/chatmail/core/compare/v1.131.3...v1.131.4 +[1.131.5]: https://github.com/chatmail/core/compare/v1.131.4...v1.131.5 +[1.131.6]: https://github.com/chatmail/core/compare/v1.131.5...v1.131.6 +[1.131.7]: https://github.com/chatmail/core/compare/v1.131.6...v1.131.7 +[1.131.8]: https://github.com/chatmail/core/compare/v1.131.7...v1.131.8 +[1.131.9]: https://github.com/chatmail/core/compare/v1.131.8...v1.131.9 +[1.132.0]: https://github.com/chatmail/core/compare/v1.131.9...v1.132.0 +[1.132.1]: https://github.com/chatmail/core/compare/v1.132.0...v1.132.1 +[1.133.0]: https://github.com/chatmail/core/compare/v1.132.1...v1.133.0 +[1.133.1]: https://github.com/chatmail/core/compare/v1.133.0...v1.133.1 +[1.133.2]: https://github.com/chatmail/core/compare/v1.133.1...v1.133.2 +[1.134.0]: https://github.com/chatmail/core/compare/v1.133.2...v1.134.0 +[1.135.0]: https://github.com/chatmail/core/compare/v1.134.0...v1.135.0 +[1.135.1]: https://github.com/chatmail/core/compare/v1.135.0...v1.135.1 +[1.136.0]: https://github.com/chatmail/core/compare/v1.135.1...v1.136.0 +[1.136.1]: https://github.com/chatmail/core/compare/v1.136.0...v1.136.1 +[1.136.2]: https://github.com/chatmail/core/compare/v1.136.1...v1.136.2 +[1.136.3]: https://github.com/chatmail/core/compare/v1.136.2...v1.136.3 +[1.136.4]: https://github.com/chatmail/core/compare/v1.136.3...v1.136.4 +[1.136.5]: https://github.com/chatmail/core/compare/v1.136.4...v1.136.5 +[1.136.6]: https://github.com/chatmail/core/compare/v1.136.5...v1.136.6 +[1.137.0]: https://github.com/chatmail/core/compare/v1.136.6...v1.137.0 +[1.137.1]: https://github.com/chatmail/core/compare/v1.137.0...v1.137.1 +[1.137.2]: https://github.com/chatmail/core/compare/v1.137.1...v1.137.2 +[1.137.3]: https://github.com/chatmail/core/compare/v1.137.2...v1.137.3 +[1.137.4]: https://github.com/chatmail/core/compare/v1.137.3...v1.137.4 +[1.138.0]: https://github.com/chatmail/core/compare/v1.137.4...v1.138.0 +[1.138.1]: https://github.com/chatmail/core/compare/v1.138.0...v1.138.1 +[1.138.2]: https://github.com/chatmail/core/compare/v1.138.1...v1.138.2 +[1.138.3]: https://github.com/chatmail/core/compare/v1.138.2...v1.138.3 +[1.138.4]: https://github.com/chatmail/core/compare/v1.138.3...v1.138.4 +[1.138.5]: https://github.com/chatmail/core/compare/v1.138.4...v1.138.5 +[1.139.0]: https://github.com/chatmail/core/compare/v1.138.5...v1.139.0 +[1.139.1]: https://github.com/chatmail/core/compare/v1.139.0...v1.139.1 +[1.139.2]: https://github.com/chatmail/core/compare/v1.139.1...v1.139.2 +[1.139.3]: https://github.com/chatmail/core/compare/v1.139.2...v1.139.3 +[1.139.4]: https://github.com/chatmail/core/compare/v1.139.3...v1.139.4 +[1.139.5]: https://github.com/chatmail/core/compare/v1.139.4...v1.139.5 +[1.139.6]: https://github.com/chatmail/core/compare/v1.139.5...v1.139.6 +[1.140.0]: https://github.com/chatmail/core/compare/v1.139.6...v1.140.0 +[1.140.1]: https://github.com/chatmail/core/compare/v1.140.0...v1.140.1 +[1.140.2]: https://github.com/chatmail/core/compare/v1.140.1...v1.140.2 +[1.141.0]: https://github.com/chatmail/core/compare/v1.140.2...v1.141.0 +[1.141.1]: https://github.com/chatmail/core/compare/v1.141.0...v1.141.1 +[1.141.2]: https://github.com/chatmail/core/compare/v1.141.1...v1.141.2 +[1.142.0]: https://github.com/chatmail/core/compare/v1.141.2...v1.142.0 +[1.142.1]: https://github.com/chatmail/core/compare/v1.142.0...v1.142.1 +[1.142.2]: https://github.com/chatmail/core/compare/v1.142.1...v1.142.2 +[1.142.3]: https://github.com/chatmail/core/compare/v1.142.2...v1.142.3 +[1.142.4]: https://github.com/chatmail/core/compare/v1.142.3...v1.142.4 +[1.142.5]: https://github.com/chatmail/core/compare/v1.142.4...v1.142.5 +[1.142.6]: https://github.com/chatmail/core/compare/v1.142.5...v1.142.6 +[1.142.7]: https://github.com/chatmail/core/compare/v1.142.6...v1.142.7 +[1.142.8]: https://github.com/chatmail/core/compare/v1.142.7...v1.142.8 +[1.142.9]: https://github.com/chatmail/core/compare/v1.142.8...v1.142.9 +[1.142.10]: https://github.com/chatmail/core/compare/v1.142.9..v1.142.10 +[1.142.11]: https://github.com/chatmail/core/compare/v1.142.10..v1.142.11 +[1.142.12]: https://github.com/chatmail/core/compare/v1.142.11..v1.142.12 +[1.143.0]: https://github.com/chatmail/core/compare/v1.142.12..v1.143.0 +[1.144.0]: https://github.com/chatmail/core/compare/v1.143.0..v1.144.0 +[1.145.0]: https://github.com/chatmail/core/compare/v1.144.0..v1.145.0 +[1.146.0]: https://github.com/chatmail/core/compare/v1.145.0..v1.146.0 +[1.147.0]: https://github.com/chatmail/core/compare/v1.146.0..v1.147.0 +[1.147.1]: https://github.com/chatmail/core/compare/v1.147.0..v1.147.1 +[1.148.0]: https://github.com/chatmail/core/compare/v1.147.1..v1.148.0 +[1.148.1]: https://github.com/chatmail/core/compare/v1.148.0..v1.148.1 +[1.148.2]: https://github.com/chatmail/core/compare/v1.148.1..v1.148.2 +[1.148.3]: https://github.com/chatmail/core/compare/v1.148.2..v1.148.3 +[1.148.4]: https://github.com/chatmail/core/compare/v1.148.3..v1.148.4 +[1.148.5]: https://github.com/chatmail/core/compare/v1.148.4..v1.148.5 +[1.148.6]: https://github.com/chatmail/core/compare/v1.148.5..v1.148.6 +[1.148.7]: https://github.com/chatmail/core/compare/v1.148.6..v1.148.7 +[1.149.0]: https://github.com/chatmail/core/compare/v1.148.7..v1.149.0 +[1.150.0]: https://github.com/chatmail/core/compare/v1.149.0..v1.150.0 +[1.151.0]: https://github.com/chatmail/core/compare/v1.150.0..v1.151.0 +[1.151.1]: https://github.com/chatmail/core/compare/v1.151.0..v1.151.1 +[1.151.2]: https://github.com/chatmail/core/compare/v1.151.1..v1.151.2 +[1.151.3]: https://github.com/chatmail/core/compare/v1.151.2..v1.151.3 +[1.151.4]: https://github.com/chatmail/core/compare/v1.151.3..v1.151.4 +[1.151.5]: https://github.com/chatmail/core/compare/v1.151.4..v1.151.5 +[1.151.6]: https://github.com/chatmail/core/compare/v1.151.5..v1.151.6 +[1.152.0]: https://github.com/chatmail/core/compare/v1.151.6..v1.152.0 +[1.152.1]: https://github.com/chatmail/core/compare/v1.152.0..v1.152.1 +[1.152.2]: https://github.com/chatmail/core/compare/v1.152.1..v1.152.2 +[1.153.0]: https://github.com/chatmail/core/compare/v1.152.2..v1.153.0 +[1.154.0]: https://github.com/chatmail/core/compare/v1.153.0..v1.154.0 +[1.154.1]: https://github.com/chatmail/core/compare/v1.154.0..v1.154.1 +[1.154.2]: https://github.com/chatmail/core/compare/v1.154.1..v1.154.2 +[1.154.3]: https://github.com/chatmail/core/compare/v1.154.2..v1.154.3 +[1.155.0]: https://github.com/chatmail/core/compare/v1.154.3..v1.155.0 +[1.155.1]: https://github.com/chatmail/core/compare/v1.155.0..v1.155.1 +[1.155.2]: https://github.com/chatmail/core/compare/v1.155.1..v1.155.2 +[1.155.3]: https://github.com/chatmail/core/compare/v1.155.2..v1.155.3 +[1.155.4]: https://github.com/chatmail/core/compare/v1.155.3..v1.155.4 +[1.155.5]: https://github.com/chatmail/core/compare/v1.155.4..v1.155.5 +[1.155.6]: https://github.com/chatmail/core/compare/v1.155.5..v1.155.6 +[1.156.0]: https://github.com/chatmail/core/compare/v1.155.6..v1.156.0 +[1.156.1]: https://github.com/chatmail/core/compare/v1.156.0..v1.156.1 +[1.156.2]: https://github.com/chatmail/core/compare/v1.156.1..v1.156.2 +[1.156.3]: https://github.com/chatmail/core/compare/v1.156.2..v1.156.3 +[1.157.0]: https://github.com/chatmail/core/compare/v1.156.3..v1.157.0 +[1.157.1]: https://github.com/chatmail/core/compare/v1.157.0..v1.157.1 +[1.157.2]: https://github.com/chatmail/core/compare/v1.157.1..v1.157.2 +[1.157.3]: https://github.com/chatmail/core/compare/v1.157.2..v1.157.3 +[1.158.0]: https://github.com/chatmail/core/compare/v1.157.3..v1.158.0 +[1.159.0]: https://github.com/chatmail/core/compare/v1.158.0..v1.159.0 +[1.159.1]: https://github.com/chatmail/core/compare/v1.159.0..v1.159.1 +[1.159.2]: https://github.com/chatmail/core/compare/v1.159.1..v1.159.2 +[1.159.3]: https://github.com/chatmail/core/compare/v1.159.2..v1.159.3 +[1.159.4]: https://github.com/chatmail/core/compare/v1.159.3..v1.159.4 +[1.159.5]: https://github.com/chatmail/core/compare/v1.159.4..v1.159.5 +[1.160.0]: https://github.com/chatmail/core/compare/v1.159.5..v1.160.0 +[2.0.0]: https://github.com/chatmail/core/compare/v1.160.0..v2.0.0 +[2.1.0]: https://github.com/chatmail/core/compare/v2.0.0..v2.1.0 +[2.2.0]: https://github.com/chatmail/core/compare/v2.1.0..v2.2.0 +[2.3.0]: https://github.com/chatmail/core/compare/v2.2.0..v2.3.0 +[2.4.0]: https://github.com/chatmail/core/compare/v2.3.0..v2.4.0 +[2.5.0]: https://github.com/chatmail/core/compare/v2.4.0..v2.5.0 +[2.6.0]: https://github.com/chatmail/core/compare/v2.5.0..v2.6.0 +[2.7.0]: https://github.com/chatmail/core/compare/v2.6.0..v2.7.0 +[2.8.0]: https://github.com/chatmail/core/compare/v2.7.0..v2.8.0 +[2.9.0]: https://github.com/chatmail/core/compare/v2.8.0..v2.9.0 +[2.10.0]: https://github.com/chatmail/core/compare/v2.9.0..v2.10.0 +[2.11.0]: https://github.com/chatmail/core/compare/v2.10.0..v2.11.0 +[2.12.0]: https://github.com/chatmail/core/compare/v2.11.0..v2.12.0 +[2.13.0]: https://github.com/chatmail/core/compare/v2.12.0..v2.13.0 +[2.14.0]: https://github.com/chatmail/core/compare/v2.13.0..v2.14.0 +[2.15.0]: https://github.com/chatmail/core/compare/v2.14.0..v2.15.0 +[2.16.0]: https://github.com/chatmail/core/compare/v2.15.0..v2.16.0 +[2.17.0]: https://github.com/chatmail/core/compare/v2.16.0..v2.17.0 +[2.18.0]: https://github.com/chatmail/core/compare/v2.17.0..v2.18.0 +[2.19.0]: https://github.com/chatmail/core/compare/v2.18.0..v2.19.0 +[2.20.0]: https://github.com/chatmail/core/compare/v2.19.0..v2.20.0 +[2.21.0]: https://github.com/chatmail/core/compare/v2.20.0..v2.21.0 +[2.22.0]: https://github.com/chatmail/core/compare/v2.21.0..v2.22.0 +[2.23.0]: https://github.com/chatmail/core/compare/v2.22.0..v2.23.0 +[2.24.0]: https://github.com/chatmail/core/compare/v2.23.0..v2.24.0 +[2.25.0]: https://github.com/chatmail/core/compare/v2.24.0..v2.25.0 +[2.26.0]: https://github.com/chatmail/core/compare/v2.25.0..v2.26.0 +[2.27.0]: https://github.com/chatmail/core/compare/v2.26.0..v2.27.0 +[2.28.0]: https://github.com/chatmail/core/compare/v2.27.0..v2.28.0 +[2.29.0]: https://github.com/chatmail/core/compare/v2.28.0..v2.29.0 +[2.30.0]: https://github.com/chatmail/core/compare/v2.29.0..v2.30.0 +[2.31.0]: https://github.com/chatmail/core/compare/v2.30.0..v2.31.0 +[2.32.0]: https://github.com/chatmail/core/compare/v2.31.0..v2.32.0 +[2.33.0]: https://github.com/chatmail/core/compare/v2.32.0..v2.33.0 +[2.34.0]: https://github.com/chatmail/core/compare/v2.33.0..v2.34.0 +[2.35.0]: https://github.com/chatmail/core/compare/v2.34.0..v2.35.0 +[2.36.0]: https://github.com/chatmail/core/compare/v2.35.0..v2.36.0 diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..8f0f2e450165687bad9ddf4f3f9312ff17e71f5e --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,46 @@ +cmake_minimum_required(VERSION 3.16) +project(deltachat LANGUAGES C) +include(GNUInstallDirs) + +find_program(CARGO cargo) + +if(APPLE) + set(DYNAMIC_EXT "dylib") +elseif(UNIX) + set(DYNAMIC_EXT "so") +else() + set(DYNAMIC_EXT "dll") +endif() + +if(DEFINED ENV{CARGO_BUILD_TARGET}) + set(ARCH_DIR "$ENV{CARGO_BUILD_TARGET}") +else() + set(ARCH_DIR "./") +endif() + +add_custom_command( + OUTPUT + "${CMAKE_BINARY_DIR}/target/release/libdeltachat.a" + "${CMAKE_BINARY_DIR}/target/release/libdeltachat.${DYNAMIC_EXT}" + "${CMAKE_BINARY_DIR}/target/release/pkgconfig/deltachat.pc" + COMMAND + PREFIX=${CMAKE_INSTALL_PREFIX} + LIBDIR=${CMAKE_INSTALL_FULL_LIBDIR} + INCLUDEDIR=${CMAKE_INSTALL_FULL_INCLUDEDIR} + ${CARGO} build --target-dir=${CMAKE_BINARY_DIR}/target --release + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/deltachat-ffi +) + +add_custom_target( + lib_deltachat + ALL + DEPENDS + "${CMAKE_BINARY_DIR}/target/release/libdeltachat.a" + "${CMAKE_BINARY_DIR}/target/release/libdeltachat.${DYNAMIC_EXT}" + "${CMAKE_BINARY_DIR}/target/release/pkgconfig/deltachat.pc" +) + +install(FILES "deltachat-ffi/deltachat.h" DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) +install(FILES "${CMAKE_BINARY_DIR}/target/${ARCH_DIR}/release/libdeltachat.a" DESTINATION ${CMAKE_INSTALL_LIBDIR}) +install(FILES "${CMAKE_BINARY_DIR}/target/${ARCH_DIR}/release/libdeltachat.${DYNAMIC_EXT}" DESTINATION ${CMAKE_INSTALL_LIBDIR}) +install(FILES "${CMAKE_BINARY_DIR}/target/${ARCH_DIR}/release/pkgconfig/deltachat.pc" DESTINATION ${CMAKE_INSTALL_LIBDIR}/pkgconfig) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000000000000000000000000000000000000..47fc28f910c352cace07e326df2cadd630984c14 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,122 @@ +# Contributing to chatmail core + +## Bug reports + +If you found a bug, [report it on GitHub](https://github.com/chatmail/core/issues). +If the bug you found is specific to +[Android](https://github.com/deltachat/deltachat-android/issues), +[iOS](https://github.com/deltachat/deltachat-ios/issues) or +[Desktop](https://github.com/deltachat/deltachat-desktop/issues), +report it to the corresponding repository. + +## Feature proposals + +If you have a feature request, create a new topic on the [forum](https://support.delta.chat/). + +## Code contributions + +If you want to contribute a code, follow this guide. + +1. **Select an issue to work on.** + + If you have an write access to the repository, assign the issue to yourself. + Otherwise state in the comment that you are going to work on the issue + to avoid duplicate work. + + If the issue does not exist yet, create it first. + +2. **Write the code.** + + Follow the [coding conventions](STYLE.md) when writing the code. + +3. **Commit the code.** + + If you have write access to the repository, + push a branch named `/` + so it is clear who is responsible for the branch, + and open a PR proposing to merge the change. + Otherwise fork the repository and create a branch in your fork. + + Commit messages follow the [Conventional Commits] notation. + We use [git-cliff] to generate the changelog from commit messages before the release. + + With **`git cliff --unreleased`**, you can check how the changelog entry for your commit will look. + + The following prefix types are used: + - `feat`: Features, e.g. "feat: Pause IO for BackupProvider". If you are unsure what's the category of your commit, you can often just use `feat`. + - `fix`: Bug fixes, e.g. "fix: delete `smtp` rows when message sending is canceled" + - `api`: API changes, e.g. "api(rust): add `get_msg_read_receipts(context, msg_id)`" + - `refactor`: Refactorings, e.g. "refactor: iterate over `msg_ids` without `.iter()`" + - `perf`: Performance improvements, e.g. "perf: improve SQLite performance with `PRAGMA synchronous=normal`" + - `test`: Test changes and improvements to the testing framework. + - `build`: Build system and tool configuration changes, e.g. "build(git-cliff): put "ci" commits into "CI" section of changelog" + - `ci`: CI configuration changes, e.g. "ci: limit artifact retention time for `libdeltachat.a` to 1 day" + - `docs`: Documentation changes, e.g. "docs: add contributing guidelines" + - `chore`: miscellaneous tasks, e.g. "chore: add `.DS_Store` to `.gitignore`" + + Release preparation commits are marked as "chore(release): prepare for X.Y.Z" + as described in [releasing guide](RELEASE.md). + + Use a `!` to mark breaking changes, e.g. "api!: Remove `dc_chat_can_send`". + + Alternatively, breaking changes can go into the commit description, e.g.: + + ``` + fix: Fix race condition and db corruption when a message was received during backup + + BREAKING CHANGE: You have to call `dc_stop_io()`/`dc_start_io()` before/after `dc_imex(DC_IMEX_EXPORT_BACKUP)` + ``` + +4. [**Open a Pull Request**](https://github.com/chatmail/core/pulls). + + Refer to the corresponding issue. + + If you intend to squash merge the PR from the web interface, + make sure the PR title follows the conventional commits notation + as it will end up being a commit title. + Otherwise make sure each commit title follows the conventional commit notation. + +5. **Make sure all CI checks succeed.** + + CI runs the tests and checks code formatting. + + While it is running, self-review your PR to make sure all the changes you expect are there + and there are no accidentally committed unrelated changes and files. + + Push the necessary fixup commits or force-push to your branch if needed. + +6. **Ask for review.** + + Use built-in GitHub feature to request a review from suggested reviewers. + + If you do not have write access to the repository, ask for review in the comments. + +7. **Merge the PR.** + + Once a PR has an approval and passes CI, it can be merged. + + PRs from a branch created in the main repository, + i.e. authored by those who have write access, are merged by their authors. + + This is to ensure that PRs are merged as intended by the author, + e.g. as a squash merge, by rebasing from the web interface or manually from the command line. + + If you have multiple changes in one PR, do a rebase merge. + Otherwise, you should usually do a squash merge. + + If PR author does not have write access to the repository, + maintainers who reviewed the PR can merge it. + + If you do not have access to the repository and created a PR from a fork, + ask the maintainers to merge the PR and say how it should be merged. + +## Other ways to contribute + +For other ways to contribute, refer to the [website](https://delta.chat/en/contribute). + +You can find the list of good first issues +and a link to this guide +on the contributing page: + +[Conventional Commits]: https://www.conventionalcommits.org/ +[git-cliff]: https://git-cliff.org/ diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000000000000000000000000000000000000..fabddf343ec57c7ae91b1c1663ccf272d7f080cb --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,7487 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "addr2line" +version = "0.24.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dfbe277e56a376000877090da837660b4427aad530e3028d44e0bffe4f89a1c1" +dependencies = [ + "gimli", +] + +[[package]] +name = "adler2" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" + +[[package]] +name = "aead" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d122413f284cf2d62fb1b7db97e02edb8cda96d769b16e443a4f6195e35662b0" +dependencies = [ + "bytes", + "crypto-common", + "generic-array", +] + +[[package]] +name = "aes" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b169f7a6d4742236a0a00c541b845991d0ac43e546831af1249753ab4c3aa3a0" +dependencies = [ + "cfg-if", + "cipher", + "cpufeatures", +] + +[[package]] +name = "aes-gcm" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "831010a0f742e1209b3bcea8fab6a8e149051ba6099432c8cb2cc117dec3ead1" +dependencies = [ + "aead", + "aes", + "cipher", + "ctr", + "ghash", + "subtle", +] + +[[package]] +name = "aes-kw" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69fa2b352dcefb5f7f3a5fb840e02665d311d878955380515e4fd50095dd3d8c" +dependencies = [ + "aes", +] + +[[package]] +name = "aho-corasick" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916" +dependencies = [ + "memchr", +] + +[[package]] +name = "alloc-no-stdlib" +version = "2.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc7bb162ec39d46ab1ca8c77bf72e890535becd1751bb45f64c597edb4c8c6b3" + +[[package]] +name = "alloc-stdlib" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94fb8275041c72129eb51b7d0322c29b8387a0386127718b096429201a5d6ece" +dependencies = [ + "alloc-no-stdlib", +] + +[[package]] +name = "alloca" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e5a7d05ea6aea7e9e64d25b9156ba2fee3fdd659e34e41063cd2fc7cd020d7f4" +dependencies = [ + "cc", +] + +[[package]] +name = "allocator-api2" +version = "0.2.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" + +[[package]] +name = "android_system_properties" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" +dependencies = [ + "libc", +] + +[[package]] +name = "anes" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b46cbb362ab8752921c97e041f5e366ee6297bd428a31275b9fcf1e380f7299" + +[[package]] +name = "anstyle" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8901269c6307e8d93993578286ac0edf7f195079ffff5ebdeea6a59ffb7e36bc" + +[[package]] +name = "anyhow" +version = "1.0.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a23eb6b1614318a8071c9b2521f36b424b2c83db5eb3a0fead4a6c0809af6e61" +dependencies = [ + "backtrace", +] + +[[package]] +name = "argon2" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c3610892ee6e0cbce8ae2700349fcf8f98adb0dbfbee85aec3c9179d29cc072" +dependencies = [ + "base64ct", + "blake2", + "cpufeatures", + "password-hash", + "zeroize", +] + +[[package]] +name = "arrayref" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76a2e8124351fda1ef8aaaa3bbd7ebbcb486bbcd4225aca0aa0d84bb2db8fecb" + +[[package]] +name = "arrayvec" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" + +[[package]] +name = "asn1-rs" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5493c3bedbacf7fd7382c6346bbd66687d12bbaad3a89a2d2c303ee6cf20b048" +dependencies = [ + "asn1-rs-derive", + "asn1-rs-impl", + "displaydoc", + "nom 7.1.3", + "num-traits", + "rusticata-macros", + "thiserror 1.0.69", + "time", +] + +[[package]] +name = "asn1-rs-derive" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "965c2d33e53cb6b267e148a4cb0760bc01f4904c1cd4bb4002a085bb016d1490" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.111", + "synstructure", +] + +[[package]] +name = "asn1-rs-impl" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b18050c2cd6fe86c3a76584ef5e0baf286d038cda203eb6223df2cc413565f7" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.111", +] + +[[package]] +name = "astral-tokio-tar" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec179a06c1769b1e42e1e2cbe74c7dcdb3d6383c838454d063eaac5bbb7ebbe5" +dependencies = [ + "filetime", + "futures-core", + "libc", + "portable-atomic", + "rustc-hash", + "tokio", + "tokio-stream", +] + +[[package]] +name = "async-broadcast" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "435a87a52755b8f27fcf321ac4f04b2802e337c8c4872923137471ec39c37532" +dependencies = [ + "event-listener 5.4.0", + "event-listener-strategy", + "futures-core", + "pin-project-lite", +] + +[[package]] +name = "async-channel" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81953c529336010edd6d8e358f886d9581267795c61b19475b71314bffa46d35" +dependencies = [ + "concurrent-queue", + "event-listener 2.5.3", + "futures-core", +] + +[[package]] +name = "async-channel" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "924ed96dd52d1b75e9c1a3e6275715fd320f5f9439fb5a4a11fa51f4221158d2" +dependencies = [ + "concurrent-queue", + "event-listener-strategy", + "futures-core", + "pin-project-lite", +] + +[[package]] +name = "async-compat" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7bab94bde396a3f7b4962e396fdad640e241ed797d4d8d77fc8c237d14c58fc0" +dependencies = [ + "futures-core", + "futures-io", + "once_cell", + "pin-project-lite", + "tokio", +] + +[[package]] +name = "async-compression" +version = "0.4.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0cf008e5e1a9e9e22a7d3c9a4992e21a350290069e36d8fb72304ed17e8f2d2" +dependencies = [ + "flate2", + "futures-core", + "futures-io", + "memchr", + "pin-project-lite", + "tokio", +] + +[[package]] +name = "async-imap" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8da885da5980f3934831e6370445c0e0e44ef251d7792308b39e908915a41d09" +dependencies = [ + "async-channel 2.5.0", + "async-compression", + "base64", + "bytes", + "chrono", + "futures", + "imap-proto", + "log", + "nom 7.1.3", + "pin-project", + "pin-utils", + "self_cell", + "stop-token", + "thiserror 1.0.69", + "tokio", +] + +[[package]] +name = "async-lock" +version = "3.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff6e472cdea888a4bd64f342f09b3f50e1886d32afe8df3d663c01140b811b18" +dependencies = [ + "event-listener 5.4.0", + "event-listener-strategy", + "pin-project-lite", +] + +[[package]] +name = "async-native-tls" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9343dc5acf07e79ff82d0c37899f079db3534d99f189a1837c8e549c99405bec" +dependencies = [ + "native-tls", + "thiserror 1.0.69", + "tokio", + "url", +] + +[[package]] +name = "async-smtp" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55219982f938e74491ba85dc4e49cefe8096b1e8f49348c67180a7d244988dca" +dependencies = [ + "anyhow", + "base64", + "futures", + "log", + "nom 8.0.0", + "pin-project", + "thiserror 2.0.17", + "tokio", +] + +[[package]] +name = "async-trait" +version = "0.1.86" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "644dd749086bf3771a2fbc5f256fdb982d53f011c7d5d560304eafeecebce79d" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.111", +] + +[[package]] +name = "async_io_stream" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6d7b9decdf35d8908a7e3ef02f64c5e9b1695e230154c0e8de3969142d9b94c" +dependencies = [ + "futures", + "pharos", + "rustc_version", +] + +[[package]] +name = "async_zip" +version = "0.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d8c50d65ce1b0e0cb65a785ff615f78860d7754290647d3b983208daa4f85e6" +dependencies = [ + "async-compression", + "crc32fast", + "futures-lite", + "pin-project", + "thiserror 2.0.17", + "tokio", + "tokio-util", +] + +[[package]] +name = "atomic-waker" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" + +[[package]] +name = "attohttpc" +version = "0.24.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d9a9bf8b79a749ee0b911b91b671cc2b6c670bdbc7e3dfd537576ddc94bb2a2" +dependencies = [ + "http 0.2.12", + "log", + "url", +] + +[[package]] +name = "autocfg" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" + +[[package]] +name = "backon" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd0b50b1b78dbadd44ab18b3c794e496f3a139abb9fbc27d9c94c4eebbb96496" +dependencies = [ + "fastrand", + "gloo-timers", + "tokio", +] + +[[package]] +name = "backtrace" +version = "0.3.75" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6806a6321ec58106fea15becdad98371e28d92ccbc7c8f1b3b6dd724fe8f1002" +dependencies = [ + "addr2line", + "cfg-if", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", + "windows-targets 0.52.6", +] + +[[package]] +name = "base16ct" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" + +[[package]] +name = "base32" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "022dfe9eb35f19ebbcb51e0b40a5ab759f46ad60cadf7297e0bd085afb50e076" + +[[package]] +name = "base64" +version = "0.22.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" + +[[package]] +name = "base64ct" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" + +[[package]] +name = "bitfields" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dcdbce6688e3ab66aff2ab413b762ccde9f37990e27bba0bb38a4b2ad1b5d877" +dependencies = [ + "bitfields-impl", +] + +[[package]] +name = "bitfields-impl" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57413e4b276d883b77fb368b7b33ae6a5eb97692852d49a5394d4f72ba961827" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.111", + "thiserror 2.0.17", +] + +[[package]] +name = "bitflags" +version = "1.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" + +[[package]] +name = "bitflags" +version = "2.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b8e56985ec62d17e9c1001dc89c88ecd7dc08e47eba5ec7c29c7b5eeecde967" + +[[package]] +name = "bitvec" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c" +dependencies = [ + "funty", + "radium", + "tap", + "wyz", +] + +[[package]] +name = "blake2" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46502ad458c9a52b69d4d4d32775c788b7a1b85e8bc9d482d92250fc0e3f8efe" +dependencies = [ + "digest", +] + +[[package]] +name = "blake3" +version = "1.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3888aaa89e4b2a40fca9848e400f6a658a5a3978de7be858e209cafa8be9a4a0" +dependencies = [ + "arrayref", + "arrayvec", + "cc", + "cfg-if", + "constant_time_eq", +] + +[[package]] +name = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array", +] + +[[package]] +name = "block-padding" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8894febbff9f758034a5b8e12d87918f56dfc64a8e1fe757d65e29041538d93" +dependencies = [ + "generic-array", +] + +[[package]] +name = "blowfish" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e412e2cd0f2b2d93e02543ceae7917b3c70331573df19ee046bcbc35e45e87d7" +dependencies = [ + "byteorder", + "cipher", +] + +[[package]] +name = "bolero" +version = "0.13.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ff44d278fc0062c95327087ed96b3d256906d1d8f579e534a3de8d6b386913a" +dependencies = [ + "bolero-afl", + "bolero-engine", + "bolero-generator", + "bolero-honggfuzz", + "bolero-kani", + "bolero-libfuzzer", + "cfg-if", + "rand 0.9.2", +] + +[[package]] +name = "bolero-afl" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9bf4cbd0bacf9356d3c7e5d9d088480f2076ba3c595c15ee9a6a378cdd7b297" +dependencies = [ + "bolero-engine", + "cc", +] + +[[package]] +name = "bolero-engine" +version = "0.13.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dca199170a7c92c669c1019f9219a316b66bcdcfa4b36cac5a460a4c1a851aba" +dependencies = [ + "anyhow", + "bolero-generator", + "lazy_static", + "pretty-hex", + "rand 0.9.2", + "rand_xoshiro", +] + +[[package]] +name = "bolero-generator" +version = "0.13.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "98a5782f2650f80d533f58ec339c6dce4cc5428f9c2755894f98156f52af81f2" +dependencies = [ + "bolero-generator-derive", + "either", + "getrandom 0.3.3", + "rand_core 0.9.3", + "rand_xoshiro", +] + +[[package]] +name = "bolero-generator-derive" +version = "0.13.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a21a3b022507b9edd2050caf370d945e398c1a7c8455531220fa3968c45d29e" +dependencies = [ + "proc-macro-crate 2.0.0", + "proc-macro2", + "quote", + "syn 2.0.111", +] + +[[package]] +name = "bolero-honggfuzz" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a118ef27295eddefadc6a99728ee698d1b18d2e80dc4777d21bee3385096ffd" +dependencies = [ + "bolero-engine", +] + +[[package]] +name = "bolero-kani" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "852ea5784a9f3e68bfd302ca80b8b863bce140593eb5770fee6ab110899c28fc" +dependencies = [ + "bolero-engine", +] + +[[package]] +name = "bolero-libfuzzer" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "858dc57c11725c52662501fa79fdbc6f7050339a05ca1bf1e587add0fed40d62" +dependencies = [ + "bolero-engine", + "cc", +] + +[[package]] +name = "bounded-integer" +version = "0.5.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "102dbef1187b1893e6dfe05a774e79fd52265f49f214f6879c8ff49f52c8188b" + +[[package]] +name = "brotli" +version = "8.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4bd8b9603c7aa97359dbd97ecf258968c95f3adddd6db2f7e7a5bef101c84560" +dependencies = [ + "alloc-no-stdlib", + "alloc-stdlib", + "brotli-decompressor", +] + +[[package]] +name = "brotli-decompressor" +version = "5.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "874bb8112abecc98cbd6d81ea4fa7e94fb9449648c93cc89aa40c81c24d7de03" +dependencies = [ + "alloc-no-stdlib", + "alloc-stdlib", +] + +[[package]] +name = "buffer-redux" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e8acf87c5b9f5897cd3ebb9a327f420e0cae9dd4e5c1d2e36f2c84c571a58f1" +dependencies = [ + "memchr", +] + +[[package]] +name = "bumpalo" +version = "3.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1628fb46dfa0b37568d12e5edd512553eccf6a22a78e8bde00bb4aed84d5bdbf" + +[[package]] +name = "byte_string" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11aade7a05aa8c3a351cedc44c3fc45806430543382fcc4743a9b757a2a0b4ed" + +[[package]] +name = "bytemuck" +version = "1.23.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9134a6ef01ce4b366b50689c94f82c14bc72bc5d0386829828a2e2752ef7958c" + +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + +[[package]] +name = "byteorder-lite" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f1fe948ff07f4bd06c30984e69f5b4899c516a3ef74f34df92a2df2ab535495" + +[[package]] +name = "bytes" +version = "1.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b35204fbdc0b3f4446b89fc1ac2cf84a8a68971995d0bf2e925ec7cd960f9cb3" +dependencies = [ + "serde", +] + +[[package]] +name = "camellia" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3264e2574e9ef2b53ce6f536dea83a69ac0bc600b762d1523ff83fe07230ce30" +dependencies = [ + "byteorder", + "cipher", +] + +[[package]] +name = "camino" +version = "1.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b96ec4966b5813e2c0507c1f86115c8c5abaadc3980879c3424042a02fd1ad3" +dependencies = [ + "serde", +] + +[[package]] +name = "cargo-platform" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24b1f0365a6c6bb4020cd05806fd0d33c44d38046b8bd7f0e40814b9763cabfc" +dependencies = [ + "serde", +] + +[[package]] +name = "cargo_metadata" +version = "0.14.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4acbb09d9ee8e23699b9634375c72795d095bf268439da88562cf9b501f181fa" +dependencies = [ + "camino", + "cargo-platform", + "semver", + "serde", + "serde_json", +] + +[[package]] +name = "cast" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5" + +[[package]] +name = "cast5" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26b07d673db1ccf000e90f54b819db9e75a8348d6eb056e9b8ab53231b7a9911" +dependencies = [ + "cipher", +] + +[[package]] +name = "cc" +version = "1.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c3d1b2e905a3a7b00a6141adb0e4c0bb941d11caf55349d863942a1cc44e3c9" +dependencies = [ + "shlex", +] + +[[package]] +name = "cfb-mode" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "738b8d467867f80a71351933f70461f5b56f24d5c93e0cf216e59229c968d330" +dependencies = [ + "cipher", +] + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "cfg_aliases" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" + +[[package]] +name = "chacha20" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3613f74bd2eac03dad61bd53dbe620703d4371614fe0bc3b9f04dd36fe4e818" +dependencies = [ + "cfg-if", + "cipher", + "cpufeatures", +] + +[[package]] +name = "chacha20poly1305" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10cd79432192d1c0f4e1a0fef9527696cc039165d729fb41b3f4f4f354c2dc35" +dependencies = [ + "aead", + "chacha20", + "cipher", + "poly1305", + "zeroize", +] + +[[package]] +name = "charset" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1f927b07c74ba84c7e5fe4db2baeb3e996ab2688992e39ac68ce3220a677c7e" +dependencies = [ + "base64", + "encoding_rs", +] + +[[package]] +name = "chrono" +version = "0.4.42" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "145052bdd345b87320e369255277e3fb5152762ad123a901ef5c262dd38fe8d2" +dependencies = [ + "iana-time-zone", + "num-traits", + "serde", + "windows-link", +] + +[[package]] +name = "ciborium" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42e69ffd6f0917f5c029256a24d0161db17cea3997d185db0d35926308770f0e" +dependencies = [ + "ciborium-io", + "ciborium-ll", + "serde", +] + +[[package]] +name = "ciborium-io" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05afea1e0a06c9be33d539b876f1ce3692f4afea2cb41f740e7743225ed1c757" + +[[package]] +name = "ciborium-ll" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57663b653d948a338bfb3eeba9bb2fd5fcfaecb9e199e87e1eda4d9e8b240fd9" +dependencies = [ + "ciborium-io", + "half", +] + +[[package]] +name = "cipher" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" +dependencies = [ + "crypto-common", + "inout", + "zeroize", +] + +[[package]] +name = "clap" +version = "4.5.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fbb260a053428790f3de475e304ff84cdbc4face759ea7a3e64c1edd938a7fc" +dependencies = [ + "clap_builder", +] + +[[package]] +name = "clap_builder" +version = "4.5.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64b17d7ea74e9f833c7dbf2cbe4fb12ff26783eda4782a8975b72f895c9b4d99" +dependencies = [ + "anstyle", + "clap_lex", +] + +[[package]] +name = "clap_lex" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f46ad14479a25103f283c0f10005961cf086d8dc42205bb44c46ac563475dca6" + +[[package]] +name = "clipboard-win" +version = "5.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "15efe7a882b08f34e38556b14f2fb3daa98769d06c7f0c1b076dfd0d983bc892" +dependencies = [ + "error-code", +] + +[[package]] +name = "cmac" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8543454e3c3f5126effff9cd44d562af4e31fb8ce1cc0d3dcd8f084515dbc1aa" +dependencies = [ + "cipher", + "dbl", + "digest", +] + +[[package]] +name = "cobs" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67ba02a97a2bd10f4b59b25c7973101c79642302776489e030cd13cdab09ed15" + +[[package]] +name = "color_quant" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b" + +[[package]] +name = "colorutils-rs" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "103c2458789cd7b46e6ed7c7ba1bf969b6569c902e3732843c55962c53eac686" +dependencies = [ + "erydanos", + "half", + "num-traits", +] + +[[package]] +name = "concurrent-queue" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ca0197aee26d1ae37445ee532fefce43251d24cc7c166799f4d46817f1d3973" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "const-oid" +version = "0.9.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" + +[[package]] +name = "constant_time_eq" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7c74b8349d32d297c9134b8c88677813a227df8f779daa29bfc29c183fe3dca6" + +[[package]] +name = "convert_case" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb4a24b1aaf0fd0ce8b45161144d6f42cd91677fd5940fd431183eb023b3a2b8" + +[[package]] +name = "cordyceps" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "688d7fbb8092b8de775ef2536f36c8c31f2bc4006ece2e8d8ad2d17d00ce0a2a" +dependencies = [ + "loom", + "tracing", +] + +[[package]] +name = "core-foundation" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "core-foundation-sys" +version = "0.8.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" + +[[package]] +name = "cpufeatures" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280" +dependencies = [ + "libc", +] + +[[package]] +name = "crc" +version = "3.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69e6e4d7b33a94f0991c26729976b10ebde1d34c3ee82408fb536164fa10d636" +dependencies = [ + "crc-catalog", +] + +[[package]] +name = "crc-catalog" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19d374276b40fb8bbdee95aef7c7fa6b5316ec764510eb64b8dd0e2ed0d7e7f5" + +[[package]] +name = "crc24" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd121741cf3eb82c08dd3023eb55bf2665e5f60ec20f89760cf836ae4562e6a0" + +[[package]] +name = "crc32fast" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "criterion" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d883447757bb0ee46f233e9dc22eb84d93a9508c9b868687b274fc431d886bf" +dependencies = [ + "alloca", + "anes", + "cast", + "ciborium", + "clap", + "criterion-plot", + "itertools", + "num-traits", + "oorandom", + "page_size", + "plotters", + "rayon", + "regex", + "serde", + "serde_json", + "tinytemplate", + "tokio", + "walkdir", +] + +[[package]] +name = "criterion-plot" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed943f81ea2faa8dcecbbfa50164acf95d555afec96a27871663b300e387b2e4" +dependencies = [ + "cast", + "itertools", +] + +[[package]] +name = "critical-section" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "790eea4361631c5e7d22598ecd5723ff611904e3344ce8720784c93e3d83d40b" + +[[package]] +name = "crossbeam-channel" +version = "0.5.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "82b8f8f868b36967f9606790d1903570de9ceaf870a7bf9fbbd3016d636a2cb2" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-deque" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9dd111b7b7f7d55b72c0a6ae361660ee5853c9af73f70c3c2ef6858b950e2e51" +dependencies = [ + "crossbeam-epoch", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.9.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-utils" +version = "0.8.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" + +[[package]] +name = "crossterm" +version = "0.28.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "829d955a0bb380ef178a640b91779e3987da38c9aea133b20614cfed8cdea9c6" +dependencies = [ + "bitflags 2.9.1", + "crossterm_winapi", + "parking_lot", + "rustix 0.38.44", + "winapi", +] + +[[package]] +name = "crossterm_winapi" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "acdd7c62a3665c7f6830a51635d9ac9b23ed385797f70a83bb8bafe9c572ab2b" +dependencies = [ + "winapi", +] + +[[package]] +name = "crunchy" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43da5946c66ffcc7745f48db692ffbb10a83bfe0afd96235c5c2a4fb23994929" + +[[package]] +name = "crypto-bigint" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0dc92fb57ca44df6db8059111ab3af99a63d5d0f8375d9972e319a379c6bab76" +dependencies = [ + "generic-array", + "rand_core 0.6.4", + "subtle", + "zeroize", +] + +[[package]] +name = "crypto-common" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +dependencies = [ + "generic-array", + "rand_core 0.6.4", + "typenum", +] + +[[package]] +name = "crypto_box" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16182b4f39a82ec8a6851155cc4c0cda3065bb1db33651726a29e1951de0f009" +dependencies = [ + "aead", + "chacha20", + "crypto_secretbox", + "curve25519-dalek", + "salsa20", + "serdect 0.2.0", + "subtle", + "zeroize", +] + +[[package]] +name = "crypto_secretbox" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9d6cf87adf719ddf43a805e92c6870a531aedda35ff640442cbaf8674e141e1" +dependencies = [ + "aead", + "chacha20", + "cipher", + "generic-array", + "poly1305", + "salsa20", + "subtle", + "zeroize", +] + +[[package]] +name = "ctr" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0369ee1ad671834580515889b80f2ea915f23b8be8d0daa4bbaf2ac5c7590835" +dependencies = [ + "cipher", +] + +[[package]] +name = "curve25519-dalek" +version = "4.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97fb8b7c4503de7d6ae7b42ab72a5a59857b4c937ec27a3d4539dba95b5ab2be" +dependencies = [ + "cfg-if", + "cpufeatures", + "curve25519-dalek-derive", + "digest", + "fiat-crypto", + "rand_core 0.6.4", + "rustc_version", + "serde", + "subtle", + "zeroize", +] + +[[package]] +name = "curve25519-dalek-derive" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.111", +] + +[[package]] +name = "cx448" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4c0cf476284b03eb6c10e78787b21c7abb7d7d43cb2f02532ba6b831ed892fa" +dependencies = [ + "crypto-bigint", + "elliptic-curve", + "pkcs8", + "rand_core 0.6.4", + "serdect 0.3.0", + "sha3", + "signature", + "subtle", + "zeroize", +] + +[[package]] +name = "darling" +version = "0.20.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f63b86c8a8826a49b8c21f08a2d07338eec8d900540f8630dc76284be802989" +dependencies = [ + "darling_core", + "darling_macro", +] + +[[package]] +name = "darling_core" +version = "0.20.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95133861a8032aaea082871032f5815eb9e98cef03fa916ab4500513994df9e5" +dependencies = [ + "fnv", + "ident_case", + "proc-macro2", + "quote", + "strsim", + "syn 2.0.111", +] + +[[package]] +name = "darling_macro" +version = "0.20.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d336a2a514f6ccccaa3e09b02d41d35330c07ddf03a62165fcec10bb561c7806" +dependencies = [ + "darling_core", + "quote", + "syn 2.0.111", +] + +[[package]] +name = "data-encoding" +version = "2.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a2330da5de22e8a3cb63252ce2abb30116bf5265e89c0e01bc17015ce30a476" + +[[package]] +name = "dbl" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd2735a791158376708f9347fe8faba9667589d82427ef3aed6794a8981de3d9" +dependencies = [ + "generic-array", +] + +[[package]] +name = "deltachat" +version = "2.36.0" +dependencies = [ + "anyhow", + "astral-tokio-tar", + "async-broadcast", + "async-channel 2.5.0", + "async-imap", + "async-native-tls", + "async-smtp", + "async_zip", + "base64", + "blake3", + "brotli", + "bytes", + "chrono", + "colorutils-rs", + "criterion", + "data-encoding", + "deltachat-contact-tools", + "deltachat-time", + "deltachat_derive", + "escaper", + "fast-socks5", + "fd-lock", + "format-flowed", + "futures", + "futures-lite", + "hex", + "http-body-util", + "humansize", + "hyper", + "hyper-util", + "image", + "iroh", + "iroh-gossip", + "kamadak-exif", + "libc", + "log", + "mail-builder", + "mailparse", + "mime", + "nu-ansi-term", + "num-derive", + "num-traits", + "num_cpus", + "parking_lot", + "percent-encoding", + "pgp", + "pin-project", + "pretty_assertions", + "proptest", + "qrcodegen", + "quick-xml", + "rand 0.8.5", + "rand 0.9.2", + "ratelimit", + "regex", + "rusqlite", + "rustls-pki-types", + "sanitize-filename", + "sdp", + "serde", + "serde_json", + "serde_urlencoded", + "sha-1", + "sha2", + "shadowsocks", + "smallvec", + "strum 0.27.2", + "strum_macros 0.27.2", + "tagger", + "tempfile", + "testdir", + "textwrap", + "thiserror 2.0.17", + "tokio", + "tokio-io-timeout", + "tokio-rustls", + "tokio-stream", + "tokio-util", + "toml", + "tracing", + "url", + "uuid", + "walkdir", + "webpki-roots", +] + +[[package]] +name = "deltachat-contact-tools" +version = "0.0.0" +dependencies = [ + "anyhow", + "chrono", + "regex", + "rusqlite", +] + +[[package]] +name = "deltachat-fuzz" +version = "0.0.0" +dependencies = [ + "bolero", + "deltachat", + "format-flowed", + "mailparse", +] + +[[package]] +name = "deltachat-jsonrpc" +version = "2.36.0" +dependencies = [ + "anyhow", + "async-channel 2.5.0", + "base64", + "deltachat", + "deltachat-contact-tools", + "futures", + "num-traits", + "sanitize-filename", + "schemars", + "serde", + "serde_json", + "tempfile", + "tokio", + "typescript-type-def", + "yerpc", +] + +[[package]] +name = "deltachat-repl" +version = "2.36.0" +dependencies = [ + "anyhow", + "deltachat", + "dirs", + "log", + "nu-ansi-term", + "qr2term", + "rusqlite", + "rustyline", + "tokio", + "tracing-subscriber", +] + +[[package]] +name = "deltachat-rpc-server" +version = "2.36.0" +dependencies = [ + "anyhow", + "deltachat", + "deltachat-jsonrpc", + "futures-lite", + "log", + "serde", + "serde_json", + "tokio", + "tokio-util", + "tracing-subscriber", + "yerpc", +] + +[[package]] +name = "deltachat-time" +version = "1.0.0" + +[[package]] +name = "deltachat_derive" +version = "2.0.0" +dependencies = [ + "quote", + "syn 2.0.111", +] + +[[package]] +name = "deltachat_ffi" +version = "2.36.0" +dependencies = [ + "anyhow", + "deltachat", + "deltachat-jsonrpc", + "human-panic", + "libc", + "num-traits", + "rand 0.9.2", + "serde_json", + "thiserror 2.0.17", + "tokio", + "yerpc", +] + +[[package]] +name = "der" +version = "0.7.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f55bf8e7b65898637379c1b74eb1551107c8294ed26d855ceb9fd1a09cfc9bc0" +dependencies = [ + "const-oid", + "der_derive", + "pem-rfc7468", + "zeroize", +] + +[[package]] +name = "der-parser" +version = "9.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5cd0a5c643689626bec213c4d8bd4d96acc8ffdb4ad4bb6bc16abf27d5f4b553" +dependencies = [ + "asn1-rs", + "displaydoc", + "nom 7.1.3", + "num-bigint", + "num-traits", + "rusticata-macros", +] + +[[package]] +name = "der_derive" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8034092389675178f570469e6c3b0465d3d30b4505c294a6550db47f3c17ad18" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.111", +] + +[[package]] +name = "deranged" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4" +dependencies = [ + "powerfmt", +] + +[[package]] +name = "derive_builder" +version = "0.20.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "507dfb09ea8b7fa618fcf76e953f4f5e192547945816d5358edffe39f6f94947" +dependencies = [ + "derive_builder_macro", +] + +[[package]] +name = "derive_builder_core" +version = "0.20.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d5bcf7b024d6835cfb3d473887cd966994907effbe9227e8c8219824d06c4e8" +dependencies = [ + "darling", + "proc-macro2", + "quote", + "syn 2.0.111", +] + +[[package]] +name = "derive_builder_macro" +version = "0.20.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab63b0e2bf4d5928aff72e83a7dace85d7bba5fe12dcc3c5a572d78caffd3f3c" +dependencies = [ + "derive_builder_core", + "syn 2.0.111", +] + +[[package]] +name = "derive_more" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a9b99b9cbbe49445b21764dc0625032a89b145a2642e67603e1c936f5458d05" +dependencies = [ + "derive_more-impl 1.0.0", +] + +[[package]] +name = "derive_more" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "093242cf7570c207c83073cf82f79706fe7b8317e98620a47d5be7c3d8497678" +dependencies = [ + "derive_more-impl 2.0.1", +] + +[[package]] +name = "derive_more-impl" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb7330aeadfbe296029522e6c40f315320aba36fc43a5b3632f3795348f3bd22" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.111", + "unicode-xid", +] + +[[package]] +name = "derive_more-impl" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bda628edc44c4bb645fbe0f758797143e4e07926f7ebf4e9bdfbd3d2ce621df3" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.111", + "unicode-xid", +] + +[[package]] +name = "des" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffdd80ce8ce993de27e9f063a444a4d53ce8e8db4c1f00cc03af5ad5a9867a1e" +dependencies = [ + "cipher", +] + +[[package]] +name = "diatomic-waker" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab03c107fafeb3ee9f5925686dbb7a73bc76e3932abb0d2b365cb64b169cf04c" + +[[package]] +name = "diff" +version = "0.1.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56254986775e3233ffa9c4d7d3faaf6d36a2c09d30b20687e9f88bc8bafc16c8" + +[[package]] +name = "digest" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +dependencies = [ + "block-buffer", + "const-oid", + "crypto-common", + "subtle", +] + +[[package]] +name = "dirs" +version = "6.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3e8aa94d75141228480295a7d0e7feb620b1a5ad9f12bc40be62411e38cce4e" +dependencies = [ + "dirs-sys", +] + +[[package]] +name = "dirs-sys" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e01a3366d27ee9890022452ee61b2b63a67e6f13f58900b651ff5665f0bb1fab" +dependencies = [ + "libc", + "option-ext", + "redox_users", + "windows-sys 0.61.1", +] + +[[package]] +name = "displaydoc" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "487585f4d0c6655fe74905e2504d8ad6908e4db67f744eb140876906c2f3175d" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.111", +] + +[[package]] +name = "dlopen2" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09b4f5f101177ff01b8ec4ecc81eead416a8aa42819a2869311b3420fa114ffa" +dependencies = [ + "libc", + "once_cell", + "winapi", +] + +[[package]] +name = "document-features" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95249b50c6c185bee49034bcb378a49dc2b5dff0be90ff6616d31d64febab05d" +dependencies = [ + "litrs", +] + +[[package]] +name = "dsa" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48bc224a9084ad760195584ce5abb3c2c34a225fa312a128ad245a6b412b7689" +dependencies = [ + "digest", + "num-bigint-dig", + "num-traits", + "pkcs8", + "rfc6979", + "sha2", + "signature", + "zeroize", +] + +[[package]] +name = "dyn-clone" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "feeef44e73baff3a26d371801df019877a9866a8c493d315ab00177843314f35" + +[[package]] +name = "dynosaur" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "277b2cb52d2df4acece06bb16bc0bb0a006970c7bf504eac2d310927a6f65890" +dependencies = [ + "dynosaur_derive", + "trait-variant", +] + +[[package]] +name = "dynosaur_derive" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a4102713839a8c01c77c165bc38ef2e83948f6397fa1e1dcfacec0f07b149d3" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.111", +] + +[[package]] +name = "eax" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9954fabd903b82b9d7a68f65f97dc96dd9ad368e40ccc907a7c19d53e6bfac28" +dependencies = [ + "aead", + "cipher", + "cmac", + "ctr", + "subtle", +] + +[[package]] +name = "ecdsa" +version = "0.16.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee27f32b5c5292967d2d4a9d7f1e0b0aed2c15daded5a60300e4abb9d8020bca" +dependencies = [ + "der", + "digest", + "elliptic-curve", + "rfc6979", + "signature", + "spki", +] + +[[package]] +name = "ed25519" +version = "2.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "115531babc129696a58c64a4fef0a8bf9e9698629fb97e9e40767d235cfbcd53" +dependencies = [ + "pkcs8", + "serde", + "signature", +] + +[[package]] +name = "ed25519-dalek" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a3daa8e81a3963a60642bcc1f90a670680bd4a77535faa384e9d1c79d620871" +dependencies = [ + "curve25519-dalek", + "ed25519", + "rand_core 0.6.4", + "serde", + "sha2", + "subtle", + "zeroize", +] + +[[package]] +name = "either" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0" + +[[package]] +name = "elliptic-curve" +version = "0.13.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5e6043086bf7973472e0c7dff2142ea0b680d30e18d9cc40f267efbf222bd47" +dependencies = [ + "base16ct", + "base64ct", + "crypto-bigint", + "digest", + "ff", + "generic-array", + "group", + "hkdf", + "pem-rfc7468", + "pkcs8", + "rand_core 0.6.4", + "sec1", + "serde_json", + "serdect 0.2.0", + "subtle", + "tap", + "zeroize", +] + +[[package]] +name = "embedded-io" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef1a6892d9eef45c8fa6b9e0086428a2cca8491aca8f787c534a3d6d0bcb3ced" + +[[package]] +name = "embedded-io" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "edd0f118536f44f5ccd48bcb8b111bdc3de888b58c74639dfb034a357d0f206d" + +[[package]] +name = "encoding_rs" +version = "0.8.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75030f3c4f45dafd7586dd6780965a8c7e8e285a5ecb86713e63a79c5b2766f3" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "endian-type" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c34f04666d835ff5d62e058c3995147c06f42fe86ff053337632bca83e42702d" + +[[package]] +name = "entities" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b5320ae4c3782150d900b79807611a59a99fc9a1d61d686faafc24b93fc8d7ca" + +[[package]] +name = "enum-as-inner" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5ffccbb6966c05b32ef8fbac435df276c4ae4d3dc55a8cd0eb9745e6c12f546a" +dependencies = [ + "heck 0.4.1", + "proc-macro2", + "quote", + "syn 2.0.111", +] + +[[package]] +name = "enumflags2" +version = "0.7.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba2f4b465f5318854c6f8dd686ede6c0a9dc67d4b1ac241cf0eb51521a309147" +dependencies = [ + "enumflags2_derive", +] + +[[package]] +name = "enumflags2_derive" +version = "0.7.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc4caf64a58d7a6d65ab00639b046ff54399a39f5f2554728895ace4b297cd79" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.111", +] + +[[package]] +name = "equivalent" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" + +[[package]] +name = "errno" +version = "0.3.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33d852cb9b869c2a9b3df2f71a3074817f01e1844f839a144f5fcef059a4eb5d" +dependencies = [ + "libc", + "windows-sys 0.59.0", +] + +[[package]] +name = "error-code" +version = "3.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5d9305ccc6942a704f4335694ecd3de2ea531b114ac2d51f5f843750787a92f" + +[[package]] +name = "erydanos" +version = "0.2.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8cbdc4987ed8e9ece64845393c2d53596b3a4ccbfb3948d799d58f6450e89fb1" +dependencies = [ + "num-traits", +] + +[[package]] +name = "escaper" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a53eb97b7349ba1bdb31839eceafe9aaae8f1d8d944dc589b67fb0b26e1c1666" +dependencies = [ + "entities", +] + +[[package]] +name = "event-listener" +version = "2.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" + +[[package]] +name = "event-listener" +version = "5.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3492acde4c3fc54c845eaab3eed8bd00c7a7d881f78bfc801e43a93dec1331ae" +dependencies = [ + "concurrent-queue", + "parking", + "pin-project-lite", +] + +[[package]] +name = "event-listener-strategy" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8be9f3dfaaffdae2972880079a491a1a8bb7cbed0b8dd7a347f668b4150a3b93" +dependencies = [ + "event-listener 5.4.0", + "pin-project-lite", +] + +[[package]] +name = "fallible-iterator" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2acce4a10f12dc2fb14a218589d4f1f62ef011b2d0cc4b3cb1bba8e94da14649" + +[[package]] +name = "fallible-streaming-iterator" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7360491ce676a36bf9bb3c56c1aa791658183a54d2744120f27285738d90465a" + +[[package]] +name = "fast-socks5" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d09fe4a491909a716088083eeb5bcc25427330fdbcd4ecd3dfa5469b3da795df" +dependencies = [ + "anyhow", + "async-trait", + "log", + "thiserror 1.0.69", + "tokio", + "tokio-stream", +] + +[[package]] +name = "fastrand" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" + +[[package]] +name = "fd-lock" +version = "4.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ce92ff622d6dadf7349484f42c93271a0d49b7cc4d466a936405bacbe10aa78" +dependencies = [ + "cfg-if", + "rustix 1.1.3", + "windows-sys 0.59.0", +] + +[[package]] +name = "fdeflate" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e6853b52649d4ac5c0bd02320cddc5ba956bdb407c4b75a2c6b75bf51500f8c" +dependencies = [ + "simd-adler32", +] + +[[package]] +name = "ff" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ded41244b729663b1e574f1b4fb731469f69f79c17667b5d776b16cda0479449" +dependencies = [ + "bitvec", + "rand_core 0.6.4", + "subtle", +] + +[[package]] +name = "fiat-crypto" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28dea519a9695b9977216879a3ebfddf92f1c08c05d984f8996aecd6ecdc811d" + +[[package]] +name = "filetime" +version = "0.2.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35c0522e981e68cbfa8c3f978441a5f34b30b96e146b33cd3359176b50fe8586" +dependencies = [ + "cfg-if", + "libc", + "libredox", + "windows-sys 0.59.0", +] + +[[package]] +name = "fixedbitset" +version = "0.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d674e81391d1e1ab681a28d99df07927c6d4aa5b027d7da16ba32d1d21ecd99" + +[[package]] +name = "flate2" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ced92e76e966ca2fd84c8f7aa01a4aea65b0eb6648d72f7c8f3e2764a67fece" +dependencies = [ + "crc32fast", + "libz-rs-sys", + "miniz_oxide", +] + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "foldhash" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" + +[[package]] +name = "foreign-types" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" +dependencies = [ + "foreign-types-shared", +] + +[[package]] +name = "foreign-types-shared" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" + +[[package]] +name = "form_urlencoded" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456" +dependencies = [ + "percent-encoding", +] + +[[package]] +name = "format-flowed" +version = "1.0.0" + +[[package]] +name = "funty" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" + +[[package]] +name = "futures" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "65bc07b1a8bc7c85c5f2e110c476c7389b4554ba72af57d8445ea63a576b0876" +dependencies = [ + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-buffered" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe940397c8b744b9c2c974791c2c08bca2c3242ce0290393249e98f215a00472" +dependencies = [ + "cordyceps", + "diatomic-waker", + "futures-core", + "pin-project-lite", + "spin 0.9.8", +] + +[[package]] +name = "futures-channel" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" +dependencies = [ + "futures-core", + "futures-sink", +] + +[[package]] +name = "futures-concurrency" +version = "7.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eb68017df91f2e477ed4bea586c59eaecaa47ed885a770d0444e21e62572cd2" +dependencies = [ + "fixedbitset", + "futures-buffered", + "futures-core", + "futures-lite", + "pin-project", + "slab", + "smallvec", +] + +[[package]] +name = "futures-core" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" + +[[package]] +name = "futures-executor" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e28d1d997f585e54aebc3f97d39e72338912123a67330d723fdbb564d646c9f" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-io" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" + +[[package]] +name = "futures-lite" +version = "2.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f78e10609fe0e0b3f4157ffab1876319b5b0db102a2c60dc4626306dc46b44ad" +dependencies = [ + "fastrand", + "futures-core", + "futures-io", + "parking", + "pin-project-lite", +] + +[[package]] +name = "futures-macro" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.111", +] + +[[package]] +name = "futures-sink" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7" + +[[package]] +name = "futures-task" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" + +[[package]] +name = "futures-util" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" +dependencies = [ + "futures-channel", + "futures-core", + "futures-io", + "futures-macro", + "futures-sink", + "futures-task", + "memchr", + "pin-project-lite", + "pin-utils", + "slab", +] + +[[package]] +name = "generator" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc6bd114ceda131d3b1d665eba35788690ad37f5916457286b32ab6fd3c438dd" +dependencies = [ + "cfg-if", + "libc", + "log", + "rustversion", + "windows 0.58.0", +] + +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "typenum", + "version_check", + "zeroize", +] + +[[package]] +name = "getrandom" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592" +dependencies = [ + "cfg-if", + "js-sys", + "libc", + "wasi 0.11.0+wasi-snapshot-preview1", + "wasm-bindgen", +] + +[[package]] +name = "getrandom" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26145e563e54f2cadc477553f1ec5ee650b00862f0a58bcd12cbdc5f0ea2d2f4" +dependencies = [ + "cfg-if", + "js-sys", + "libc", + "r-efi", + "wasi 0.14.2+wasi-0.2.4", + "wasm-bindgen", +] + +[[package]] +name = "ghash" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0d8a4362ccb29cb0b265253fb0a2728f592895ee6854fd9bc13f2ffda266ff1" +dependencies = [ + "opaque-debug", + "polyval", +] + +[[package]] +name = "gif" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f954a9e9159ec994f73a30a12b96a702dde78f5547bcb561174597924f7d4162" +dependencies = [ + "color_quant", + "weezl", +] + +[[package]] +name = "gimli" +version = "0.31.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" + +[[package]] +name = "glob" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8d1add55171497b4705a648c6b583acafb01d58050a51727785f0b2c8e0a2b2" + +[[package]] +name = "gloo-timers" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbb143cf96099802033e0d4f4963b19fd2e0b728bcf076cd9cf7f6634f092994" +dependencies = [ + "futures-channel", + "futures-core", + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "group" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" +dependencies = [ + "ff", + "rand_core 0.6.4", + "subtle", +] + +[[package]] +name = "h2" +version = "0.4.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ccae279728d634d083c00f6099cb58f01cc99c145b84b8be2f6c74618d79922e" +dependencies = [ + "atomic-waker", + "bytes", + "fnv", + "futures-core", + "futures-sink", + "http 1.1.0", + "indexmap", + "slab", + "tokio", + "tokio-util", + "tracing", +] + +[[package]] +name = "half" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "459196ed295495a68f7d7fe1d84f6c4b7ff0e21fe3017b2f283c6fac3ad803c9" +dependencies = [ + "cfg-if", + "crunchy", +] + +[[package]] +name = "hashbrown" +version = "0.15.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5971ac85611da7067dbfcabef3c70ebb5606018acd9e2a3903a0da507521e0d5" +dependencies = [ + "allocator-api2", + "equivalent", + "foldhash", +] + +[[package]] +name = "hashlink" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7382cf6263419f2d8df38c55d7da83da5c18aef87fc7a7fc1fb1e344edfe14c1" +dependencies = [ + "hashbrown", +] + +[[package]] +name = "heck" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" + +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + +[[package]] +name = "hermit-abi" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f154ce46856750ed433c8649605bf7ed2de3bc35fd9d2a9f30cddd873c80cb08" + +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" + +[[package]] +name = "hickory-proto" +version = "0.25.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8a6fe56c0038198998a6f217ca4e7ef3a5e51f46163bd6dd60b5c71ca6c6502" +dependencies = [ + "async-trait", + "cfg-if", + "data-encoding", + "enum-as-inner", + "futures-channel", + "futures-io", + "futures-util", + "idna", + "ipnet", + "once_cell", + "rand 0.9.2", + "ring", + "thiserror 2.0.17", + "tinyvec", + "tokio", + "tracing", + "url", +] + +[[package]] +name = "hickory-resolver" +version = "0.25.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc62a9a99b0bfb44d2ab95a7208ac952d31060efc16241c87eaf36406fecf87a" +dependencies = [ + "cfg-if", + "futures-util", + "hickory-proto", + "ipconfig", + "moka", + "once_cell", + "parking_lot", + "rand 0.9.2", + "resolv-conf", + "smallvec", + "thiserror 2.0.17", + "tokio", + "tracing", +] + +[[package]] +name = "hkdf" +version = "0.12.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b5f8eb2ad728638ea2c7d47a21db23b7b58a72ed6a38256b8a1849f15fbbdf7" +dependencies = [ + "hmac", +] + +[[package]] +name = "hmac" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" +dependencies = [ + "digest", +] + +[[package]] +name = "hmac-sha1" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b05da5b9e5d4720bfb691eebb2b9d42da3570745da71eac8a1f5bb7e59aab88" +dependencies = [ + "hmac", + "sha1", +] + +[[package]] +name = "hmac-sha256" +version = "1.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a8575493d277c9092b988c780c94737fb9fd8651a1001e16bee3eccfc1baedb" + +[[package]] +name = "home" +version = "0.5.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589533453244b0995c858700322199b2becb13b627df2851f64a2775d024abcf" +dependencies = [ + "windows-sys 0.59.0", +] + +[[package]] +name = "hostname" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f9c7c7c8ac16c798734b8a24560c1362120597c40d5e1459f09498f8f6c8f2ba" +dependencies = [ + "cfg-if", + "libc", + "windows 0.52.0", +] + +[[package]] +name = "hostname-validator" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f558a64ac9af88b5ba400d99b579451af0d39c6d360980045b91aac966d705e2" + +[[package]] +name = "http" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "601cbb57e577e2f5ef5be8e7b83f0f63994f25aa94d673e54a92d5c516d101f1" +dependencies = [ + "bytes", + "fnv", + "itoa", +] + +[[package]] +name = "http" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21b9ddb458710bc376481b842f5da65cdf31522de232c1ca8146abce2a358258" +dependencies = [ + "bytes", + "fnv", + "itoa", +] + +[[package]] +name = "http-body" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" +dependencies = [ + "bytes", + "http 1.1.0", +] + +[[package]] +name = "http-body-util" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b021d93e26becf5dc7e1b75b1bed1fd93124b374ceb73f43d4d4eafec896a64a" +dependencies = [ + "bytes", + "futures-core", + "http 1.1.0", + "http-body", + "pin-project-lite", +] + +[[package]] +name = "httparse" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2d708df4e7140240a16cd6ab0ab65c972d7433ab77819ea693fde9c43811e2a" + +[[package]] +name = "httpdate" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" + +[[package]] +name = "human-panic" +version = "2.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a8a07a0957cd4a3cad4a1e4ca7cd5ea07fcacef6ebe2e5d0c7935bfc95120d8" +dependencies = [ + "backtrace", + "os_info", + "serde", + "serde_derive", + "toml", + "uuid", +] + +[[package]] +name = "humansize" +version = "2.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6cb51c9a029ddc91b07a787f1d86b53ccfa49b0e86688c946ebe8d3555685dd7" +dependencies = [ + "libm", +] + +[[package]] +name = "hyper" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2ab2d4f250c3d7b1c9fcdff1cece94ea4e2dfbec68614f7b87cb205f24ca9d11" +dependencies = [ + "atomic-waker", + "bytes", + "futures-channel", + "futures-core", + "h2", + "http 1.1.0", + "http-body", + "httparse", + "httpdate", + "itoa", + "pin-project-lite", + "pin-utils", + "smallvec", + "tokio", + "want", +] + +[[package]] +name = "hyper-rustls" +version = "0.27.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d191583f3da1305256f22463b9bb0471acad48a4e534a5218b9963e9c1f59b2" +dependencies = [ + "futures-util", + "http 1.1.0", + "hyper", + "hyper-util", + "rustls", + "rustls-pki-types", + "tokio", + "tokio-rustls", + "tower-service", + "webpki-roots", +] + +[[package]] +name = "hyper-util" +version = "0.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "727805d60e7938b76b826a6ef209eb70eaa1812794f9424d4a4e2d740662df5f" +dependencies = [ + "bytes", + "futures-channel", + "futures-core", + "futures-util", + "http 1.1.0", + "http-body", + "hyper", + "libc", + "pin-project-lite", + "socket2 0.6.0", + "tokio", + "tower-service", + "tracing", +] + +[[package]] +name = "iana-time-zone" +version = "0.1.61" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "235e081f3925a06703c2d0117ea8b91f042756fd6e7a6e5d901e8ca1a996b220" +dependencies = [ + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "wasm-bindgen", + "windows-core 0.52.0", +] + +[[package]] +name = "iana-time-zone-haiku" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" +dependencies = [ + "cc", +] + +[[package]] +name = "icu_collections" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db2fa452206ebee18c4b5c2274dbf1de17008e874b4dc4f0aea9d01ca79e4526" +dependencies = [ + "displaydoc", + "yoke", + "zerofrom", + "zerovec", +] + +[[package]] +name = "icu_locid" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13acbb8371917fc971be86fc8057c41a64b521c184808a698c02acc242dbf637" +dependencies = [ + "displaydoc", + "litemap", + "tinystr", + "writeable", + "zerovec", +] + +[[package]] +name = "icu_locid_transform" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "01d11ac35de8e40fdeda00d9e1e9d92525f3f9d887cdd7aa81d727596788b54e" +dependencies = [ + "displaydoc", + "icu_locid", + "icu_locid_transform_data", + "icu_provider", + "tinystr", + "zerovec", +] + +[[package]] +name = "icu_locid_transform_data" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fdc8ff3388f852bede6b579ad4e978ab004f139284d7b28715f773507b946f6e" + +[[package]] +name = "icu_normalizer" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19ce3e0da2ec68599d193c93d088142efd7f9c5d6fc9b803774855747dc6a84f" +dependencies = [ + "displaydoc", + "icu_collections", + "icu_normalizer_data", + "icu_properties", + "icu_provider", + "smallvec", + "utf16_iter", + "utf8_iter", + "write16", + "zerovec", +] + +[[package]] +name = "icu_normalizer_data" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8cafbf7aa791e9b22bec55a167906f9e1215fd475cd22adfcf660e03e989516" + +[[package]] +name = "icu_properties" +version = "1.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93d6020766cfc6302c15dbbc9c8778c37e62c14427cb7f6e601d849e092aeef5" +dependencies = [ + "displaydoc", + "icu_collections", + "icu_locid_transform", + "icu_properties_data", + "icu_provider", + "tinystr", + "zerovec", +] + +[[package]] +name = "icu_properties_data" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67a8effbc3dd3e4ba1afa8ad918d5684b8868b3b26500753effea8d2eed19569" + +[[package]] +name = "icu_provider" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ed421c8a8ef78d3e2dbc98a973be2f3770cb42b606e3ab18d6237c4dfde68d9" +dependencies = [ + "displaydoc", + "icu_locid", + "icu_provider_macros", + "stable_deref_trait", + "tinystr", + "writeable", + "yoke", + "zerofrom", + "zerovec", +] + +[[package]] +name = "icu_provider_macros" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.111", +] + +[[package]] +name = "idea" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "075557004419d7f2031b8bb7f44bb43e55a83ca7b63076a8fb8fe75753836477" +dependencies = [ + "cipher", +] + +[[package]] +name = "ident_case" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" + +[[package]] +name = "idna" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "686f825264d630750a544639377bae737628043f20d38bbc029e8f29ea968a7e" +dependencies = [ + "idna_adapter", + "smallvec", + "utf8_iter", +] + +[[package]] +name = "idna_adapter" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "daca1df1c957320b2cf139ac61e7bd64fed304c5040df000a745aa1de3b4ef71" +dependencies = [ + "icu_normalizer", + "icu_properties", +] + +[[package]] +name = "igd-next" +version = "0.16.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d06464e726471718db9ad3fefc020529fabcde03313a0fc3967510e2db5add12" +dependencies = [ + "async-trait", + "attohttpc", + "bytes", + "futures", + "http 1.1.0", + "http-body-util", + "hyper", + "hyper-util", + "log", + "rand 0.9.2", + "tokio", + "url", + "xmltree", +] + +[[package]] +name = "image" +version = "0.25.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6506c6c10786659413faa717ceebcb8f70731c0a60cbae39795fdf114519c1a" +dependencies = [ + "bytemuck", + "byteorder-lite", + "color_quant", + "gif", + "image-webp", + "moxcms", + "num-traits", + "png", + "zune-core", + "zune-jpeg", +] + +[[package]] +name = "image-webp" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b77d01e822461baa8409e156015a1d91735549f0f2c17691bd2d996bef238f7f" +dependencies = [ + "byteorder-lite", + "quick-error", +] + +[[package]] +name = "imap-proto" +version = "0.16.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de555d9526462b6f9ece826a26fb7c67eca9a0245bd9ff84fa91972a5d5d8856" +dependencies = [ + "nom 7.1.3", +] + +[[package]] +name = "indexmap" +version = "2.11.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b0f83760fb341a774ed326568e19f5a863af4a952def8c39f9ab92fd95b88e5" +dependencies = [ + "equivalent", + "hashbrown", +] + +[[package]] +name = "inout" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a0c10553d664a4d0bcff9f4215d0aac67a639cc68ef660840afe309b807bc9f5" +dependencies = [ + "generic-array", +] + +[[package]] +name = "instant" +version = "0.1.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0242819d153cba4b4b05a5a8f2a7e9bbf97b6055b2a002b395c96b5ff3c0222" +dependencies = [ + "cfg-if", + "js-sys", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "ipconfig" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b58db92f96b720de98181bbbe63c831e87005ab460c1bf306eb2622b4707997f" +dependencies = [ + "socket2 0.5.9", + "widestring", + "windows-sys 0.48.0", + "winreg", +] + +[[package]] +name = "ipnet" +version = "2.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "469fb0b9cefa57e3ef31275ee7cacb78f2fdca44e4765491884a2b119d4eb130" + +[[package]] +name = "iroh" +version = "0.35.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ca758f4ce39ae3f07de922be6c73de6a48a07f39554e78b5745585652ce38f5" +dependencies = [ + "aead", + "anyhow", + "atomic-waker", + "backon", + "bytes", + "cfg_aliases", + "concurrent-queue", + "crypto_box", + "data-encoding", + "der", + "derive_more 1.0.0", + "ed25519-dalek", + "futures-buffered", + "futures-util", + "getrandom 0.3.3", + "hickory-resolver", + "http 1.1.0", + "igd-next", + "instant", + "iroh-base", + "iroh-metrics", + "iroh-quinn", + "iroh-quinn-proto", + "iroh-quinn-udp", + "iroh-relay", + "n0-future", + "netdev", + "netwatch", + "pin-project", + "pkarr", + "portmapper", + "rand 0.8.5", + "rcgen", + "reqwest", + "ring", + "rustls", + "rustls-webpki", + "serde", + "smallvec", + "spki", + "strum 0.26.2", + "stun-rs", + "surge-ping", + "thiserror 2.0.17", + "time", + "tokio", + "tokio-stream", + "tokio-util", + "tracing", + "url", + "wasm-bindgen-futures", + "webpki-roots", + "x509-parser", + "z32", +] + +[[package]] +name = "iroh-base" +version = "0.35.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f91ac4aaab68153d726c4e6b39c30f9f9253743f0e25664e52f4caeb46f48d11" +dependencies = [ + "curve25519-dalek", + "data-encoding", + "derive_more 1.0.0", + "ed25519-dalek", + "rand_core 0.6.4", + "serde", + "thiserror 2.0.17", + "url", +] + +[[package]] +name = "iroh-blake3" +version = "1.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "efbba31f40a650f58fa28dd585a8ca76d8ae3ba63aacab4c8269004a0c803930" +dependencies = [ + "arrayref", + "arrayvec", + "cc", + "cfg-if", + "constant_time_eq", +] + +[[package]] +name = "iroh-gossip" +version = "0.35.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ca43045ceb44b913369f417d56323fb1628ebf482ab4c1e9360e81f1b58cbc2" +dependencies = [ + "anyhow", + "async-channel 2.5.0", + "bytes", + "derive_more 1.0.0", + "ed25519-dalek", + "futures-concurrency", + "futures-lite", + "futures-util", + "hex", + "indexmap", + "iroh", + "iroh-blake3", + "iroh-metrics", + "n0-future", + "postcard", + "rand 0.8.5", + "rand_core 0.6.4", + "serde", + "serde-error", + "thiserror 2.0.17", + "tokio", + "tokio-util", + "tracing", +] + +[[package]] +name = "iroh-metrics" +version = "0.34.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f70466f14caff7420a14373676947e25e2917af6a5b1bec45825beb2bf1eb6a7" +dependencies = [ + "iroh-metrics-derive", + "itoa", + "serde", + "snafu", + "tracing", +] + +[[package]] +name = "iroh-metrics-derive" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d12f5c45c4ed2436302a4e03cad9a0ad34b2962ad0c5791e1019c0ee30eeb09" +dependencies = [ + "heck 0.5.0", + "proc-macro2", + "quote", + "syn 2.0.111", +] + +[[package]] +name = "iroh-quinn" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76c6245c9ed906506ab9185e8d7f64857129aee4f935e899f398a3bd3b70338d" +dependencies = [ + "bytes", + "cfg_aliases", + "iroh-quinn-proto", + "iroh-quinn-udp", + "pin-project-lite", + "rustc-hash", + "rustls", + "socket2 0.5.9", + "thiserror 2.0.17", + "tokio", + "tracing", + "web-time", +] + +[[package]] +name = "iroh-quinn-proto" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "929d5d8fa77d5c304d3ee7cae9aede31f13908bd049f9de8c7c0094ad6f7c535" +dependencies = [ + "bytes", + "getrandom 0.2.16", + "rand 0.8.5", + "ring", + "rustc-hash", + "rustls", + "rustls-pki-types", + "slab", + "thiserror 2.0.17", + "tinyvec", + "tracing", + "web-time", +] + +[[package]] +name = "iroh-quinn-udp" +version = "0.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c53afaa1049f7c83ea1331f5ebb9e6ebc5fdd69c468b7a22dd598b02c9bcc973" +dependencies = [ + "cfg_aliases", + "libc", + "once_cell", + "socket2 0.5.9", + "tracing", + "windows-sys 0.59.0", +] + +[[package]] +name = "iroh-relay" +version = "0.35.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c63f122cdfaa4b4e0e7d6d3921d2b878f42a0c6d3ee5a29456dc3f5ab5ec931f" +dependencies = [ + "anyhow", + "bytes", + "cfg_aliases", + "data-encoding", + "derive_more 1.0.0", + "getrandom 0.3.3", + "hickory-resolver", + "http 1.1.0", + "http-body-util", + "hyper", + "hyper-util", + "iroh-base", + "iroh-metrics", + "iroh-quinn", + "iroh-quinn-proto", + "lru 0.12.5", + "n0-future", + "num_enum", + "pin-project", + "pkarr", + "postcard", + "rand 0.8.5", + "reqwest", + "rustls", + "rustls-webpki", + "serde", + "sha1", + "strum 0.26.2", + "stun-rs", + "thiserror 2.0.17", + "tokio", + "tokio-rustls", + "tokio-util", + "tokio-websockets", + "tracing", + "url", + "webpki-roots", + "ws_stream_wasm", + "z32", +] + +[[package]] +name = "itertools" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186" +dependencies = [ + "either", +] + +[[package]] +name = "itoa" +version = "1.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" + +[[package]] +name = "js-sys" +version = "0.3.77" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1cfaf33c695fc6e08064efbc1f72ec937429614f25eef83af942d0e227c3a28f" +dependencies = [ + "once_cell", + "wasm-bindgen", +] + +[[package]] +name = "k256" +version = "0.13.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6e3919bbaa2945715f0bb6d3934a173d1e9a59ac23767fbaaef277265a7411b" +dependencies = [ + "cfg-if", + "ecdsa", + "elliptic-curve", + "once_cell", + "sha2", + "signature", +] + +[[package]] +name = "kamadak-exif" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1130d80c7374efad55a117d715a3af9368f0fa7a2c54573afc15a188cd984837" +dependencies = [ + "mutate_once", +] + +[[package]] +name = "keccak" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ecc2af9a1119c51f12a14607e783cb977bde58bc069ff0c3da1095e635d70654" +dependencies = [ + "cpufeatures", +] + +[[package]] +name = "lazy_static" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" +dependencies = [ + "spin 0.9.8", +] + +[[package]] +name = "libc" +version = "0.2.178" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37c93d8daa9d8a012fd8ab92f088405fb202ea0b6ab73ee2482ae66af4f42091" + +[[package]] +name = "libm" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8355be11b20d696c8f18f6cc018c4e372165b1fa8126cef092399c9951984ffa" + +[[package]] +name = "libredox" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d" +dependencies = [ + "bitflags 2.9.1", + "libc", + "redox_syscall 0.5.12", +] + +[[package]] +name = "libsqlite3-sys" +version = "0.35.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "133c182a6a2c87864fe97778797e46c7e999672690dc9fa3ee8e241aa4a9c13f" +dependencies = [ + "cc", + "openssl-sys", + "pkg-config", + "vcpkg", +] + +[[package]] +name = "libz-rs-sys" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6489ca9bd760fe9642d7644e827b0c9add07df89857b0416ee15c1cc1a3b8c5a" +dependencies = [ + "zlib-rs", +] + +[[package]] +name = "linux-raw-sys" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" + +[[package]] +name = "linux-raw-sys" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df1d3c3b53da64cf5760482273a98e575c651a67eec7f77df96b5b642de8f039" + +[[package]] +name = "litemap" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ee93343901ab17bd981295f2cf0026d4ad018c7c31ba84549a4ddbb47a45104" + +[[package]] +name = "litrs" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4ce301924b7887e9d637144fdade93f9dfff9b60981d4ac161db09720d39aa5" + +[[package]] +name = "lock_api" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "224399e74b87b5f3557511d98dff8b14089b3dadafcab6bb93eab67d3aace965" +dependencies = [ + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.29" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897" + +[[package]] +name = "loom" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "419e0dc8046cb947daa77eb95ae174acfbddb7673b4151f56d1eed8e93fbfaca" +dependencies = [ + "cfg-if", + "generator", + "scoped-tls", + "tracing", + "tracing-subscriber", +] + +[[package]] +name = "lru" +version = "0.12.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "234cf4f4a04dc1f57e24b96cc0cd600cf2af460d4161ac5ecdd0af8e1f3b2a38" +dependencies = [ + "hashbrown", +] + +[[package]] +name = "lru" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "227748d55f2f0ab4735d87fd623798cb6b664512fe979705f829c9f81c934465" + +[[package]] +name = "lru_time_cache" +version = "0.11.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9106e1d747ffd48e6be5bb2d97fa706ed25b144fbee4d5c02eae110cd8d6badd" + +[[package]] +name = "mail-builder" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "900998f307338c4013a28ab14d760b784067324b164448c6d98a89e44810473b" + +[[package]] +name = "mailparse" +version = "0.16.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60819a97ddcb831a5614eb3b0174f3620e793e97e09195a395bfa948fd68ed2f" +dependencies = [ + "charset", + "data-encoding", + "quoted_printable", +] + +[[package]] +name = "matchers" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1525a2a28c7f4fa0fc98bb91ae755d1e2d1505079e05539e35bc876b5d65ae9" +dependencies = [ + "regex-automata", +] + +[[package]] +name = "md-5" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d89e7ee0cfbedfc4da3340218492196241d89eefb6dab27de5df917a6d2e78cf" +dependencies = [ + "cfg-if", + "digest", +] + +[[package]] +name = "md5" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "490cc448043f947bae3cbee9c203358d62dbee0db12107a74be5c30ccfd09771" + +[[package]] +name = "memchr" +version = "2.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" + +[[package]] +name = "mime" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" + +[[package]] +name = "minimal-lexical" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" + +[[package]] +name = "miniz_oxide" +version = "0.8.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3be647b768db090acb35d5ec5db2b0e1f1de11133ca123b9eacf5137868f892a" +dependencies = [ + "adler2", + "simd-adler32", +] + +[[package]] +name = "mio" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2886843bf800fba2e3377cff24abf6379b4c4d5c6681eaf9ea5b0d15090450bd" +dependencies = [ + "libc", + "wasi 0.11.0+wasi-snapshot-preview1", + "windows-sys 0.52.0", +] + +[[package]] +name = "moka" +version = "0.12.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9321642ca94a4282428e6ea4af8cc2ca4eac48ac7a6a4ea8f33f76d0ce70926" +dependencies = [ + "crossbeam-channel", + "crossbeam-epoch", + "crossbeam-utils", + "loom", + "parking_lot", + "portable-atomic", + "rustc_version", + "smallvec", + "tagptr", + "thiserror 1.0.69", + "uuid", +] + +[[package]] +name = "moxcms" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ddd32fa8935aeadb8a8a6b6b351e40225570a37c43de67690383d87ef170cd08" +dependencies = [ + "num-traits", + "pxfm", +] + +[[package]] +name = "mutate_once" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16cf681a23b4d0a43fc35024c176437f9dcd818db34e0f42ab456a0ee5ad497b" + +[[package]] +name = "n0-future" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7bb0e5d99e681ab3c938842b96fcb41bf8a7bb4bfdb11ccbd653a7e83e06c794" +dependencies = [ + "cfg_aliases", + "derive_more 1.0.0", + "futures-buffered", + "futures-lite", + "futures-util", + "js-sys", + "pin-project", + "send_wrapper", + "tokio", + "tokio-util", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-time", +] + +[[package]] +name = "native-tls" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87de3442987e9dbec73158d5c715e7ad9072fda936bb03d19d7fa10e00520f0e" +dependencies = [ + "libc", + "log", + "openssl", + "openssl-probe", + "openssl-sys", + "schannel", + "security-framework", + "security-framework-sys", + "tempfile", +] + +[[package]] +name = "nested_enum_utils" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43fa9161ed44d30e9702fe42bd78693bceac0fed02f647da749f36109023d3a3" +dependencies = [ + "proc-macro-crate 3.2.0", + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "netdev" +version = "0.31.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f901362e84cd407be6f8cd9d3a46bccf09136b095792785401ea7d283c79b91d" +dependencies = [ + "dlopen2", + "ipnet", + "libc", + "netlink-packet-core", + "netlink-packet-route 0.17.1", + "netlink-sys", + "once_cell", + "system-configuration", + "windows-sys 0.52.0", +] + +[[package]] +name = "netlink-packet-core" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72724faf704479d67b388da142b186f916188505e7e0b26719019c525882eda4" +dependencies = [ + "anyhow", + "byteorder", + "netlink-packet-utils", +] + +[[package]] +name = "netlink-packet-route" +version = "0.17.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "053998cea5a306971f88580d0829e90f270f940befd7cf928da179d4187a5a66" +dependencies = [ + "anyhow", + "bitflags 1.3.2", + "byteorder", + "libc", + "netlink-packet-core", + "netlink-packet-utils", +] + +[[package]] +name = "netlink-packet-route" +version = "0.23.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0800eae8638a299eaa67476e1c6b6692922273e0f7939fd188fc861c837b9cd2" +dependencies = [ + "anyhow", + "bitflags 2.9.1", + "byteorder", + "libc", + "log", + "netlink-packet-core", + "netlink-packet-utils", +] + +[[package]] +name = "netlink-packet-utils" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ede8a08c71ad5a95cdd0e4e52facd37190977039a4704eb82a283f713747d34" +dependencies = [ + "anyhow", + "byteorder", + "paste", + "thiserror 1.0.69", +] + +[[package]] +name = "netlink-proto" +version = "0.11.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72452e012c2f8d612410d89eea01e2d9b56205274abb35d53f60200b2ec41d60" +dependencies = [ + "bytes", + "futures", + "log", + "netlink-packet-core", + "netlink-sys", + "thiserror 2.0.17", +] + +[[package]] +name = "netlink-sys" +version = "0.8.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "16c903aa70590cb93691bf97a767c8d1d6122d2cc9070433deb3bbf36ce8bd23" +dependencies = [ + "bytes", + "futures", + "libc", + "log", + "tokio", +] + +[[package]] +name = "netwatch" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67eeaa5f7505c93c5a9b35ba84fd21fb8aa3f24678c76acfe8716af7862fb07a" +dependencies = [ + "atomic-waker", + "bytes", + "cfg_aliases", + "derive_more 1.0.0", + "iroh-quinn-udp", + "js-sys", + "libc", + "n0-future", + "nested_enum_utils", + "netdev", + "netlink-packet-core", + "netlink-packet-route 0.23.0", + "netlink-proto", + "netlink-sys", + "serde", + "snafu", + "socket2 0.5.9", + "time", + "tokio", + "tokio-util", + "tracing", + "web-sys", + "windows 0.59.0", + "windows-result 0.3.0", + "wmi", +] + +[[package]] +name = "nibble_vec" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77a5d83df9f36fe23f0c3648c6bbb8b0298bb5f1939c8f2704431371f4b84d43" +dependencies = [ + "smallvec", +] + +[[package]] +name = "nix" +version = "0.30.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74523f3a35e05aba87a1d978330aef40f67b0304ac79c1c00b294c9830543db6" +dependencies = [ + "bitflags 2.9.1", + "cfg-if", + "cfg_aliases", + "libc", +] + +[[package]] +name = "no-std-net" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "43794a0ace135be66a25d3ae77d41b91615fb68ae937f904090203e81f755b65" + +[[package]] +name = "nom" +version = "7.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" +dependencies = [ + "memchr", + "minimal-lexical", +] + +[[package]] +name = "nom" +version = "8.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df9761775871bdef83bee530e60050f7e54b1105350d6884eb0fb4f46c2f9405" +dependencies = [ + "memchr", +] + +[[package]] +name = "ntapi" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8a3895c6391c39d7fe7ebc444a87eb2991b2a0bc718fdabd071eec617fc68e4" +dependencies = [ + "winapi", +] + +[[package]] +name = "ntimestamp" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c50f94c405726d3e0095e89e72f75ce7f6587b94a8bd8dc8054b73f65c0fd68c" +dependencies = [ + "base32", + "document-features", + "getrandom 0.2.16", + "httpdate", + "js-sys", + "once_cell", + "serde", +] + +[[package]] +name = "nu-ansi-term" +version = "0.50.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7957b9740744892f114936ab4a57b3f487491bbeafaf8083688b16841a4240e5" +dependencies = [ + "windows-sys 0.61.1", +] + +[[package]] +name = "num-bigint" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9" +dependencies = [ + "num-integer", + "num-traits", +] + +[[package]] +name = "num-bigint-dig" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e661dda6640fad38e827a6d4a310ff4763082116fe217f279885c97f511bb0b7" +dependencies = [ + "lazy_static", + "libm", + "num-integer", + "num-iter", + "num-traits", + "rand 0.8.5", + "serde", + "smallvec", + "zeroize", +] + +[[package]] +name = "num-conv" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" + +[[package]] +name = "num-derive" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.111", +] + +[[package]] +name = "num-integer" +version = "0.1.46" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" +dependencies = [ + "num-traits", +] + +[[package]] +name = "num-iter" +version = "0.1.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1429034a0490724d0075ebb2bc9e875d6503c3cf69e235a8941aa757d83ef5bf" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg", + "libm", +] + +[[package]] +name = "num_cpus" +version = "1.17.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91df4bbde75afed763b708b7eee1e8e7651e02d97f6d5dd763e89367e957b23b" +dependencies = [ + "hermit-abi", + "libc", +] + +[[package]] +name = "num_enum" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e613fc340b2220f734a8595782c551f1250e969d87d3be1ae0579e8d4065179" +dependencies = [ + "num_enum_derive", +] + +[[package]] +name = "num_enum_derive" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af1844ef2428cc3e1cb900be36181049ef3d3193c63e43026cfe202983b27a56" +dependencies = [ + "proc-macro-crate 3.2.0", + "proc-macro2", + "quote", + "syn 2.0.111", +] + +[[package]] +name = "object" +version = "0.36.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62948e14d923ea95ea2c7c86c71013138b66525b86bdc08d2dcc262bdb497b87" +dependencies = [ + "memchr", +] + +[[package]] +name = "ocb3" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c196e0276c471c843dd5777e7543a36a298a4be942a2a688d8111cd43390dedb" +dependencies = [ + "aead", + "cipher", + "ctr", + "subtle", +] + +[[package]] +name = "oid-registry" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8d8034d9489cdaf79228eb9f6a3b8d7bb32ba00d6645ebd48eef4077ceb5bd9" +dependencies = [ + "asn1-rs", +] + +[[package]] +name = "once_cell" +version = "1.21.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" +dependencies = [ + "critical-section", + "portable-atomic", +] + +[[package]] +name = "oorandom" +version = "11.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b410bbe7e14ab526a0e86877eb47c6996a2bd7746f027ba551028c925390e4e9" + +[[package]] +name = "opaque-debug" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" + +[[package]] +name = "openssl" +version = "0.10.72" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fedfea7d58a1f73118430a55da6a286e7b044961736ce96a16a17068ea25e5da" +dependencies = [ + "bitflags 2.9.1", + "cfg-if", + "foreign-types", + "libc", + "once_cell", + "openssl-macros", + "openssl-sys", +] + +[[package]] +name = "openssl-macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.111", +] + +[[package]] +name = "openssl-probe" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d05e27ee213611ffe7d6348b942e8f942b37114c00cc03cec254295a4a17852e" + +[[package]] +name = "openssl-src" +version = "300.4.2+3.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "168ce4e058f975fe43e89d9ccf78ca668601887ae736090aacc23ae353c298e2" +dependencies = [ + "cc", +] + +[[package]] +name = "openssl-sys" +version = "0.9.107" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8288979acd84749c744a9014b4382d42b8f7b2592847b5afb2ed29e5d16ede07" +dependencies = [ + "cc", + "libc", + "openssl-src", + "pkg-config", + "vcpkg", +] + +[[package]] +name = "option-ext" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" + +[[package]] +name = "os_info" +version = "3.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a604e53c24761286860eba4e2c8b23a0161526476b1de520139d69cdb85a6b5" +dependencies = [ + "log", + "serde", + "windows-sys 0.52.0", +] + +[[package]] +name = "p256" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c9863ad85fa8f4460f9c48cb909d38a0d689dba1f6f6988a5e3e0d31071bcd4b" +dependencies = [ + "ecdsa", + "elliptic-curve", + "primeorder", + "sha2", +] + +[[package]] +name = "p384" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe42f1670a52a47d448f14b6a5c61dd78fce51856e68edaa38f7ae3a46b8d6b6" +dependencies = [ + "ecdsa", + "elliptic-curve", + "primeorder", + "sha2", +] + +[[package]] +name = "p521" +version = "0.13.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fc9e2161f1f215afdfce23677034ae137bbd45016a880c2eb3ba8eb95f085b2" +dependencies = [ + "base16ct", + "ecdsa", + "elliptic-curve", + "primeorder", + "rand_core 0.6.4", + "sha2", +] + +[[package]] +name = "page_size" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "30d5b2194ed13191c1999ae0704b7839fb18384fa22e49b57eeaa97d79ce40da" +dependencies = [ + "libc", + "winapi", +] + +[[package]] +name = "parking" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f38d5652c16fde515bb1ecef450ab0f6a219d619a7274976324d5e377f7dceba" + +[[package]] +name = "parking_lot" +version = "0.12.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93857453250e3077bd71ff98b6a65ea6621a19bb0f559a85248955ac12c45a1a" +dependencies = [ + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2621685985a2ebf1c516881c026032ac7deafcda1a2c9b7850dc81e3dfcb64c1" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall 0.5.12", + "smallvec", + "windows-link", +] + +[[package]] +name = "password-hash" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "346f04948ba92c43e8469c1ee6736c7563d71012b17d40745260fe106aac2166" +dependencies = [ + "base64ct", + "rand_core 0.6.4", + "subtle", +] + +[[package]] +name = "paste" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" + +[[package]] +name = "pem" +version = "3.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e459365e590736a54c3fa561947c84837534b8e9af6fc5bf781307e82658fae" +dependencies = [ + "base64", + "serde", +] + +[[package]] +name = "pem-rfc7468" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88b39c9bfcfc231068454382784bb460aae594343fb030d46e9f50a645418412" +dependencies = [ + "base64ct", +] + +[[package]] +name = "percent-encoding" +version = "2.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" + +[[package]] +name = "pest" +version = "2.7.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b7cafe60d6cf8e62e1b9b2ea516a089c008945bb5a275416789e7db0bc199dc" +dependencies = [ + "memchr", + "thiserror 2.0.17", + "ucd-trie", +] + +[[package]] +name = "pest_derive" +version = "2.7.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26293c9193fbca7b1a3bf9b79dc1e388e927e6cacaa78b4a3ab705a1d3d41459" +dependencies = [ + "pest", + "pest_generator", +] + +[[package]] +name = "pest_generator" +version = "2.7.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ec22af7d3fb470a85dd2ca96b7c577a1eb4ef6f1683a9fe9a8c16e136c04687" +dependencies = [ + "pest", + "pest_meta", + "proc-macro2", + "quote", + "syn 2.0.111", +] + +[[package]] +name = "pest_meta" +version = "2.7.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1e58089ea25d717bfd31fb534e4f3afcc2cc569c70de3e239778991ea3b7dea" +dependencies = [ + "once_cell", + "pest", + "sha2", +] + +[[package]] +name = "pgp" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "66d4a27a4d5cfd4e185ddd3eff94dee0f611c4c3e776422254237c54c336c160" +dependencies = [ + "aead", + "aes", + "aes-gcm", + "aes-kw", + "argon2", + "base64", + "bitfields", + "block-padding", + "blowfish", + "buffer-redux", + "byteorder", + "bytes", + "camellia", + "cast5", + "cfb-mode", + "chrono", + "cipher", + "const-oid", + "crc24", + "curve25519-dalek", + "cx448", + "derive_builder", + "derive_more 2.0.1", + "des", + "digest", + "dsa", + "eax", + "ecdsa", + "ed25519-dalek", + "elliptic-curve", + "flate2", + "generic-array", + "hex", + "hkdf", + "idea", + "k256", + "log", + "md-5", + "nom 8.0.0", + "num-bigint-dig", + "num-traits", + "num_enum", + "ocb3", + "p256", + "p384", + "p521", + "rand 0.8.5", + "regex", + "replace_with", + "ripemd", + "rsa", + "sha1", + "sha1-checked", + "sha2", + "sha3", + "signature", + "smallvec", + "snafu", + "twofish", + "x25519-dalek", + "zeroize", +] + +[[package]] +name = "pharos" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e9567389417feee6ce15dd6527a8a1ecac205ef62c2932bcf3d9f6fc5b78b414" +dependencies = [ + "futures", + "rustc_version", +] + +[[package]] +name = "pin-project" +version = "1.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677f1add503faace112b9f1373e43e9e054bfdd22ff1a63c1bc485eaec6a6a8a" +dependencies = [ + "pin-project-internal", +] + +[[package]] +name = "pin-project-internal" +version = "1.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e918e4ff8c4549eb882f14b3a4bc8c8bc93de829416eacf579f1207a8fbf861" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.111", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "pkarr" +version = "3.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e32222ae3d617bf92414db29085f8a959a4515effce916e038e9399a335a0d6d" +dependencies = [ + "async-compat", + "base32", + "bytes", + "cfg_aliases", + "document-features", + "dyn-clone", + "ed25519-dalek", + "futures-buffered", + "futures-lite", + "getrandom 0.2.16", + "log", + "lru 0.13.0", + "ntimestamp", + "reqwest", + "self_cell", + "serde", + "sha1_smol", + "simple-dns", + "thiserror 2.0.17", + "tokio", + "tracing", + "url", + "wasm-bindgen-futures", +] + +[[package]] +name = "pkcs1" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8ffb9f10fa047879315e6625af03c164b16962a5368d724ed16323b68ace47f" +dependencies = [ + "der", + "pkcs8", + "spki", +] + +[[package]] +name = "pkcs8" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" +dependencies = [ + "der", + "spki", +] + +[[package]] +name = "pkg-config" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "953ec861398dccce10c670dfeaf3ec4911ca479e9c02154b3a215178c5f566f2" + +[[package]] +name = "plotters" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5aeb6f403d7a4911efb1e33402027fc44f29b5bf6def3effcc22d7bb75f2b747" +dependencies = [ + "num-traits", + "plotters-backend", + "plotters-svg", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "plotters-backend" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df42e13c12958a16b3f7f4386b9ab1f3e7933914ecea48da7139435263a4172a" + +[[package]] +name = "plotters-svg" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51bae2ac328883f7acdfea3d66a7c35751187f870bc81f94563733a154d7a670" +dependencies = [ + "plotters-backend", +] + +[[package]] +name = "pnet_base" +version = "0.34.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe4cf6fb3ab38b68d01ab2aea03ed3d1132b4868fa4e06285f29f16da01c5f4c" +dependencies = [ + "no-std-net", +] + +[[package]] +name = "pnet_macros" +version = "0.34.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "688b17499eee04a0408aca0aa5cba5fc86401d7216de8a63fdf7a4c227871804" +dependencies = [ + "proc-macro2", + "quote", + "regex", + "syn 2.0.111", +] + +[[package]] +name = "pnet_macros_support" +version = "0.34.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eea925b72f4bd37f8eab0f221bbe4c78b63498350c983ffa9dd4bcde7e030f56" +dependencies = [ + "pnet_base", +] + +[[package]] +name = "pnet_packet" +version = "0.34.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9a005825396b7fe7a38a8e288dbc342d5034dac80c15212436424fef8ea90ba" +dependencies = [ + "glob", + "pnet_base", + "pnet_macros", + "pnet_macros_support", +] + +[[package]] +name = "png" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97baced388464909d42d89643fe4361939af9b7ce7a31ee32a168f832a70f2a0" +dependencies = [ + "bitflags 2.9.1", + "crc32fast", + "fdeflate", + "flate2", + "miniz_oxide", +] + +[[package]] +name = "poly1305" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8159bd90725d2df49889a078b54f4f79e87f1f8a8444194cdca81d38f5393abf" +dependencies = [ + "cpufeatures", + "opaque-debug", + "universal-hash", +] + +[[package]] +name = "polyval" +version = "0.6.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d1fe60d06143b2430aa532c94cfe9e29783047f06c0d7fd359a9a51b729fa25" +dependencies = [ + "cfg-if", + "cpufeatures", + "opaque-debug", + "universal-hash", +] + +[[package]] +name = "portable-atomic" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "280dc24453071f1b63954171985a0b0d30058d287960968b9b2aca264c8d4ee6" + +[[package]] +name = "portmapper" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d6db66007eac4a0ec8331d0d20c734bd64f6445d64bbaf0d0a27fea7a054e36" +dependencies = [ + "base64", + "bytes", + "derive_more 1.0.0", + "futures-lite", + "futures-util", + "hyper-util", + "igd-next", + "iroh-metrics", + "libc", + "nested_enum_utils", + "netwatch", + "num_enum", + "rand 0.8.5", + "serde", + "smallvec", + "snafu", + "socket2 0.5.9", + "time", + "tokio", + "tokio-util", + "tower-layer", + "tracing", + "url", +] + +[[package]] +name = "postcard" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "170a2601f67cc9dba8edd8c4870b15f71a6a2dc196daec8c83f72b59dff628a8" +dependencies = [ + "cobs", + "embedded-io 0.4.0", + "embedded-io 0.6.1", + "postcard-derive", + "serde", +] + +[[package]] +name = "postcard-derive" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0239fa9c1d225d4b7eb69925c25c5e082307a141e470573fbbe3a817ce6a7a37" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "powerfmt" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" + +[[package]] +name = "ppv-lite86" +version = "0.2.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04" +dependencies = [ + "zerocopy", +] + +[[package]] +name = "precis-core" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c2e7b31f132e0c6f8682cfb7bf4a5340dbe925b7986618d0826a56dfe0c8e56" +dependencies = [ + "precis-tools", + "ucd-parse", + "unicode-normalization", +] + +[[package]] +name = "precis-profiles" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc4f67f78f50388f03494794766ba824a704db16fb5d400fe8d545fa7bc0d3f1" +dependencies = [ + "lazy_static", + "precis-core", + "precis-tools", + "unicode-normalization", +] + +[[package]] +name = "precis-tools" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6cc1eb2d5887ac7bfd2c0b745764db89edb84b856e4214e204ef48ef96d10c4a" +dependencies = [ + "lazy_static", + "regex", + "ucd-parse", +] + +[[package]] +name = "pretty-hex" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbc83ee4a840062f368f9096d80077a9841ec117e17e7f700df81958f1451254" + +[[package]] +name = "pretty_assertions" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ae130e2f271fbc2ac3a40fb1d07180839cdbbe443c7a27e1e3c13c5cac0116d" +dependencies = [ + "diff", + "yansi", +] + +[[package]] +name = "primeorder" +version = "0.13.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "353e1ca18966c16d9deb1c69278edbc5f194139612772bd9537af60ac231e1e6" +dependencies = [ + "elliptic-curve", +] + +[[package]] +name = "proc-macro-crate" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e8366a6159044a37876a2b9817124296703c586a5c92e2c53751fa06d8d43e8" +dependencies = [ + "toml_edit 0.20.7", +] + +[[package]] +name = "proc-macro-crate" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ecf48c7ca261d60b74ab1a7b20da18bede46776b2e55535cb958eb595c5fa7b" +dependencies = [ + "toml_edit 0.22.27", +] + +[[package]] +name = "proc-macro-error-attr2" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96de42df36bb9bba5542fe9f1a054b8cc87e172759a1868aa05c1f3acc89dfc5" +dependencies = [ + "proc-macro2", + "quote", +] + +[[package]] +name = "proc-macro-error2" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "11ec05c52be0a07b08061f7dd003e7d7092e0472bc731b4af7bb1ef876109802" +dependencies = [ + "proc-macro-error-attr2", + "proc-macro2", + "quote", + "syn 2.0.111", +] + +[[package]] +name = "proc-macro2" +version = "1.0.93" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60946a68e5f9d28b0dc1c21bb8a97ee7d018a8b322fa57838ba31cc878e22d99" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "proptest" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bee689443a2bd0a16ab0348b52ee43e3b2d1b1f931c8aa5c9f8de4c86fbe8c40" +dependencies = [ + "bitflags 2.9.1", + "num-traits", + "rand 0.9.2", + "rand_chacha 0.9.0", + "rand_xorshift", + "regex-syntax", + "unarray", +] + +[[package]] +name = "pxfm" +version = "0.1.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "83f9b339b02259ada5c0f4a389b7fb472f933aa17ce176fd2ad98f28bb401fde" +dependencies = [ + "num-traits", +] + +[[package]] +name = "qr2term" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6867c60b38e9747a079a19614dbb5981a53f21b9a56c265f3bfdf6011a50a957" +dependencies = [ + "crossterm", + "qrcode", +] + +[[package]] +name = "qrcode" +version = "0.14.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d68782463e408eb1e668cf6152704bd856c78c5b6417adaee3203d8f4c1fc9ec" + +[[package]] +name = "qrcodegen" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4339fc7a1021c9c1621d87f5e3505f2805c8c105420ba2f2a4df86814590c142" + +[[package]] +name = "quick-error" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a993555f31e5a609f617c12db6250dedcac1b0a85076912c436e6fc9b2c8e6a3" + +[[package]] +name = "quick-xml" +version = "0.38.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b66c2058c55a409d601666cffe35f04333cf1013010882cec174a7467cd4e21c" +dependencies = [ + "memchr", +] + +[[package]] +name = "quinn" +version = "0.11.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62e96808277ec6f97351a2380e6c25114bc9e67037775464979f3037c92d05ef" +dependencies = [ + "bytes", + "pin-project-lite", + "quinn-proto", + "quinn-udp", + "rustc-hash", + "rustls", + "socket2 0.5.9", + "thiserror 2.0.17", + "tokio", + "tracing", +] + +[[package]] +name = "quinn-proto" +version = "0.11.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2fe5ef3495d7d2e377ff17b1a8ce2ee2ec2a18cde8b6ad6619d65d0701c135d" +dependencies = [ + "bytes", + "getrandom 0.2.16", + "rand 0.8.5", + "ring", + "rustc-hash", + "rustls", + "rustls-pki-types", + "slab", + "thiserror 2.0.17", + "tinyvec", + "tracing", + "web-time", +] + +[[package]] +name = "quinn-udp" +version = "0.5.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e46f3055866785f6b92bc6164b76be02ca8f2eb4b002c0354b28cf4c119e5944" +dependencies = [ + "cfg_aliases", + "libc", + "once_cell", + "socket2 0.5.9", + "tracing", + "windows-sys 0.59.0", +] + +[[package]] +name = "quote" +version = "1.0.42" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a338cc41d27e6cc6dce6cefc13a0729dfbb81c262b1f519331575dd80ef3067f" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "quoted-string-parser" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0dc75379cdb451d001f1cb667a9f74e8b355e9df84cc5193513cbe62b96fc5e9" +dependencies = [ + "pest", + "pest_derive", +] + +[[package]] +name = "quoted_printable" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "640c9bd8497b02465aeef5375144c26062e0dcd5939dfcbb0f5db76cb8c17c73" + +[[package]] +name = "r-efi" +version = "5.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74765f6d916ee2faa39bc8e68e4f3ed8949b48cccdac59983d287a7cb71ce9c5" + +[[package]] +name = "radium" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" + +[[package]] +name = "radix_trie" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c069c179fcdc6a2fe24d8d18305cf085fdbd4f922c041943e203685d6a1c58fd" +dependencies = [ + "endian-type", + "nibble_vec", +] + +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha 0.3.1", + "rand_core 0.6.4", +] + +[[package]] +name = "rand" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6db2770f06117d490610c7488547d543617b21bfa07796d7a12f6f1bd53850d1" +dependencies = [ + "rand_chacha 0.9.0", + "rand_core 0.9.3", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core 0.6.4", +] + +[[package]] +name = "rand_chacha" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb" +dependencies = [ + "ppv-lite86", + "rand_core 0.9.3", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom 0.2.16", +] + +[[package]] +name = "rand_core" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38" +dependencies = [ + "getrandom 0.3.3", +] + +[[package]] +name = "rand_xorshift" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "513962919efc330f829edb2535844d1b912b0fbe2ca165d613e4e8788bb05a5a" +dependencies = [ + "rand_core 0.9.3", +] + +[[package]] +name = "rand_xoshiro" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f703f4665700daf5512dcca5f43afa6af89f09db47fb56be587f80636bda2d41" +dependencies = [ + "rand_core 0.9.3", +] + +[[package]] +name = "ratelimit" +version = "1.0.0" + +[[package]] +name = "rayon" +version = "1.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa" +dependencies = [ + "either", + "rayon-core", +] + +[[package]] +name = "rayon-core" +version = "1.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2" +dependencies = [ + "crossbeam-deque", + "crossbeam-utils", +] + +[[package]] +name = "rcgen" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75e669e5202259b5314d1ea5397316ad400819437857b90861765f24c4cf80a2" +dependencies = [ + "pem", + "ring", + "rustls-pki-types", + "time", + "yasna", +] + +[[package]] +name = "redox_syscall" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" +dependencies = [ + "bitflags 1.3.2", +] + +[[package]] +name = "redox_syscall" +version = "0.5.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "928fca9cf2aa042393a8325b9ead81d2f0df4cb12e1e24cef072922ccd99c5af" +dependencies = [ + "bitflags 2.9.1", +] + +[[package]] +name = "redox_users" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd6f9d3d47bdd2ad6945c5015a226ec6155d0bcdfd8f7cd29f86b71f8de99d2b" +dependencies = [ + "getrandom 0.2.16", + "libredox", + "thiserror 2.0.17", +] + +[[package]] +name = "regex" +version = "1.12.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "843bc0191f75f3e22651ae5f1e72939ab2f72a4bc30fa80a066bd66edefc24d4" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5276caf25ac86c8d810222b3dbb938e512c55c6831a10f3e6ed1c93b84041f1c" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-lite" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53a49587ad06b26609c52e423de037e7f57f20d53535d66e08c695f347df952a" + +[[package]] +name = "regex-syntax" +version = "0.8.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a2d987857b319362043e95f5353c0535c1f58eec5336fdfcf626430af7def58" + +[[package]] +name = "replace_with" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51743d3e274e2b18df81c4dc6caf8a5b8e15dbe799e0dca05c7617380094e884" + +[[package]] +name = "reqwest" +version = "0.12.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d19c46a6fdd48bc4dab94b6103fccc55d34c67cc0ad04653aad4ea2a07cd7bbb" +dependencies = [ + "base64", + "bytes", + "futures-core", + "futures-util", + "http 1.1.0", + "http-body", + "http-body-util", + "hyper", + "hyper-rustls", + "hyper-util", + "ipnet", + "js-sys", + "log", + "mime", + "once_cell", + "percent-encoding", + "pin-project-lite", + "quinn", + "rustls", + "rustls-pemfile", + "rustls-pki-types", + "serde", + "serde_json", + "serde_urlencoded", + "sync_wrapper", + "tokio", + "tokio-rustls", + "tokio-util", + "tower", + "tower-service", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "wasm-streams", + "web-sys", + "webpki-roots", + "windows-registry", +] + +[[package]] +name = "resolv-conf" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48375394603e3dd4b2d64371f7148fd8c7baa2680e28741f2cb8d23b59e3d4c4" +dependencies = [ + "hostname", +] + +[[package]] +name = "rfc6979" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8dd2a808d456c4a54e300a23e9f5a67e122c3024119acbfd73e3bf664491cb2" +dependencies = [ + "hmac", + "subtle", +] + +[[package]] +name = "ring" +version = "0.17.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70ac5d832aa16abd7d1def883a8545280c20a60f523a370aa3a9617c2b8550ee" +dependencies = [ + "cc", + "cfg-if", + "getrandom 0.2.16", + "libc", + "untrusted", + "windows-sys 0.52.0", +] + +[[package]] +name = "ring-compat" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ccce7bae150b815f0811db41b8312fcb74bffa4cab9cee5429ee00f356dd5bd4" +dependencies = [ + "aead", + "digest", + "ecdsa", + "ed25519", + "generic-array", + "p256", + "p384", + "pkcs8", + "rand_core 0.6.4", + "ring", + "signature", +] + +[[package]] +name = "ripemd" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd124222d17ad93a644ed9d011a40f4fb64aa54275c08cc216524a9ea82fb09f" +dependencies = [ + "digest", +] + +[[package]] +name = "rsa" +version = "0.9.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8573f03f5883dcaebdfcf4725caa1ecb9c15b2ef50c43a07b816e06799bb12d" +dependencies = [ + "const-oid", + "digest", + "num-bigint-dig", + "num-integer", + "num-traits", + "pkcs1", + "pkcs8", + "rand_core 0.6.4", + "signature", + "spki", + "subtle", + "zeroize", +] + +[[package]] +name = "rusqlite" +version = "0.37.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "165ca6e57b20e1351573e3729b958bc62f0e48025386970b6e4d29e7a7e71f3f" +dependencies = [ + "bitflags 2.9.1", + "fallible-iterator", + "fallible-streaming-iterator", + "hashlink", + "libsqlite3-sys", + "smallvec", +] + +[[package]] +name = "rustc-demangle" +version = "0.1.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" + +[[package]] +name = "rustc-hash" +version = "2.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d" + +[[package]] +name = "rustc_version" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" +dependencies = [ + "semver", +] + +[[package]] +name = "rusticata-macros" +version = "4.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "faf0c4a6ece9950b9abdb62b1cfcf2a68b3b67a10ba445b3bb85be2a293d0632" +dependencies = [ + "nom 7.1.3", +] + +[[package]] +name = "rustix" +version = "0.38.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154" +dependencies = [ + "bitflags 2.9.1", + "errno", + "libc", + "linux-raw-sys 0.4.14", + "windows-sys 0.59.0", +] + +[[package]] +name = "rustix" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "146c9e247ccc180c1f61615433868c99f3de3ae256a30a43b49f67c2d9171f34" +dependencies = [ + "bitflags 2.9.1", + "errno", + "libc", + "linux-raw-sys 0.11.0", + "windows-sys 0.61.1", +] + +[[package]] +name = "rustls" +version = "0.23.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47796c98c480fce5406ef69d1c76378375492c3b0a0de587be0c1d9feb12f395" +dependencies = [ + "log", + "once_cell", + "ring", + "rustls-pki-types", + "rustls-webpki", + "subtle", + "zeroize", +] + +[[package]] +name = "rustls-pemfile" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dce314e5fee3f39953d46bb63bb8a46d40c2f8fb7cc5a3b6cab2bde9721d6e50" +dependencies = [ + "rustls-pki-types", +] + +[[package]] +name = "rustls-pki-types" +version = "1.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21e6f2ab2928ca4291b86736a8bd920a277a399bba1589409d72154ff87c1282" +dependencies = [ + "web-time", + "zeroize", +] + +[[package]] +name = "rustls-webpki" +version = "0.102.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "64ca1bc8749bd4cf37b5ce386cc146580777b4e8572c7b97baf22c83f444bee9" +dependencies = [ + "ring", + "rustls-pki-types", + "untrusted", +] + +[[package]] +name = "rustversion" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4" + +[[package]] +name = "rustyline" +version = "16.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62fd9ca5ebc709e8535e8ef7c658eb51457987e48c98ead2be482172accc408d" +dependencies = [ + "bitflags 2.9.1", + "cfg-if", + "clipboard-win", + "fd-lock", + "home", + "libc", + "log", + "memchr", + "nix", + "radix_trie", + "unicode-segmentation", + "unicode-width", + "utf8parse", + "windows-sys 0.59.0", +] + +[[package]] +name = "ryu" +version = "1.0.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ea1a2d0a644769cc99faa24c3ad26b379b786fe7c36fd3c546254801650e6dd" + +[[package]] +name = "salsa20" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97a22f5af31f73a954c10289c93e8a50cc23d971e80ee446f1f6f7137a088213" +dependencies = [ + "cipher", +] + +[[package]] +name = "same-file" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "sanitize-filename" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc984f4f9ceb736a7bb755c3e3bd17dc56370af2600c9780dcc48c66453da34d" +dependencies = [ + "regex", +] + +[[package]] +name = "schannel" +version = "0.1.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f29ebaa345f945cec9fbbc532eb307f0fdad8161f281b6369539c8d84876b3d" +dependencies = [ + "windows-sys 0.59.0", +] + +[[package]] +name = "schemars" +version = "0.8.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fbf2ae1b8bc8e02df939598064d22402220cd5bbcca1c76f7d6a310974d5615" +dependencies = [ + "dyn-clone", + "schemars_derive", + "serde", + "serde_json", +] + +[[package]] +name = "schemars_derive" +version = "0.8.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32e265784ad618884abaea0600a9adf15393368d840e0222d101a072f3f7534d" +dependencies = [ + "proc-macro2", + "quote", + "serde_derive_internals", + "syn 2.0.111", +] + +[[package]] +name = "scoped-tls" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1cf6437eb19a8f4a6cc0f7dca544973b0b78843adbfeb3683d1a94a0024a294" + +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + +[[package]] +name = "sdp" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32c374dceda16965d541c8800ce9cc4e1c14acfd661ddf7952feeedc3411e5c6" +dependencies = [ + "rand 0.9.2", + "substring", + "thiserror 1.0.69", + "url", +] + +[[package]] +name = "sec1" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3e97a565f76233a6003f9f5c54be1d9c5bdfa3eccfb189469f11ec4901c47dc" +dependencies = [ + "base16ct", + "der", + "generic-array", + "pkcs8", + "serdect 0.2.0", + "subtle", + "zeroize", +] + +[[package]] +name = "security-framework" +version = "2.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02" +dependencies = [ + "bitflags 2.9.1", + "core-foundation", + "core-foundation-sys", + "libc", + "security-framework-sys", +] + +[[package]] +name = "security-framework-sys" +version = "2.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49db231d56a190491cb4aeda9527f1ad45345af50b0851622a7adb8c03b01c32" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "self_cell" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2fdfc24bc566f839a2da4c4295b82db7d25a24253867d5c64355abb5799bdbe" + +[[package]] +name = "semver" +version = "1.0.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f79dfe2d285b0488816f30e700a7438c5a73d816b5b7d3ac72fbc48b0d185e03" +dependencies = [ + "serde", +] + +[[package]] +name = "send_wrapper" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd0b0ec5f1c1ca621c432a25813d8d60c88abe6d3e08a3eb9cf37d97a0fe3d73" + +[[package]] +name = "sendfd" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "604b71b8fc267e13bb3023a2c901126c8f349393666a6d98ac1ae5729b701798" +dependencies = [ + "libc", + "tokio", +] + +[[package]] +name = "serde" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" +dependencies = [ + "serde_core", + "serde_derive", +] + +[[package]] +name = "serde-error" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "342110fb7a5d801060c885da03bf91bfa7c7ca936deafcc64bb6706375605d47" +dependencies = [ + "serde", +] + +[[package]] +name = "serde_core" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.111", +] + +[[package]] +name = "serde_derive_internals" +version = "0.29.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "330f01ce65a3a5fe59a60c82f3c9a024b573b8a6e875bd233fe5f934e71d54e3" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.111", +] + +[[package]] +name = "serde_json" +version = "1.0.148" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3084b546a1dd6289475996f182a22aba973866ea8e8b02c51d9f46b1336a22da" +dependencies = [ + "itoa", + "memchr", + "serde", + "serde_core", + "zmij", +] + +[[package]] +name = "serde_spanned" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8bbf91e5a4d6315eee45e704372590b30e260ee83af6639d64557f51b067776" +dependencies = [ + "serde_core", +] + +[[package]] +name = "serde_urlencoded" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" +dependencies = [ + "form_urlencoded", + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "serdect" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a84f14a19e9a014bb9f4512488d9829a68e04ecabffb0f9904cd1ace94598177" +dependencies = [ + "base16ct", + "serde", +] + +[[package]] +name = "serdect" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f42f67da2385b51a5f9652db9c93d78aeaf7610bf5ec366080b6de810604af53" +dependencies = [ + "base16ct", + "serde", +] + +[[package]] +name = "sha-1" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f5058ada175748e33390e40e872bd0fe59a19f265d0158daa551c5a88a76009c" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + +[[package]] +name = "sha1" +version = "0.10.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + +[[package]] +name = "sha1-checked" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89f599ac0c323ebb1c6082821a54962b839832b03984598375bff3975b804423" +dependencies = [ + "digest", + "sha1", + "zeroize", +] + +[[package]] +name = "sha1_smol" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbfa15b3dddfee50a0fff136974b3e1bde555604ba463834a7eb7deb6417705d" + +[[package]] +name = "sha2" +version = "0.10.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + +[[package]] +name = "sha3" +version = "0.10.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75872d278a8f37ef87fa0ddbda7802605cb18344497949862c0d4dcb291eba60" +dependencies = [ + "digest", + "keccak", +] + +[[package]] +name = "shadowsocks" +version = "1.23.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e78db9c9912c90ea7487f49bc149b329b535806bfa12b740fbade73f573a3d9f" +dependencies = [ + "aes", + "base64", + "blake3", + "byte_string", + "bytes", + "cfg-if", + "dynosaur", + "futures", + "libc", + "log", + "lru_time_cache", + "once_cell", + "percent-encoding", + "pin-project", + "rand 0.9.2", + "sendfd", + "serde", + "serde_json", + "serde_urlencoded", + "shadowsocks-crypto", + "socket2 0.5.9", + "spin 0.10.0", + "thiserror 2.0.17", + "tokio", + "tokio-tfo", + "trait-variant", + "url", + "windows-sys 0.59.0", +] + +[[package]] +name = "shadowsocks-crypto" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bda401a0ad32c82981d8862f2795713618de9bbf9768f03c17d9d145c6d805df" +dependencies = [ + "aes", + "aes-gcm", + "blake3", + "bytes", + "cfg-if", + "chacha20poly1305", + "hkdf", + "md-5", + "rand 0.9.2", + "ring-compat", + "sha1", +] + +[[package]] +name = "sharded-slab" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" +dependencies = [ + "lazy_static", +] + +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + +[[package]] +name = "signal-hook-registry" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a9e9e0b4211b72e7b8b6e85c807d36c212bdb33ea8587f7569562a84df5465b1" +dependencies = [ + "libc", +] + +[[package]] +name = "signature" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" +dependencies = [ + "digest", + "rand_core 0.6.4", +] + +[[package]] +name = "simd-adler32" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d66dc143e6b11c1eddc06d5c423cfc97062865baf299914ab64caa38182078fe" + +[[package]] +name = "simdutf8" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3a9fe34e3e7a50316060351f37187a3f546bce95496156754b601a5fa71b76e" + +[[package]] +name = "simple-dns" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dee851d0e5e7af3721faea1843e8015e820a234f81fda3dea9247e15bac9a86a" +dependencies = [ + "bitflags 2.9.1", +] + +[[package]] +name = "slab" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" +dependencies = [ + "autocfg", +] + +[[package]] +name = "smallvec" +version = "1.15.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" + +[[package]] +name = "smawk" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7c388c1b5e93756d0c740965c41e8822f866621d41acbdf6336a6a168f8840c" + +[[package]] +name = "snafu" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "223891c85e2a29c3fe8fb900c1fae5e69c2e42415e3177752e8718475efa5019" +dependencies = [ + "snafu-derive", +] + +[[package]] +name = "snafu-derive" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03c3c6b7927ffe7ecaa769ee0e3994da3b8cafc8f444578982c83ecb161af917" +dependencies = [ + "heck 0.5.0", + "proc-macro2", + "quote", + "syn 2.0.111", +] + +[[package]] +name = "socket2" +version = "0.5.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4f5fd57c80058a56cf5c777ab8a126398ece8e442983605d280a44ce79d0edef" +dependencies = [ + "libc", + "windows-sys 0.52.0", +] + +[[package]] +name = "socket2" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "233504af464074f9d066d7b5416c5f9b894a5862a6506e306f7b816cdd6f1807" +dependencies = [ + "libc", + "windows-sys 0.59.0", +] + +[[package]] +name = "spin" +version = "0.9.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" + +[[package]] +name = "spin" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d5fe4ccb98d9c292d56fec89a5e07da7fc4cf0dc11e156b41793132775d3e591" +dependencies = [ + "lock_api", +] + +[[package]] +name = "spki" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d" +dependencies = [ + "base64ct", + "der", +] + +[[package]] +name = "stable_deref_trait" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" + +[[package]] +name = "stop-token" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af91f480ee899ab2d9f8435bfdfc14d08a5754bd9d3fef1f1a1c23336aad6c8b" +dependencies = [ + "async-channel 1.9.0", + "cfg-if", + "futures-core", + "pin-project-lite", +] + +[[package]] +name = "strsim" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" + +[[package]] +name = "strum" +version = "0.26.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d8cec3501a5194c432b2b7976db6b7d10ec95c253208b45f83f7136aa985e29" +dependencies = [ + "strum_macros 0.26.2", +] + +[[package]] +name = "strum" +version = "0.27.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af23d6f6c1a224baef9d3f61e287d2761385a5b88fdab4eb4c6f11aeb54c4bcf" + +[[package]] +name = "strum_macros" +version = "0.26.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6cf59daf282c0a494ba14fd21610a0325f9f90ec9d1231dea26bcb1d696c946" +dependencies = [ + "heck 0.4.1", + "proc-macro2", + "quote", + "rustversion", + "syn 2.0.111", +] + +[[package]] +name = "strum_macros" +version = "0.27.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7695ce3845ea4b33927c055a39dc438a45b059f7c1b3d91d38d10355fb8cbca7" +dependencies = [ + "heck 0.5.0", + "proc-macro2", + "quote", + "syn 2.0.111", +] + +[[package]] +name = "stun-rs" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb921f10397d5669e1af6455e9e2d367bf1f9cebcd6b1dd1dc50e19f6a9ac2ac" +dependencies = [ + "base64", + "bounded-integer", + "byteorder", + "crc", + "enumflags2", + "fallible-iterator", + "hmac-sha1", + "hmac-sha256", + "hostname-validator", + "lazy_static", + "md5", + "paste", + "precis-core", + "precis-profiles", + "quoted-string-parser", + "rand 0.9.2", +] + +[[package]] +name = "substring" +version = "1.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42ee6433ecef213b2e72f587ef64a2f5943e7cd16fbd82dbe8bc07486c534c86" +dependencies = [ + "autocfg", +] + +[[package]] +name = "subtle" +version = "2.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" + +[[package]] +name = "surge-ping" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "efbf95ce4c7c5b311d2ce3f088af2b93edef0f09727fa50fbe03c7a979afce77" +dependencies = [ + "hex", + "parking_lot", + "pnet_packet", + "rand 0.8.5", + "socket2 0.5.9", + "thiserror 1.0.69", + "tokio", + "tracing", +] + +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "syn" +version = "2.0.111" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "390cc9a294ab71bdb1aa2e99d13be9c753cd2d7bd6560c77118597410c4d2e87" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "sync_wrapper" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "384595c11a4e2969895cad5a8c4029115f5ab956a9e5ef4de79d11a426e5f20c" +dependencies = [ + "futures-core", +] + +[[package]] +name = "synstructure" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.111", +] + +[[package]] +name = "sysinfo" +version = "0.26.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c18a6156d1f27a9592ee18c1a846ca8dd5c258b7179fc193ae87c74ebb666f5" +dependencies = [ + "cfg-if", + "core-foundation-sys", + "libc", + "ntapi", + "once_cell", + "winapi", +] + +[[package]] +name = "system-configuration" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c879d448e9d986b661742763247d3693ed13609438cf3d006f51f5368a5ba6b" +dependencies = [ + "bitflags 2.9.1", + "core-foundation", + "system-configuration-sys", +] + +[[package]] +name = "system-configuration-sys" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e1d1b10ced5ca923a1fcb8d03e96b8d3268065d724548c0211415ff6ac6bac4" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "tagger" +version = "4.3.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "094c9f64d6de9a8506b1e49b63a29333b37ed9e821ee04be694d431b3264c3c5" + +[[package]] +name = "tagptr" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7b2093cf4c8eb1e67749a6762251bc9cd836b6fc171623bd0a9d324d37af2417" + +[[package]] +name = "tap" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" + +[[package]] +name = "tempfile" +version = "3.24.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "655da9c7eb6305c55742045d5a8d2037996d61d8de95806335c7c86ce0f82e9c" +dependencies = [ + "fastrand", + "getrandom 0.3.3", + "once_cell", + "rustix 1.1.3", + "windows-sys 0.61.1", +] + +[[package]] +name = "testdir" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c9ffa013be124f7e8e648876190de818e3a87088ed97ccd414a398b403aec8c8" +dependencies = [ + "anyhow", + "backtrace", + "cargo-platform", + "cargo_metadata", + "once_cell", + "sysinfo", + "whoami", +] + +[[package]] +name = "textwrap" +version = "0.16.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c13547615a44dc9c452a8a534638acdf07120d4b6847c8178705da06306a3057" +dependencies = [ + "smawk", + "unicode-linebreak", + "unicode-width", +] + +[[package]] +name = "thiserror" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" +dependencies = [ + "thiserror-impl 1.0.69", +] + +[[package]] +name = "thiserror" +version = "2.0.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f63587ca0f12b72a0600bcba1d40081f830876000bb46dd2337a3051618f4fc8" +dependencies = [ + "thiserror-impl 2.0.17", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.111", +] + +[[package]] +name = "thiserror-impl" +version = "2.0.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ff15c8ecd7de3849db632e14d18d2571fa09dfc5ed93479bc4485c7a517c913" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.111", +] + +[[package]] +name = "thread_local" +version = "1.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b9ef9bad013ada3808854ceac7b46812a6465ba368859a37e2100283d2d719c" +dependencies = [ + "cfg-if", + "once_cell", +] + +[[package]] +name = "time" +version = "0.3.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "35e7868883861bd0e56d9ac6efcaaca0d6d5d82a2a7ec8209ff492c07cf37b21" +dependencies = [ + "deranged", + "itoa", + "js-sys", + "num-conv", + "powerfmt", + "serde", + "time-core", + "time-macros", +] + +[[package]] +name = "time-core" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" + +[[package]] +name = "time-macros" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2834e6017e3e5e4b9834939793b282bc03b37a3336245fa820e35e233e2a85de" +dependencies = [ + "num-conv", + "time-core", +] + +[[package]] +name = "tinystr" +version = "0.7.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9117f5d4db391c1cf6927e7bea3db74b9a1c1add8f7eda9ffd5364f40f57b82f" +dependencies = [ + "displaydoc", + "zerovec", +] + +[[package]] +name = "tinytemplate" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "be4d6b5f19ff7664e8c98d03e2139cb510db9b0a60b55f8e8709b689d939b6bc" +dependencies = [ + "serde", + "serde_json", +] + +[[package]] +name = "tinyvec" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" +dependencies = [ + "tinyvec_macros", +] + +[[package]] +name = "tinyvec_macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" + +[[package]] +name = "tokio" +version = "1.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff360e02eab121e0bc37a2d3b4d4dc622e6eda3a8e5253d5435ecf5bd4c68408" +dependencies = [ + "bytes", + "libc", + "mio", + "parking_lot", + "pin-project-lite", + "signal-hook-registry", + "socket2 0.6.0", + "tokio-macros", + "windows-sys 0.61.1", +] + +[[package]] +name = "tokio-io-timeout" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bd86198d9ee903fedd2f9a2e72014287c0d9167e4ae43b5853007205dda1b76" +dependencies = [ + "pin-project-lite", + "tokio", +] + +[[package]] +name = "tokio-macros" +version = "2.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af407857209536a95c8e56f8231ef2c2e2aff839b22e07a1ffcbc617e9db9fa5" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.111", +] + +[[package]] +name = "tokio-rustls" +version = "0.26.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e727b36a1a0e8b74c376ac2211e40c2c8af09fb4013c60d910495810f008e9b" +dependencies = [ + "rustls", + "tokio", +] + +[[package]] +name = "tokio-stream" +version = "0.1.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eca58d7bba4a75707817a2c44174253f9236b2d5fbd055602e9d5c07c139a047" +dependencies = [ + "futures-core", + "pin-project-lite", + "tokio", + "tokio-util", +] + +[[package]] +name = "tokio-tfo" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3fb4382c6371e29365853d2b71e915d5398df46312a2158097d8bb3f54d0f1b4" +dependencies = [ + "cfg-if", + "futures", + "libc", + "log", + "once_cell", + "pin-project", + "socket2 0.5.9", + "tokio", + "windows-sys 0.52.0", +] + +[[package]] +name = "tokio-util" +version = "0.7.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2efa149fe76073d6e8fd97ef4f4eca7b67f599660115591483572e406e165594" +dependencies = [ + "bytes", + "futures-core", + "futures-io", + "futures-sink", + "futures-util", + "pin-project-lite", + "tokio", +] + +[[package]] +name = "tokio-websockets" +version = "0.11.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fcaf159b4e7a376b05b5bfd77bfd38f3324f5fce751b4213bfc7eaa47affb4e" +dependencies = [ + "base64", + "bytes", + "futures-core", + "futures-sink", + "getrandom 0.3.3", + "http 1.1.0", + "httparse", + "rand 0.9.2", + "ring", + "rustls-pki-types", + "simdutf8", + "tokio", + "tokio-rustls", + "tokio-util", +] + +[[package]] +name = "toml" +version = "0.9.10+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0825052159284a1a8b4d6c0c86cbc801f2da5afd2b225fa548c72f2e74002f48" +dependencies = [ + "indexmap", + "serde_core", + "serde_spanned", + "toml_datetime 0.7.5+spec-1.1.0", + "toml_parser", + "toml_writer", + "winnow 0.7.13", +] + +[[package]] +name = "toml_datetime" +version = "0.6.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22cddaf88f4fbc13c51aebbf5f8eceb5c7c5a9da2ac40a13519eb5b0a0e8f11c" + +[[package]] +name = "toml_datetime" +version = "0.7.5+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "92e1cfed4a3038bc5a127e35a2d360f145e1f4b971b551a2ba5fd7aedf7e1347" +dependencies = [ + "serde_core", +] + +[[package]] +name = "toml_edit" +version = "0.20.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70f427fce4d84c72b5b732388bf4a9f4531b53f74e2887e3ecb2481f68f66d81" +dependencies = [ + "indexmap", + "toml_datetime 0.6.11", + "winnow 0.5.40", +] + +[[package]] +name = "toml_edit" +version = "0.22.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41fe8c660ae4257887cf66394862d21dbca4a6ddd26f04a3560410406a2f819a" +dependencies = [ + "indexmap", + "toml_datetime 0.6.11", + "toml_write", + "winnow 0.7.13", +] + +[[package]] +name = "toml_parser" +version = "1.0.6+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a3198b4b0a8e11f09dd03e133c0280504d0801269e9afa46362ffde1cbeebf44" +dependencies = [ + "winnow 0.7.13", +] + +[[package]] +name = "toml_write" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d99f8c9a7727884afe522e9bd5edbfc91a3312b36a77b5fb8926e4c31a41801" + +[[package]] +name = "toml_writer" +version = "1.0.6+spec-1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab16f14aed21ee8bfd8ec22513f7287cd4a91aa92e44edfe2c17ddd004e92607" + +[[package]] +name = "tower" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d039ad9159c98b70ecfd540b2573b97f7f52c3e8d9f8ad57a24b916a536975f9" +dependencies = [ + "futures-core", + "futures-util", + "pin-project-lite", + "sync_wrapper", + "tokio", + "tower-layer", + "tower-service", +] + +[[package]] +name = "tower-layer" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "121c2a6cda46980bb0fcd1647ffaf6cd3fc79a013de288782836f6df9c48780e" + +[[package]] +name = "tower-service" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" + +[[package]] +name = "tracing" +version = "0.1.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "63e71662fa4b2a2c3a26f570f037eb95bb1f85397f3cd8076caed2f026a6d100" +dependencies = [ + "log", + "pin-project-lite", + "tracing-attributes", + "tracing-core", +] + +[[package]] +name = "tracing-attributes" +version = "0.1.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7490cfa5ec963746568740651ac6781f701c9c5ea257c58e057f3ba8cf69e8da" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.111", +] + +[[package]] +name = "tracing-core" +version = "0.1.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db97caf9d906fbde555dd62fa95ddba9eecfd14cb388e4f491a66d74cd5fb79a" +dependencies = [ + "once_cell", + "valuable", +] + +[[package]] +name = "tracing-log" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3" +dependencies = [ + "log", + "once_cell", + "tracing-core", +] + +[[package]] +name = "tracing-subscriber" +version = "0.3.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2054a14f5307d601f88daf0553e1cbf472acc4f2c51afab632431cdcd72124d5" +dependencies = [ + "matchers", + "nu-ansi-term", + "once_cell", + "regex-automata", + "sharded-slab", + "smallvec", + "thread_local", + "tracing", + "tracing-core", + "tracing-log", +] + +[[package]] +name = "trait-variant" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70977707304198400eb4835a78f6a9f928bf41bba420deb8fdb175cd965d77a7" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.111", +] + +[[package]] +name = "try-lock" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" + +[[package]] +name = "twofish" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a78e83a30223c757c3947cd144a31014ff04298d8719ae10d03c31c0448c8013" +dependencies = [ + "cipher", +] + +[[package]] +name = "typenum" +version = "1.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1dccffe3ce07af9386bfd29e80c0ab1a8205a2fc34e4bcd40364df902cfa8f3f" + +[[package]] +name = "typescript-type-def" +version = "0.5.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "233ee5e596f41dbaf8c3e48a60b128eadf89395ee9e45fcedc3281c077c5a014" +dependencies = [ + "serde_json", + "typescript-type-def-derive", +] + +[[package]] +name = "typescript-type-def-derive" +version = "0.5.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "912e6d6fed61bac90cd957093b11b5330d756ad4e7b8f309f71ae04b546a8513" +dependencies = [ + "darling", + "ident_case", + "proc-macro-error2", + "proc-macro2", + "quote", + "syn 2.0.111", +] + +[[package]] +name = "ucd-parse" +version = "0.1.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c06ff81122fcbf4df4c1660b15f7e3336058e7aec14437c9f85c6b31a0f279b9" +dependencies = [ + "regex-lite", +] + +[[package]] +name = "ucd-trie" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed646292ffc8188ef8ea4d1e0e0150fb15a5c2e12ad9b8fc191ae7a8a7f3c4b9" + +[[package]] +name = "unarray" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eaea85b334db583fe3274d12b4cd1880032beab409c0d774be044d4480ab9a94" + +[[package]] +name = "unicode-ident" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" + +[[package]] +name = "unicode-linebreak" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b09c83c3c29d37506a3e260c08c03743a6bb66a9cd432c6934ab501a190571f" + +[[package]] +name = "unicode-normalization" +version = "0.1.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5033c97c4262335cded6d6fc3e5c18ab755e1a3dc96376350f3d8e9f009ad956" +dependencies = [ + "tinyvec", +] + +[[package]] +name = "unicode-segmentation" +version = "1.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4c87d22b6e3f4a18d4d40ef354e97c90fcb14dd91d7dc0aa9d8a1172ebf7202" + +[[package]] +name = "unicode-width" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fc81956842c57dac11422a97c3b8195a1ff727f06e85c84ed2e8aa277c9a0fd" + +[[package]] +name = "unicode-xid" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c" + +[[package]] +name = "universal-hash" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc1de2c688dc15305988b563c3854064043356019f97a4b46276fe734c4f07ea" +dependencies = [ + "crypto-common", + "subtle", +] + +[[package]] +name = "untrusted" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" + +[[package]] +name = "url" +version = "2.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32f8b686cadd1473f4bd0117a5d28d36b1ade384ea9b5069a1c40aefed7fda60" +dependencies = [ + "form_urlencoded", + "idna", + "percent-encoding", + "serde", +] + +[[package]] +name = "utf16_iter" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8232dd3cdaed5356e0f716d285e4b40b932ac434100fe9b7e0e8e935b9e6246" + +[[package]] +name = "utf8_iter" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" + +[[package]] +name = "utf8parse" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" + +[[package]] +name = "uuid" +version = "1.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2e054861b4bd027cd373e18e8d8d8e6548085000e41290d95ce0c373a654b4a" +dependencies = [ + "getrandom 0.3.3", + "js-sys", + "serde_core", + "wasm-bindgen", +] + +[[package]] +name = "valuable" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba73ea9cf16a25df0c8caa16c51acb937d5712a8429db78a3ee29d5dcacd3a65" + +[[package]] +name = "vcpkg" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" + +[[package]] +name = "version_check" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" + +[[package]] +name = "walkdir" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "29790946404f91d9c5d06f9874efddea1dc06c5efe94541a7d6863108e3a5e4b" +dependencies = [ + "same-file", + "winapi-util", +] + +[[package]] +name = "want" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" +dependencies = [ + "try-lock", +] + +[[package]] +name = "wasi" +version = "0.11.0+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" + +[[package]] +name = "wasi" +version = "0.14.2+wasi-0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9683f9a5a998d873c0d21fcbe3c083009670149a8fab228644b8bd36b2c48cb3" +dependencies = [ + "wit-bindgen-rt", +] + +[[package]] +name = "wasite" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8dad83b4f25e74f184f64c43b150b91efe7647395b42289f38e50566d82855b" + +[[package]] +name = "wasm-bindgen" +version = "0.2.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1edc8929d7499fc4e8f0be2262a241556cfc54a0bea223790e71446f2aab1ef5" +dependencies = [ + "cfg-if", + "once_cell", + "rustversion", + "wasm-bindgen-macro", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2f0a0651a5c2bc21487bde11ee802ccaf4c51935d0d3d42a6101f98161700bc6" +dependencies = [ + "bumpalo", + "log", + "proc-macro2", + "quote", + "syn 2.0.111", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-futures" +version = "0.4.50" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "555d470ec0bc3bb57890405e5d4322cc9ea83cebb085523ced7be4144dac1e61" +dependencies = [ + "cfg-if", + "js-sys", + "once_cell", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fe63fc6d09ed3792bd0897b314f53de8e16568c2b3f7982f468c0bf9bd0b407" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.111", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a05d73b933a847d6cccdda8f838a22ff101ad9bf93e33684f39c1f5f0eece3d" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "wasm-streams" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4e072d4e72f700fb3443d8fe94a39315df013eef1104903cdb0a2abd322bbecd" +dependencies = [ + "futures-util", + "js-sys", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", +] + +[[package]] +name = "web-sys" +version = "0.3.77" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33b6dd2ef9186f1f2072e409e99cd22a975331a6b3591b12c764e0e55c60d5d2" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "web-time" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a6580f308b1fad9207618087a65c04e7a10bc77e02c8e84e9b00dd4b12fa0bb" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "webpki-roots" +version = "0.26.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2210b291f7ea53617fbafcc4939f10914214ec15aace5ba62293a668f322c5c9" +dependencies = [ + "rustls-pki-types", +] + +[[package]] +name = "weezl" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a28ac98ddc8b9274cb41bb4d9d4d5c425b6020c50c46f25559911905610b4a88" + +[[package]] +name = "whoami" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fec781d48b41f8163426ed18e8fc2864c12937df9ce54c88ede7bd47270893e" +dependencies = [ + "redox_syscall 0.4.1", + "wasite", + "web-sys", +] + +[[package]] +name = "widestring" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "653f141f39ec16bba3c5abe400a0c60da7468261cc2cbf36805022876bc721a8" + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-util" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596" +dependencies = [ + "winapi", +] + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e48a53791691ab099e5e2ad123536d0fff50652600abaf43bbf952894110d0be" +dependencies = [ + "windows-core 0.52.0", + "windows-targets 0.52.6", +] + +[[package]] +name = "windows" +version = "0.58.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd04d41d93c4992d421894c18c8b43496aa748dd4c081bac0dc93eb0489272b6" +dependencies = [ + "windows-core 0.58.0", + "windows-targets 0.52.6", +] + +[[package]] +name = "windows" +version = "0.59.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f919aee0a93304be7f62e8e5027811bbba96bcb1de84d6618be56e43f8a32a1" +dependencies = [ + "windows-core 0.59.0", + "windows-targets 0.53.0", +] + +[[package]] +name = "windows-core" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" +dependencies = [ + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-core" +version = "0.58.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ba6d44ec8c2591c134257ce647b7ea6b20335bf6379a27dac5f1641fcf59f99" +dependencies = [ + "windows-implement 0.58.0", + "windows-interface 0.58.0", + "windows-result 0.2.0", + "windows-strings 0.1.0", + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-core" +version = "0.59.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "810ce18ed2112484b0d4e15d022e5f598113e220c53e373fb31e67e21670c1ce" +dependencies = [ + "windows-implement 0.59.0", + "windows-interface 0.59.0", + "windows-result 0.3.0", + "windows-strings 0.3.0", + "windows-targets 0.53.0", +] + +[[package]] +name = "windows-implement" +version = "0.58.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2bbd5b46c938e506ecbce286b6628a02171d56153ba733b6c741fc627ec9579b" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.111", +] + +[[package]] +name = "windows-implement" +version = "0.59.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "83577b051e2f49a058c308f17f273b570a6a758386fc291b5f6a934dd84e48c1" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.111", +] + +[[package]] +name = "windows-interface" +version = "0.58.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "053c4c462dc91d3b1504c6fe5a726dd15e216ba718e84a0e46a88fbe5ded3515" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.111", +] + +[[package]] +name = "windows-interface" +version = "0.59.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb26fd936d991781ea39e87c3a27285081e3c0da5ca0fcbc02d368cc6f52ff01" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.111", +] + +[[package]] +name = "windows-link" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "45e46c0661abb7180e7b9c281db115305d49ca1709ab8242adf09666d2173c65" + +[[package]] +name = "windows-registry" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4286ad90ddb45071efd1a66dfa43eb02dd0dfbae1545ad6cc3c51cf34d7e8ba3" +dependencies = [ + "windows-result 0.3.0", + "windows-strings 0.3.0", + "windows-targets 0.53.0", +] + +[[package]] +name = "windows-result" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d1043d8214f791817bab27572aaa8af63732e11bf84aa21a45a78d6c317ae0e" +dependencies = [ + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-result" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d08106ce80268c4067c0571ca55a9b4e9516518eaa1a1fe9b37ca403ae1d1a34" +dependencies = [ + "windows-targets 0.53.0", +] + +[[package]] +name = "windows-strings" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4cd9b125c486025df0eabcb585e62173c6c9eddcec5d117d3b6e8c30e2ee4d10" +dependencies = [ + "windows-result 0.2.0", + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-strings" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b888f919960b42ea4e11c2f408fadb55f78a9f236d5eef084103c8ce52893491" +dependencies = [ + "windows-targets 0.53.0", +] + +[[package]] +name = "windows-sys" +version = "0.48.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" +dependencies = [ + "windows-targets 0.48.5", +] + +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-sys" +version = "0.59.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +dependencies = [ + "windows-targets 0.52.6", +] + +[[package]] +name = "windows-sys" +version = "0.61.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f109e41dd4a3c848907eb83d5a42ea98b3769495597450cf6d153507b166f0f" +dependencies = [ + "windows-link", +] + +[[package]] +name = "windows-targets" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" +dependencies = [ + "windows_aarch64_gnullvm 0.48.5", + "windows_aarch64_msvc 0.48.5", + "windows_i686_gnu 0.48.5", + "windows_i686_msvc 0.48.5", + "windows_x86_64_gnu 0.48.5", + "windows_x86_64_gnullvm 0.48.5", + "windows_x86_64_msvc 0.48.5", +] + +[[package]] +name = "windows-targets" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +dependencies = [ + "windows_aarch64_gnullvm 0.52.6", + "windows_aarch64_msvc 0.52.6", + "windows_i686_gnu 0.52.6", + "windows_i686_gnullvm 0.52.6", + "windows_i686_msvc 0.52.6", + "windows_x86_64_gnu 0.52.6", + "windows_x86_64_gnullvm 0.52.6", + "windows_x86_64_msvc 0.52.6", +] + +[[package]] +name = "windows-targets" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1e4c7e8ceaaf9cb7d7507c974735728ab453b67ef8f18febdd7c11fe59dca8b" +dependencies = [ + "windows_aarch64_gnullvm 0.53.0", + "windows_aarch64_msvc 0.53.0", + "windows_i686_gnu 0.53.0", + "windows_i686_gnullvm 0.53.0", + "windows_i686_msvc 0.53.0", + "windows_x86_64_gnu 0.53.0", + "windows_x86_64_gnullvm 0.53.0", + "windows_x86_64_msvc 0.53.0", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86b8d5f90ddd19cb4a147a5fa63ca848db3df085e25fee3cc10b39b6eebae764" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7651a1f62a11b8cbd5e0d42526e55f2c99886c77e007179efff86c2b137e66c" + +[[package]] +name = "windows_i686_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnu" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1dc67659d35f387f5f6c479dc4e28f1d4bb90ddd1a5d3da2e5d97b42d6272c3" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ce6ccbdedbf6d6354471319e781c0dfef054c81fbc7cf83f338a4296c0cae11" + +[[package]] +name = "windows_i686_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" + +[[package]] +name = "windows_i686_msvc" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "581fee95406bb13382d2f65cd4a908ca7b1e4c2f1917f143ba16efe98a589b5d" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e55b5ac9ea33f2fc1716d1742db15574fd6fc8dadc51caab1c16a3d3b4190ba" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a6e035dd0599267ce1ee132e51c27dd29437f63325753051e71dd9e42406c57" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.48.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "271414315aff87387382ec3d271b52d7ae78726f5d44ac98b4f4030c91880486" + +[[package]] +name = "winnow" +version = "0.5.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f593a95398737aeed53e489c785df13f3618e41dbcd6718c6addbf1395aa6876" +dependencies = [ + "memchr", +] + +[[package]] +name = "winnow" +version = "0.7.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21a0236b59786fed61e2a80582dd500fe61f18b5dca67a4a067d0bc9039339cf" +dependencies = [ + "memchr", +] + +[[package]] +name = "winreg" +version = "0.50.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1" +dependencies = [ + "cfg-if", + "windows-sys 0.48.0", +] + +[[package]] +name = "wit-bindgen-rt" +version = "0.39.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6f42320e61fe2cfd34354ecb597f86f413484a798ba44a8ca1165c58d42da6c1" +dependencies = [ + "bitflags 2.9.1", +] + +[[package]] +name = "wmi" +version = "0.14.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7787dacdd8e71cbc104658aade4009300777f9b5fda6a75f19145fedb8a18e71" +dependencies = [ + "chrono", + "futures", + "log", + "serde", + "thiserror 2.0.17", + "windows 0.59.0", + "windows-core 0.59.0", +] + +[[package]] +name = "write16" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1890f4022759daae28ed4fe62859b1236caebfc61ede2f63ed4e695f3f6d936" + +[[package]] +name = "writeable" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e9df38ee2d2c3c5948ea468a8406ff0db0b29ae1ffde1bcf20ef305bcc95c51" + +[[package]] +name = "ws_stream_wasm" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7999f5f4217fe3818726b66257a4475f71e74ffd190776ad053fa159e50737f5" +dependencies = [ + "async_io_stream", + "futures", + "js-sys", + "log", + "pharos", + "rustc_version", + "send_wrapper", + "thiserror 1.0.69", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", +] + +[[package]] +name = "wyz" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed" +dependencies = [ + "tap", +] + +[[package]] +name = "x25519-dalek" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7e468321c81fb07fa7f4c636c3972b9100f0346e5b6a9f2bd0603a52f7ed277" +dependencies = [ + "curve25519-dalek", + "rand_core 0.6.4", + "serde", + "zeroize", +] + +[[package]] +name = "x509-parser" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcbc162f30700d6f3f82a24bf7cc62ffe7caea42c0b2cba8bf7f3ae50cf51f69" +dependencies = [ + "asn1-rs", + "data-encoding", + "der-parser", + "lazy_static", + "nom 7.1.3", + "oid-registry", + "rusticata-macros", + "thiserror 1.0.69", + "time", +] + +[[package]] +name = "xml-rs" +version = "0.8.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c5b940ebc25896e71dd073bad2dbaa2abfe97b0a391415e22ad1326d9c54e3c4" + +[[package]] +name = "xmltree" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7d8a75eaf6557bb84a65ace8609883db44a29951042ada9b393151532e41fcb" +dependencies = [ + "xml-rs", +] + +[[package]] +name = "yansi" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfe53a6657fd280eaa890a3bc59152892ffa3e30101319d168b781ed6529b049" + +[[package]] +name = "yasna" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e17bb3549cc1321ae1296b9cdc2698e2b6cb1992adfa19a8c72e5b7a738f44cd" +dependencies = [ + "time", +] + +[[package]] +name = "yerpc" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1dc24983fbe850227bfc1de89bf8cbfb3e2463afc322e0de2f155c4c23d06445" +dependencies = [ + "anyhow", + "async-channel 1.9.0", + "async-lock", + "async-trait", + "futures", + "futures-util", + "log", + "schemars", + "serde", + "serde_json", + "typescript-type-def", + "yerpc_derive", +] + +[[package]] +name = "yerpc_derive" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d8560d021437420316370db865e44c000bf86380b47cf05e49be9d652042bf5" +dependencies = [ + "convert_case", + "darling", + "proc-macro2", + "quote", + "syn 2.0.111", +] + +[[package]] +name = "yoke" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "120e6aef9aa629e3d4f52dc8cc43a015c7724194c97dfaf45180d2daf2b77f40" +dependencies = [ + "serde", + "stable_deref_trait", + "yoke-derive", + "zerofrom", +] + +[[package]] +name = "yoke-derive" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2380878cad4ac9aac1e2435f3eb4020e8374b5f13c296cb75b4620ff8e229154" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.111", + "synstructure", +] + +[[package]] +name = "z32" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2164e798d9e3d84ee2c91139ace54638059a3b23e361f5c11781c2c6459bde0f" + +[[package]] +name = "zerocopy" +version = "0.7.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74d4d3961e53fa4c9a25a8637fc2bfaf2595b3d3ae34875568a5cf64787716be" +dependencies = [ + "byteorder", + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.7.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.111", +] + +[[package]] +name = "zerofrom" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cff3ee08c995dee1859d998dea82f7374f2826091dd9cd47def953cae446cd2e" +dependencies = [ + "zerofrom-derive", +] + +[[package]] +name = "zerofrom-derive" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "595eed982f7d355beb85837f651fa22e90b3c044842dc7f2c2842c086f295808" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.111", + "synstructure", +] + +[[package]] +name = "zeroize" +version = "1.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde" +dependencies = [ + "zeroize_derive", +] + +[[package]] +name = "zeroize_derive" +version = "1.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.111", +] + +[[package]] +name = "zerovec" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa2b893d79df23bfb12d5461018d408ea19dfafe76c2c7ef6d4eba614f8ff079" +dependencies = [ + "yoke", + "zerofrom", + "zerovec-derive", +] + +[[package]] +name = "zerovec-derive" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6eafa6dfb17584ea3e2bd6e76e0cc15ad7af12b09abdd1ca55961bed9b1063c6" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.111", +] + +[[package]] +name = "zlib-rs" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "868b928d7949e09af2f6086dfc1e01936064cc7a819253bce650d4e2a2d63ba8" + +[[package]] +name = "zmij" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aac060176f7020d62c3bcc1cdbcec619d54f48b07ad1963a3f80ce7a0c17755f" + +[[package]] +name = "zune-core" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "111f7d9820f05fd715df3144e254d6fc02ee4088b0644c0ffd0efc9e6d9d2773" + +[[package]] +name = "zune-jpeg" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc6fb7703e32e9a07fb3f757360338b3a567a5054f21b5f52a666752e333d58e" +dependencies = [ + "zune-core", +] diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..5b2655a6c5f1a27b79e0e04f64dc27c84f74eb4c --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,218 @@ +[package] +name = "deltachat" +version = "2.36.0" +edition = "2024" +license = "MPL-2.0" +rust-version = "1.88" +repository = "https://github.com/chatmail/core" + +[profile.dev] +debug = 0 +panic = 'abort' +opt-level = 1 + +[profile.test] +# Make anyhow `backtrace` feature useful. +# With `debug = 0` there are no line numbers in the backtrace +# produced with RUST_BACKTRACE=1. +debug = 1 +opt-level = 0 + +[profile.fuzz] +inherits = "test" + +# Always optimize dependencies. +# This does not apply to crates in the workspace. +# +[profile.dev.package."*"] +opt-level = "z" + +[profile.release] +lto = true +panic = 'abort' +opt-level = "z" +codegen-units = 1 +strip = true + +[dependencies] +deltachat_derive = { path = "./deltachat_derive" } +deltachat-time = { path = "./deltachat-time" } +deltachat-contact-tools = { workspace = true } +format-flowed = { path = "./format-flowed" } +ratelimit = { path = "./deltachat-ratelimit" } + +anyhow = { workspace = true } +async-broadcast = "0.7.2" +async-channel = { workspace = true } +async-imap = { version = "0.11.1", default-features = false, features = ["runtime-tokio", "compress"] } +async-native-tls = { version = "0.5", default-features = false, features = ["runtime-tokio"] } +async-smtp = { version = "0.10.2", default-features = false, features = ["runtime-tokio"] } +async_zip = { version = "0.0.18", default-features = false, features = ["deflate", "tokio-fs"] } +base64 = { workspace = true } +blake3 = "1.8.2" +brotli = { version = "8", default-features=false, features = ["std"] } +bytes = "1" +chrono = { workspace = true, features = ["alloc", "clock", "std"] } +colorutils-rs = { version = "0.7.5", default-features = false } +data-encoding = "2.9.0" +escaper = "0.1" +fast-socks5 = "0.10" +fd-lock = "4" +futures-lite = { workspace = true } +futures = { workspace = true } +hex = "0.4.0" +http-body-util = "0.1.3" +humansize = "2" +hyper = "1" +hyper-util = "0.1.16" +image = { version = "0.25.6", default-features=false, features = ["gif", "jpeg", "ico", "png", "pnm", "webp", "bmp"] } +iroh-gossip = { version = "0.35", default-features = false, features = ["net"] } +iroh = { version = "0.35", default-features = false } +kamadak-exif = "0.6.1" +libc = { workspace = true } +mail-builder = { version = "0.4.4", default-features = false } +mailparse = { workspace = true } +mime = "0.3.17" +num_cpus = "1.17" +num-derive = "0.4" +num-traits = { workspace = true } +parking_lot = "0.12.4" +percent-encoding = "2.3" +pgp = { version = "0.18.0", default-features = false } +pin-project = "1" +qrcodegen = "1.7.0" +quick-xml = { version = "0.38", features = ["escape-html"] } +rand-old = { package = "rand", version = "0.8" } +rand = { workspace = true } +regex = { workspace = true } +rusqlite = { workspace = true, features = ["sqlcipher"] } +rustls-pki-types = "1.12.0" +sanitize-filename = { workspace = true } +sdp = "0.10.0" +serde_json = { workspace = true } +serde_urlencoded = "0.7.1" +serde = { workspace = true, features = ["derive"] } +sha-1 = "0.10" +sha2 = "0.10" +shadowsocks = { version = "1.23.1", default-features = false, features = ["aead-cipher", "aead-cipher-2022"] } +smallvec = "1.15.1" +strum = "0.27" +strum_macros = "0.27" +tagger = "4.3.4" +textwrap = "0.16.2" +thiserror = { workspace = true } +tokio-io-timeout = "1.2.1" +tokio-rustls = { version = "0.26.2", default-features = false } +tokio-stream = { version = "0.1.17", features = ["fs"] } +astral-tokio-tar = { version = "0.5.6", default-features = false } +tokio-util = { workspace = true } +tokio = { workspace = true, features = ["fs", "rt-multi-thread", "macros"] } +toml = "0.9" +tracing = "0.1.41" +url = "2" +uuid = { version = "1", features = ["serde", "v4"] } +walkdir = "2.5.0" +webpki-roots = "0.26.8" + +[dev-dependencies] +anyhow = { workspace = true, features = ["backtrace"] } # Enable `backtrace` feature in tests. +criterion = { version = "0.8.1", features = ["async_tokio"] } +futures-lite = { workspace = true } +log = { workspace = true } +nu-ansi-term = { workspace = true } +pretty_assertions = "1.4.1" +proptest = { version = "1", default-features = false, features = ["std"] } +tempfile = { workspace = true } +testdir = "0.9.3" +tokio = { workspace = true, features = ["rt-multi-thread", "macros"] } + +[workspace] +members = [ + "deltachat-ffi", + "deltachat_derive", + "deltachat-jsonrpc", + "deltachat-rpc-server", + "deltachat-ratelimit", + "deltachat-repl", + "deltachat-time", + "format-flowed", + "deltachat-contact-tools", + "fuzz", +] + +[[bench]] +name = "create_account" +harness = false + +[[bench]] +name = "contacts" +harness = false + +[[bench]] +name = "search_msgs" +harness = false + +[[bench]] +name = "receive_emails" +required-features = ["internals"] +harness = false + +[[bench]] +name = "decrypting" +required-features = ["internals"] +harness = false + +[[bench]] +name = "get_chat_msgs" +harness = false + +[[bench]] +name = "marknoticed_chat" +harness = false + +[[bench]] +name = "get_chatlist" +harness = false + +[[bench]] +name = "send_events" +harness = false + +[workspace.dependencies] +anyhow = "1" +async-channel = "2.5.0" +base64 = "0.22" +chrono = { version = "0.4.42", default-features = false } +deltachat-contact-tools = { path = "deltachat-contact-tools" } +deltachat-jsonrpc = { path = "deltachat-jsonrpc", default-features = false } +deltachat = { path = ".", default-features = false } +futures = "0.3.31" +futures-lite = "2.6.1" +libc = "0.2" +log = "0.4" +mailparse = "0.16.1" +nu-ansi-term = "0.50" +num-traits = "0.2" +rand = "0.9" +regex = "1.10" +rusqlite = "0.37" +sanitize-filename = "0.6" +serde = "1.0" +serde_json = "1" +tempfile = "3.24.0" +thiserror = "2" +tokio = "1" +tokio-util = "0.7.17" +tracing-subscriber = "0.3" +yerpc = "0.6.4" + +[features] +default = ["vendored"] +internals = [] +vendored = [ + "rusqlite/bundled-sqlcipher-vendored-openssl", + "async-native-tls/vendored" +] + +[lints.rust] +unexpected_cfgs = { level = "warn", check-cfg = ['cfg(fuzzing)'] } diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000000000000000000000000000000000000..7d0aa6a5c13e1bca9b537eb2e5ea7cd45010c202 --- /dev/null +++ b/LICENSE @@ -0,0 +1,377 @@ +The files in this directory and under its subdirectories +are (c) 2019 by Bjoern Petersen and contributors and released under the +Mozilla Public License Version 2.0, see below for a copy. + +Mozilla Public License Version 2.0 +================================== + +1. Definitions +-------------- + +1.1. "Contributor" + means each individual or legal entity that creates, contributes to + the creation of, or owns Covered Software. + +1.2. "Contributor Version" + means the combination of the Contributions of others (if any) used + by a Contributor and that particular Contributor's Contribution. + +1.3. "Contribution" + means Covered Software of a particular Contributor. + +1.4. "Covered Software" + means Source Code Form to which the initial Contributor has attached + the notice in Exhibit A, the Executable Form of such Source Code + Form, and Modifications of such Source Code Form, in each case + including portions thereof. + +1.5. "Incompatible With Secondary Licenses" + means + + (a) that the initial Contributor has attached the notice described + in Exhibit B to the Covered Software; or + + (b) that the Covered Software was made available under the terms of + version 1.1 or earlier of the License, but not also under the + terms of a Secondary License. + +1.6. "Executable Form" + means any form of the work other than Source Code Form. + +1.7. "Larger Work" + means a work that combines Covered Software with other material, in + a separate file or files, that is not Covered Software. + +1.8. "License" + means this document. + +1.9. "Licensable" + means having the right to grant, to the maximum extent possible, + whether at the time of the initial grant or subsequently, any and + all of the rights conveyed by this License. + +1.10. "Modifications" + means any of the following: + + (a) any file in Source Code Form that results from an addition to, + deletion from, or modification of the contents of Covered + Software; or + + (b) any new file in Source Code Form that contains any Covered + Software. + +1.11. "Patent Claims" of a Contributor + means any patent claim(s), including without limitation, method, + process, and apparatus claims, in any patent Licensable by such + Contributor that would be infringed, but for the grant of the + License, by the making, using, selling, offering for sale, having + made, import, or transfer of either its Contributions or its + Contributor Version. + +1.12. "Secondary License" + means either the GNU General Public License, Version 2.0, the GNU + Lesser General Public License, Version 2.1, the GNU Affero General + Public License, Version 3.0, or any later versions of those + licenses. + +1.13. "Source Code Form" + means the form of the work preferred for making modifications. + +1.14. "You" (or "Your") + means an individual or a legal entity exercising rights under this + License. For legal entities, "You" includes any entity that + controls, is controlled by, or is under common control with You. For + purposes of this definition, "control" means (a) the power, direct + or indirect, to cause the direction or management of such entity, + whether by contract or otherwise, or (b) ownership of more than + fifty percent (50%) of the outstanding shares or beneficial + ownership of such entity. + +2. License Grants and Conditions +-------------------------------- + +2.1. Grants + +Each Contributor hereby grants You a world-wide, royalty-free, +non-exclusive license: + +(a) under intellectual property rights (other than patent or trademark) + Licensable by such Contributor to use, reproduce, make available, + modify, display, perform, distribute, and otherwise exploit its + Contributions, either on an unmodified basis, with Modifications, or + as part of a Larger Work; and + +(b) under Patent Claims of such Contributor to make, use, sell, offer + for sale, have made, import, and otherwise transfer either its + Contributions or its Contributor Version. + +2.2. Effective Date + +The licenses granted in Section 2.1 with respect to any Contribution +become effective for each Contribution on the date the Contributor first +distributes such Contribution. + +2.3. Limitations on Grant Scope + +The licenses granted in this Section 2 are the only rights granted under +this License. No additional rights or licenses will be implied from the +distribution or licensing of Covered Software under this License. +Notwithstanding Section 2.1(b) above, no patent license is granted by a +Contributor: + +(a) for any code that a Contributor has removed from Covered Software; + or + +(b) for infringements caused by: (i) Your and any other third party's + modifications of Covered Software, or (ii) the combination of its + Contributions with other software (except as part of its Contributor + Version); or + +(c) under Patent Claims infringed by Covered Software in the absence of + its Contributions. + +This License does not grant any rights in the trademarks, service marks, +or logos of any Contributor (except as may be necessary to comply with +the notice requirements in Section 3.4). + +2.4. Subsequent Licenses + +No Contributor makes additional grants as a result of Your choice to +distribute the Covered Software under a subsequent version of this +License (see Section 10.2) or under the terms of a Secondary License (if +permitted under the terms of Section 3.3). + +2.5. Representation + +Each Contributor represents that the Contributor believes its +Contributions are its original creation(s) or it has sufficient rights +to grant the rights to its Contributions conveyed by this License. + +2.6. Fair Use + +This License is not intended to limit any rights You have under +applicable copyright doctrines of fair use, fair dealing, or other +equivalents. + +2.7. Conditions + +Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted +in Section 2.1. + +3. Responsibilities +------------------- + +3.1. Distribution of Source Form + +All distribution of Covered Software in Source Code Form, including any +Modifications that You create or to which You contribute, must be under +the terms of this License. You must inform recipients that the Source +Code Form of the Covered Software is governed by the terms of this +License, and how they can obtain a copy of this License. You may not +attempt to alter or restrict the recipients' rights in the Source Code +Form. + +3.2. Distribution of Executable Form + +If You distribute Covered Software in Executable Form then: + +(a) such Covered Software must also be made available in Source Code + Form, as described in Section 3.1, and You must inform recipients of + the Executable Form how they can obtain a copy of such Source Code + Form by reasonable means in a timely manner, at a charge no more + than the cost of distribution to the recipient; and + +(b) You may distribute such Executable Form under the terms of this + License, or sublicense it under different terms, provided that the + license for the Executable Form does not attempt to limit or alter + the recipients' rights in the Source Code Form under this License. + +3.3. Distribution of a Larger Work + +You may create and distribute a Larger Work under terms of Your choice, +provided that You also comply with the requirements of this License for +the Covered Software. If the Larger Work is a combination of Covered +Software with a work governed by one or more Secondary Licenses, and the +Covered Software is not Incompatible With Secondary Licenses, this +License permits You to additionally distribute such Covered Software +under the terms of such Secondary License(s), so that the recipient of +the Larger Work may, at their option, further distribute the Covered +Software under the terms of either this License or such Secondary +License(s). + +3.4. Notices + +You may not remove or alter the substance of any license notices +(including copyright notices, patent notices, disclaimers of warranty, +or limitations of liability) contained within the Source Code Form of +the Covered Software, except that You may alter any license notices to +the extent required to remedy known factual inaccuracies. + +3.5. Application of Additional Terms + +You may choose to offer, and to charge a fee for, warranty, support, +indemnity or liability obligations to one or more recipients of Covered +Software. However, You may do so only on Your own behalf, and not on +behalf of any Contributor. You must make it absolutely clear that any +such warranty, support, indemnity, or liability obligation is offered by +You alone, and You hereby agree to indemnify every Contributor for any +liability incurred by such Contributor as a result of warranty, support, +indemnity or liability terms You offer. You may include additional +disclaimers of warranty and limitations of liability specific to any +jurisdiction. + +4. Inability to Comply Due to Statute or Regulation +--------------------------------------------------- + +If it is impossible for You to comply with any of the terms of this +License with respect to some or all of the Covered Software due to +statute, judicial order, or regulation then You must: (a) comply with +the terms of this License to the maximum extent possible; and (b) +describe the limitations and the code they affect. Such description must +be placed in a text file included with all distributions of the Covered +Software under this License. Except to the extent prohibited by statute +or regulation, such description must be sufficiently detailed for a +recipient of ordinary skill to be able to understand it. + +5. Termination +-------------- + +5.1. The rights granted under this License will terminate automatically +if You fail to comply with any of its terms. However, if You become +compliant, then the rights granted under this License from a particular +Contributor are reinstated (a) provisionally, unless and until such +Contributor explicitly and finally terminates Your grants, and (b) on an +ongoing basis, if such Contributor fails to notify You of the +non-compliance by some reasonable means prior to 60 days after You have +come back into compliance. Moreover, Your grants from a particular +Contributor are reinstated on an ongoing basis if such Contributor +notifies You of the non-compliance by some reasonable means, this is the +first time You have received notice of non-compliance with this License +from such Contributor, and You become compliant prior to 30 days after +Your receipt of the notice. + +5.2. If You initiate litigation against any entity by asserting a patent +infringement claim (excluding declaratory judgment actions, +counter-claims, and cross-claims) alleging that a Contributor Version +directly or indirectly infringes any patent, then the rights granted to +You by any and all Contributors for the Covered Software under Section +2.1 of this License shall terminate. + +5.3. In the event of termination under Sections 5.1 or 5.2 above, all +end user license agreements (excluding distributors and resellers) which +have been validly granted by You or Your distributors under this License +prior to termination shall survive termination. + +************************************************************************ +* * +* 6. Disclaimer of Warranty * +* ------------------------- * +* * +* Covered Software is provided under this License on an "as is" * +* basis, without warranty of any kind, either expressed, implied, or * +* statutory, including, without limitation, warranties that the * +* Covered Software is free of defects, merchantable, fit for a * +* particular purpose or non-infringing. The entire risk as to the * +* quality and performance of the Covered Software is with You. * +* Should any Covered Software prove defective in any respect, You * +* (not any Contributor) assume the cost of any necessary servicing, * +* repair, or correction. This disclaimer of warranty constitutes an * +* essential part of this License. No use of any Covered Software is * +* authorized under this License except under this disclaimer. * +* * +************************************************************************ + +************************************************************************ +* * +* 7. Limitation of Liability * +* -------------------------- * +* * +* Under no circumstances and under no legal theory, whether tort * +* (including negligence), contract, or otherwise, shall any * +* Contributor, or anyone who distributes Covered Software as * +* permitted above, be liable to You for any direct, indirect, * +* special, incidental, or consequential damages of any character * +* including, without limitation, damages for lost profits, loss of * +* goodwill, work stoppage, computer failure or malfunction, or any * +* and all other commercial damages or losses, even if such party * +* shall have been informed of the possibility of such damages. This * +* limitation of liability shall not apply to liability for death or * +* personal injury resulting from such party's negligence to the * +* extent applicable law prohibits such limitation. Some * +* jurisdictions do not allow the exclusion or limitation of * +* incidental or consequential damages, so this exclusion and * +* limitation may not apply to You. * +* * +************************************************************************ + +8. Litigation +------------- + +Any litigation relating to this License may be brought only in the +courts of a jurisdiction where the defendant maintains its principal +place of business and such litigation shall be governed by laws of that +jurisdiction, without reference to its conflict-of-law provisions. +Nothing in this Section shall prevent a party's ability to bring +cross-claims or counter-claims. + +9. Miscellaneous +---------------- + +This License represents the complete agreement concerning the subject +matter hereof. If any provision of this License is held to be +unenforceable, such provision shall be reformed only to the extent +necessary to make it enforceable. Any law or regulation which provides +that the language of a contract shall be construed against the drafter +shall not be used to construe this License against a Contributor. + +10. Versions of the License +--------------------------- + +10.1. New Versions + +Mozilla Foundation is the license steward. Except as provided in Section +10.3, no one other than the license steward has the right to modify or +publish new versions of this License. Each version will be given a +distinguishing version number. + +10.2. Effect of New Versions + +You may distribute the Covered Software under the terms of the version +of the License under which You originally received the Covered Software, +or under the terms of any subsequent version published by the license +steward. + +10.3. Modified Versions + +If you create software not governed by this License, and you want to +create a new license for such software, you may create and use a +modified version of this License if you rename the license and remove +any references to the name of the license steward (except to note that +such modified license differs from this License). + +10.4. Distributing Source Code Form that is Incompatible With Secondary +Licenses + +If You choose to distribute Source Code Form that is Incompatible With +Secondary Licenses under the terms of this version of the License, the +notice described in Exhibit B of this License must be attached. + +Exhibit A - Source Code Form License Notice +------------------------------------------- + + This Source Code Form is subject to the terms of the Mozilla Public + License, v. 2.0. If a copy of the MPL was not distributed with this + file, You can obtain one at https://mozilla.org/MPL/2.0/. + +If it is not possible or desirable to put the notice in a particular +file, then You may include the notice in a location (such as a LICENSE +file in a relevant directory) where a recipient would be likely to look +for such a notice. + +You may add additional accurate notices of copyright ownership. + +Exhibit B - "Incompatible With Secondary Licenses" Notice +--------------------------------------------------------- + + This Source Code Form is "Incompatible With Secondary Licenses", as + defined by the Mozilla Public License, v. 2.0. diff --git a/README.md b/README.md new file mode 100644 index 0000000000000000000000000000000000000000..ba61fe7a5c81a350bc50f1bbab73a0f945493b23 --- /dev/null +++ b/README.md @@ -0,0 +1,215 @@ +

+Chatmail logo +

+ +

+ + Rust CI + + + dependency status + +

+ +The chatmail core library implements low-level network and encryption protocols, +integrated by many chat bots and higher level applications, +allowing to securely participate in the globally scaled e-mail server network. +We provide reproducibly-built `deltachat-rpc-server` static binaries +that offer a stdio-based high-level JSON-RPC API for instant messaging purposes. + +The following protocols are handled without requiring API users to know much about them: + +- secure TLS setup with DNS caching and shadowsocks/proxy support + +- robust [SMTP](https://github.com/chatmail/async-imap) + and [IMAP](https://github.com/chatmail/async-smtp) handling + +- safe and interoperable [MIME parsing](https://github.com/staktrace/mailparse) + and [MIME building](https://github.com/stalwartlabs/mail-builder). + +- security-audited end-to-end encryption with [rPGP](https://github.com/rpgp/rpgp) + and [Autocrypt and SecureJoin protocols](https://securejoin.rtfd.io) + +- ephemeral [Peer-to-Peer networking using Iroh](https://iroh.computer) for multi-device setup and + [webxdc realtime data](https://delta.chat/en/2024-11-20-webxdc-realtime). + +- a simulation- and real-world tested [P2P group membership + protocol without requiring server state](https://github.com/chatmail/models/tree/main/group-membership). + + +## Installing Rust and Cargo + +To download and install the official compiler for the Rust programming language, and the Cargo package manager, run the command in your user environment: + +``` +$ curl https://sh.rustup.rs -sSf | sh +``` + +> On Windows, you may need to also install **Perl** to be able to compile deltachat-core. + +## Using the CLI client + +Compile and run the command line utility, using `cargo`: + +``` +$ cargo run --locked -p deltachat-repl -- ~/profile-db +``` +where ~/profile-db is the database file. The utility will create it if it does not exist. + +Optionally, install `deltachat-repl` binary with +``` +$ cargo install --locked --path deltachat-repl/ +``` +and run as +``` +$ deltachat-repl ~/profile-db +``` + +Configure your account (if not already configured): + +``` +Chatmail is awaiting your commands. +> set addr your@email.org +> set mail_pw yourpassword +> configure +``` + +Connect to your mail server (if already configured): + +``` +> connect +``` + +Export your public key to a vCard file: + +``` +> make-vcard my.vcard 1 +``` + +Create contacts by address or vCard file: + +``` +> addcontact yourfriends@email.org +> import-vcard key-contact.vcard +``` + +List contacts: + +``` +> listcontacts +Contact#Contact#11: key-contact@email.org +Contact#Contact#Self: Me √ +2 key contacts. +Contact#Contact#10: yourfriends@email.org +1 address contacts. +``` + +Create a chat with your friend and send a message: + +``` +> createchat 10 +Single#Chat#12 created successfully. +> chat 12 +Selecting chat Chat#12 +Single#Chat#12: yourfriends@email.org [yourfriends@email.org] Icon: profile-db-blobs/4138c52e5bc1c576cda7dd44d088c07.png +0 messages. +81.252µs to create this list, 123.625µs to mark all messages as noticed. +> send hi +``` + +List messages when inside a chat: + +``` +> chat +``` + +For more commands type: + +``` +> help +``` + +## Installing libdeltachat system wide + +``` +$ git clone https://github.com/chatmail/core.git +$ cd deltachat-core-rust +$ cmake -B build . -DCMAKE_INSTALL_PREFIX=/usr +$ cmake --build build +$ sudo cmake --install build +``` + +## Development + +```sh +# run tests +$ cargo test --all +# build c-ffi +$ cargo build -p deltachat_ffi --release +``` + +## Debugging environment variables + +- `DCC_MIME_DEBUG`: if set outgoing and incoming message will be printed + +- `RUST_LOG=async_imap=trace,async_smtp=trace`: enable IMAP and +SMTP tracing in addition to info messages. + +### Expensive tests + +Some tests are expensive and marked with `#[ignore]`, to run these +use the `--ignored` argument to the test binary (not to cargo itself): +```sh +$ cargo test -- --ignored +``` + +### Fuzzing + +Install [`cargo-bolero`](https://github.com/camshaft/bolero) with +```sh +$ cargo install cargo-bolero +``` + +Run fuzzing tests with +```sh +$ cd fuzz +$ cargo bolero test fuzz_mailparse -s NONE +``` + +Corpus is created at `fuzz/fuzz_targets/corpus`, +you can add initial inputs there. +For `fuzz_mailparse` target corpus can be populated with +`../test-data/message/*.eml`. + +## Features + +- `vendored`: When using Openssl for TLS, this bundles a vendored version. + +## Update Provider Data + +To add the updates from the +[provider-db](https://github.com/chatmail/provider-db) to the core, +check line `REV=` inside `./scripts/update-provider-database.sh` +and then run the script. + +## Language bindings and frontend projects + +Language bindings are available for: + +- **C** \[[📂 source](./deltachat-ffi) | [📚 docs](https://c.delta.chat)\] + - -> libdeltachat is going to be deprecated and only exists because Android, iOS and Ubuntu Touch are still using it. If you build a new project, then please use the jsonrpc api instead. +- **JS**: \[[📂 source](./deltachat-rpc-client) | [📦 npm](https://www.npmjs.com/package/@deltachat/jsonrpc-client) | [📚 docs](https://js.jsonrpc.delta.chat/)\] +- **Python** \[[📂 source](./python) | [📦 pypi](https://pypi.org/project/deltachat) | [📚 docs](https://py.delta.chat)\] +- **Go** \[[📂 source](https://github.com/deltachat/deltachat-rpc-client-go/)\] +- **Java** and **Swift** (contained in the Android/iOS repos) + +The following "frontend" projects make use of the Rust-library +or its language bindings: + +- [Android](https://github.com/deltachat/deltachat-android) +- [iOS](https://github.com/deltachat/deltachat-ios) +- [Desktop](https://github.com/deltachat/deltachat-desktop) +- [Pidgin](https://code.ur.gs/lupine/purple-plugin-delta/) +- [Telepathy](https://code.ur.gs/lupine/telepathy-padfoot/) +- [Ubuntu Touch](https://codeberg.org/lk108/deltatouch) +- several **Bots** diff --git a/RELEASE.md b/RELEASE.md new file mode 100644 index 0000000000000000000000000000000000000000..177cceb389978fb486d0c9002012cead27cd7404 --- /dev/null +++ b/RELEASE.md @@ -0,0 +1,21 @@ +# Releasing a new version of DeltaChat core + +For example, to release version 1.116.0 of the core, do the following steps. + +1. Resolve all [blocker issues](https://github.com/chatmail/core/labels/blocker). + +2. Update the changelog: `git cliff --unreleased --tag 1.116.0 --prepend CHANGELOG.md` or `git cliff -u -t 1.116.0 -p CHANGELOG.md`. + +3. add a link to compare previous with current version to the end of CHANGELOG.md: + `[1.116.0]: https://github.com/chatmail/core/compare/v1.115.2...v1.116.0` + +4. Update the version by running `scripts/set_core_version.py 1.116.0`. + +5. Commit the changes as `chore(release): prepare for 1.116.0`. + Optionally, use a separate branch like `prep-1.116.0` for this commit and open a PR for review. + +6. Tag the release: `git tag --annotate v1.116.0`. + +7. Push the release tag: `git push origin v1.116.0`. + +8. Create a GitHub release: `gh release create v1.116.0 --notes ''`. diff --git a/STYLE.md b/STYLE.md new file mode 100644 index 0000000000000000000000000000000000000000..719a6d9dcf0d8ad59b24c88bb141f4a4c145ec89 --- /dev/null +++ b/STYLE.md @@ -0,0 +1,157 @@ +# Coding conventions + +We format the code using `rustfmt`. Run `cargo fmt` prior to committing the code. +Run `scripts/clippy.sh` to check the code for common mistakes with [Clippy]. + +[Clippy]: https://doc.rust-lang.org/clippy/ + +## SQL + +Multi-line SQL statements should be formatted using string literals, +for example +``` + sql.execute( + "CREATE TABLE messages ( +id INTEGER PRIMARY KEY AUTOINCREMENT, +text TEXT DEFAULT '' NOT NULL -- message text +) STRICT", + ) + .await + .context("CREATE TABLE messages")?; +``` + +Do not use macros like [`concat!`](https://doc.rust-lang.org/std/macro.concat.html) +or [`indoc!](https://docs.rs/indoc). +Do not escape newlines like this: +``` + sql.execute( + "CREATE TABLE messages ( \ +id INTEGER PRIMARY KEY AUTOINCREMENT, \ +text TEXT DEFAULT '' NOT NULL \ +) STRICT", + ) + .await + .context("CREATE TABLE messages")?; +``` +Escaping newlines +is prone to errors like this if space before backslash is missing: +``` +"SELECT foo\ + FROM bar" +``` +Literal above results in `SELECT fooFROM bar` string. +This style also does not allow using `--` comments. + +--- + +Declare new SQL tables with [`STRICT`](https://sqlite.org/stricttables.html) keyword +to make SQLite check column types. + +Declare primary keys with [`AUTOINCREMENT`](https://www.sqlite.org/autoinc.html) keyword. +This avoids reuse of the row IDs and can avoid dangerous bugs +like forwarding wrong message because the message was deleted +and another message took its row ID. + +Declare all new columns as `NOT NULL` +and set the `DEFAULT` value if it is optional so the column can be skipped in `INSERT` statements. +Dealing with `NULL` values both in SQL and in Rust is tricky and we try to avoid it. +If column is already declared without `NOT NULL`, use `IFNULL` function to provide default value when selecting it. +Use `HAVING COUNT(*) > 0` clause +to [prevent aggregate functions such as `MIN` and `MAX` from returning `NULL`](https://stackoverflow.com/questions/66527856/aggregate-functions-max-etc-return-null-instead-of-no-rows). + +Don't delete unused columns too early, but maybe after several months/releases, unused columns are +still used by older versions, so deleting them breaks downgrading the core or importing a backup in +an older version. Also don't change the column type, consider adding a new column with another name +instead. Finally, never change column semantics, this is especially dangerous because the `STRICT` +keyword doesn't help here. + +Consider adding context to `anyhow` errors for SQL statements using `.context()` so that it's +possible to understand from logs which statement failed. See [Errors](#errors) for more info. + +## Errors + +Delta Chat core mostly uses [`anyhow`](https://docs.rs/anyhow/) errors. +When using [`Context`](https://docs.rs/anyhow/latest/anyhow/trait.Context.html), +capitalize it but do not add a full stop as the contexts will be separated by `:`. +For example: +``` +.with_context(|| format!("Unable to trash message {msg_id}")) +``` + +All errors should be handled in one of these ways: +- With `if let Err() =` (incl. logging them into `warn!()`/`err!()`). +- With `.log_err().ok()`. +- Bubbled up with `?`. + +When working with [async streams](https://docs.rs/futures/0.3.31/futures/stream/index.html), +prefer [`try_next`](https://docs.rs/futures/0.3.31/futures/stream/trait.TryStreamExt.html#method.try_next) over `next()`, e.g. do +``` +while let Some(event) = stream.try_next().await? { + todo!(); +} +``` +instead of +``` +while let Some(event_res) = stream.next().await { + todo!(); +} +``` +as it allows bubbling up the error early with `?` +with no way to accidentally skip error processing +with early `continue` or `break`. +Some streams reading from a connection +return infinite number of `Some(Err(_))` +items when connection breaks and not processing +errors may result in infinite loop. + +`backtrace` feature is enabled for `anyhow` crate +and `debug = 1` option is set in the test profile. +This allows to run `RUST_BACKTRACE=1 cargo test` +and get a backtrace with line numbers in resultified tests +which return `anyhow::Result`. + +`unwrap` and `expect` are not used in the library +because panics are difficult to debug on user devices. +However, in the tests `.expect` may be used. +Follow + +for `.expect` message style. + +## BTreeMap vs HashMap + +Prefer [BTreeMap](https://doc.rust-lang.org/std/collections/struct.BTreeMap.html) +over [HashMap](https://doc.rust-lang.org/std/collections/struct.HashMap.html) +and [BTreeSet](https://doc.rust-lang.org/std/collections/struct.BTreeSet.html) +over [HashSet](https://doc.rust-lang.org/std/collections/struct.HashSet.html) +as iterating over these structures returns items in deterministic order. + +Non-deterministic code may result in difficult to reproduce bugs, +flaky tests, regression tests that miss bugs +or different behavior on different devices when processing the same messages. + +## Logging + +For logging, use `info!`, `warn!` and `error!` macros. +Log messages should be capitalized and have a full stop in the end. For example: +``` +info!(context, "Ignoring addition of {added_addr:?} to {chat_id}."); +``` + +Format anyhow errors with `{:#}` to print all the contexts like this: +``` +error!(context, "Failed to set selfavatar timestamp: {err:#}."); +``` + +## Documentation comments + +All public modules, methods and fields should be documented. +This is checked by [`missing_docs`](https://doc.rust-lang.org/rustdoc/lints.html#missing_docs) lint. + +Private items do not have to be documented, +but CI uses `cargo doc --document-private-items` +to build the documentation, +so it is preferred that new items +are documented. + +Follow Rust guidelines for the documentation comments: + diff --git a/assets/icon-archive.png b/assets/icon-archive.png new file mode 100644 index 0000000000000000000000000000000000000000..95d35e2a5107e14ee900d0b7947b2eb9a38e6a85 Binary files /dev/null and b/assets/icon-archive.png differ diff --git a/assets/icon-archive.svg b/assets/icon-archive.svg new file mode 100644 index 0000000000000000000000000000000000000000..a8ba45d490e22d1096a3d164f7dd8dcc76cf54be --- /dev/null +++ b/assets/icon-archive.svg @@ -0,0 +1,60 @@ + + + + + + + + + + diff --git a/assets/icon-broadcast.png b/assets/icon-broadcast.png new file mode 100644 index 0000000000000000000000000000000000000000..aa761885eb7d99662335514849a7f6fc6816b2d0 Binary files /dev/null and b/assets/icon-broadcast.png differ diff --git a/assets/icon-broadcast.svg b/assets/icon-broadcast.svg new file mode 100644 index 0000000000000000000000000000000000000000..733e48c1d8701f65882791864e3d4abeb2fa3d67 --- /dev/null +++ b/assets/icon-broadcast.svg @@ -0,0 +1,149 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/icon-device.png b/assets/icon-device.png new file mode 100644 index 0000000000000000000000000000000000000000..87544ceb927e7ff85faae7c14a0bd1ecf5a6fedc Binary files /dev/null and b/assets/icon-device.png differ diff --git a/assets/icon-device.svg b/assets/icon-device.svg new file mode 100644 index 0000000000000000000000000000000000000000..c242507d3717ec0148e445184bd899657374f559 --- /dev/null +++ b/assets/icon-device.svg @@ -0,0 +1,83 @@ + + + + + +Created by potrace 1.15, written by Peter Selinger 2001-2017 + + + image/svg+xml + + + + + + + + + + + diff --git a/assets/icon-saved-messages.png b/assets/icon-saved-messages.png new file mode 100644 index 0000000000000000000000000000000000000000..5020a75ccdce3d4faa87ddde6f58591becae8df5 Binary files /dev/null and b/assets/icon-saved-messages.png differ diff --git a/assets/icon-saved-messages.svg b/assets/icon-saved-messages.svg new file mode 100644 index 0000000000000000000000000000000000000000..20e477599efb48a82b2de803e3625e1148cc6800 --- /dev/null +++ b/assets/icon-saved-messages.svg @@ -0,0 +1,71 @@ + + + + + +Created by potrace 1.15, written by Peter Selinger 2001-2017 + + + image/svg+xml + + + + + + + + diff --git a/assets/icon-unencrypted.png b/assets/icon-unencrypted.png new file mode 100644 index 0000000000000000000000000000000000000000..9262dbdac2586a35d5d305cb5aa3694423bf12bd Binary files /dev/null and b/assets/icon-unencrypted.png differ diff --git a/assets/icon-unencrypted.svg b/assets/icon-unencrypted.svg new file mode 100644 index 0000000000000000000000000000000000000000..0cb9d97a89c67d08d020ef8abdde7be0c8d24087 --- /dev/null +++ b/assets/icon-unencrypted.svg @@ -0,0 +1,47 @@ + + + + + + + diff --git a/assets/icon-webxdc.png b/assets/icon-webxdc.png new file mode 100644 index 0000000000000000000000000000000000000000..8f10d7be95c3ce4926f9aafaf0ee0276ad9c8e55 Binary files /dev/null and b/assets/icon-webxdc.png differ diff --git a/assets/icon-webxdc.svg b/assets/icon-webxdc.svg new file mode 100644 index 0000000000000000000000000000000000000000..67f846d2cfe69370daae27ad164d8ae4b060af8a --- /dev/null +++ b/assets/icon-webxdc.svg @@ -0,0 +1,181 @@ + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/assets/qr_overlay_delta.svg-part b/assets/qr_overlay_delta.svg-part new file mode 100644 index 0000000000000000000000000000000000000000..9830f7b35633f477e949932e6955cf33608e8fa8 --- /dev/null +++ b/assets/qr_overlay_delta.svg-part @@ -0,0 +1,12 @@ + + + + + diff --git a/assets/qrcode_logo_footer.svg b/assets/qrcode_logo_footer.svg new file mode 100644 index 0000000000000000000000000000000000000000..b445e9dd9acdfbc0eeaabcaaf2a4adc15f577c66 --- /dev/null +++ b/assets/qrcode_logo_footer.svg @@ -0,0 +1,10 @@ +get.delta.chat + \ No newline at end of file diff --git a/assets/statistics-bot.vcf b/assets/statistics-bot.vcf new file mode 100644 index 0000000000000000000000000000000000000000..0e38035fe61fd6032a7eee4ae8ffe8281c613dd9 --- /dev/null +++ b/assets/statistics-bot.vcf @@ -0,0 +1,7 @@ +BEGIN:VCARD +VERSION:4.0 +EMAIL:self_reporting@testrun.org +FN:Statistics bot +KEY:data:application/pgp-keys;base64,xjMEZbfBlBYJKwYBBAHaRw8BAQdABpLWS2PUIGGo4pslVt4R8sylP5wZihmhf1DTDr3oCMPNHDxzZWxmX3JlcG9ydGluZ0B0ZXN0cnVuLm9yZz7CiwQQFggAMwIZAQUCZbfBlAIbAwQLCQgHBhUICQoLAgMWAgEWIQTS2i16sHeYTckGn284K3M5Z4oohAAKCRA4K3M5Z4oohD8dAQCQV7CoH6UP4PD+NqI4kW5tbbqdh2AnDROg60qotmLExAEAxDfd3QHAK9f8b9qQUbLmHIztCLxhEuVbWPBEYeVW0gvOOARlt8GUEgorBgEEAZdVAQUBAQdAMBUhYoAAcI625vGZqnM5maPX4sGJ7qvJxPAFILPy6AcDAQgHwngEGBYIACAFAmW3wZQCGwwWIQTS2i16sHeYTckGn284K3M5Z4oohAAKCRA4K3M5Z4oohPwCAQCvzk1ObIkj2GqsuIfaULlgdnfdZY8LNary425CEfHZDQD5AblXVrlMO1frdlc/Vo9z3pEeCrfYdD7ITD3/OeVoiQ4= +REV:20250412T195751Z +END:VCARD diff --git a/assets/welcome-image.jpg b/assets/welcome-image.jpg new file mode 100644 index 0000000000000000000000000000000000000000..2445ef3b0ad98c9f360045a503b347f9edb6860a --- /dev/null +++ b/assets/welcome-image.jpg @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:33295a21c664603a96f82bbc16c3a398de5cc53e7ee99a37af2342d964179485 +size 124234 diff --git a/benches/contacts.rs b/benches/contacts.rs new file mode 100644 index 0000000000000000000000000000000000000000..54e8b0cc47f67537cec509ee51313ed2f699b409 --- /dev/null +++ b/benches/contacts.rs @@ -0,0 +1,47 @@ +#![recursion_limit = "256"] +use std::hint::black_box; + +use criterion::{Criterion, criterion_group, criterion_main}; +use deltachat::Events; +use deltachat::contact::Contact; +use deltachat::context::Context; +use deltachat::stock_str::StockStrings; +use tempfile::tempdir; + +async fn address_book_benchmark(n: u32, read_count: u32) { + let dir = tempdir().unwrap(); + let dbfile = dir.path().join("db.sqlite"); + let id = 100; + let context = Context::new(&dbfile, id, Events::new(), StockStrings::new()) + .await + .unwrap(); + + let book = (0..n) + .map(|i| format!("Name {i}\naddr{i}@example.org\n")) + .collect::>() + .join(""); + + Contact::add_address_book(&context, &book).await.unwrap(); + + let query: Option<&str> = None; + for _ in 0..read_count { + Contact::get_all(&context, 0, query).await.unwrap(); + } +} + +fn criterion_benchmark(c: &mut Criterion) { + let rt = tokio::runtime::Runtime::new().unwrap(); + + c.bench_function("create 500 contacts", |b| { + b.to_async(&rt) + .iter(|| async { address_book_benchmark(black_box(500), black_box(0)).await }) + }); + + c.bench_function("create 100 contacts and read it 1000 times", |b| { + b.to_async(&rt) + .iter(|| async { address_book_benchmark(black_box(100), black_box(1000)).await }) + }); +} + +criterion_group!(benches, criterion_benchmark); +criterion_main!(benches); diff --git a/benches/create_account.rs b/benches/create_account.rs new file mode 100644 index 0000000000000000000000000000000000000000..92e56c3057f376fd3cf001888b859a5c4c327793 --- /dev/null +++ b/benches/create_account.rs @@ -0,0 +1,30 @@ +#![recursion_limit = "256"] +use std::hint::black_box; +use std::path::PathBuf; + +use criterion::{Criterion, criterion_group, criterion_main}; +use deltachat::accounts::Accounts; +use tempfile::tempdir; + +async fn create_accounts(n: u32) { + let dir = tempdir().unwrap(); + let p: PathBuf = dir.path().join("accounts"); + + let writable = true; + let mut accounts = Accounts::new(p.clone(), writable).await.unwrap(); + + for expected_id in 2..n { + let id = accounts.add_account().await.unwrap(); + assert_eq!(id, expected_id); + } +} + +fn criterion_benchmark(c: &mut Criterion) { + c.bench_function("create 1 account", |b| { + let rt = tokio::runtime::Runtime::new().unwrap(); + b.to_async(&rt).iter(|| create_accounts(black_box(1))) + }); +} + +criterion_group!(benches, criterion_benchmark); +criterion_main!(benches); diff --git a/benches/decrypting.rs b/benches/decrypting.rs new file mode 100644 index 0000000000000000000000000000000000000000..4358507821dfa758e442a98ed27db1d033afdb78 --- /dev/null +++ b/benches/decrypting.rs @@ -0,0 +1,201 @@ +//! Benchmarks for message decryption, +//! comparing decryption of symmetrically-encrypted messages +//! to decryption of asymmetrically-encrypted messages. +//! +//! Call with +//! +//! ```text +//! cargo bench --bench decrypting --features="internals" +//! ``` +//! +//! or, if you want to only run e.g. the 'Decrypt a symmetrically encrypted message' benchmark: +//! +//! ```text +//! cargo bench --bench decrypting --features="internals" -- 'Decrypt a symmetrically encrypted message' +//! ``` +//! +//! You can also pass a substring. +//! So, you can run all 'Decrypt and parse' benchmarks with: +//! +//! ```text +//! cargo bench --bench decrypting --features="internals" -- 'Decrypt and parse' +//! ``` +//! +//! Symmetric decryption has to try out all known secrets, +//! You can benchmark this by adapting the `NUM_SECRETS` variable. + +use std::hint::black_box; + +use criterion::{Criterion, criterion_group, criterion_main}; +use deltachat::internals_for_benches::create_broadcast_secret; +use deltachat::internals_for_benches::create_dummy_keypair; +use deltachat::internals_for_benches::save_broadcast_secret; +use deltachat::{ + Events, + chat::ChatId, + config::Config, + context::Context, + internals_for_benches::key_from_asc, + internals_for_benches::parse_and_get_text, + internals_for_benches::store_self_keypair, + pgp::{KeyPair, SeipdVersion, decrypt, pk_encrypt, symm_encrypt_message}, + stock_str::StockStrings, +}; +use rand::{Rng, rng}; +use tempfile::tempdir; + +const NUM_SECRETS: usize = 500; + +async fn create_context() -> Context { + let dir = tempdir().unwrap(); + let dbfile = dir.path().join("db.sqlite"); + let context = Context::new(dbfile.as_path(), 100, Events::new(), StockStrings::new()) + .await + .unwrap(); + + context + .set_config(Config::ConfiguredAddr, Some("bob@example.net")) + .await + .unwrap(); + let secret = key_from_asc(include_str!("../test-data/key/bob-secret.asc")).unwrap(); + let public = secret.signed_public_key(); + let key_pair = KeyPair { public, secret }; + store_self_keypair(&context, &key_pair) + .await + .expect("Failed to save key"); + + context +} + +fn criterion_benchmark(c: &mut Criterion) { + let mut group = c.benchmark_group("Decrypt"); + + // =========================================================================================== + // Benchmarks for decryption only, without any other parsing + // =========================================================================================== + + group.sample_size(10); + + group.bench_function("Decrypt a symmetrically encrypted message", |b| { + let plain = generate_plaintext(); + let secrets = generate_secrets(); + let encrypted = tokio::runtime::Runtime::new().unwrap().block_on(async { + let secret = secrets[NUM_SECRETS / 2].clone(); + symm_encrypt_message( + plain.clone(), + create_dummy_keypair("alice@example.org").unwrap().secret, + black_box(&secret), + true, + ) + .await + .unwrap() + }); + + b.iter(|| { + let mut msg = + decrypt(encrypted.clone().into_bytes(), &[], black_box(&secrets)).unwrap(); + let decrypted = msg.as_data_vec().unwrap(); + + assert_eq!(black_box(decrypted), plain); + }); + }); + + group.bench_function("Decrypt a public-key encrypted message", |b| { + let plain = generate_plaintext(); + let key_pair = create_dummy_keypair("alice@example.org").unwrap(); + let secrets = generate_secrets(); + let encrypted = tokio::runtime::Runtime::new().unwrap().block_on(async { + pk_encrypt( + plain.clone(), + vec![black_box(key_pair.public.clone())], + key_pair.secret.clone(), + true, + true, + SeipdVersion::V2, + ) + .await + .unwrap() + }); + + b.iter(|| { + let mut msg = decrypt( + encrypted.clone().into_bytes(), + std::slice::from_ref(&key_pair.secret), + black_box(&secrets), + ) + .unwrap(); + let decrypted = msg.as_data_vec().unwrap(); + + assert_eq!(black_box(decrypted), plain); + }); + }); + + // =========================================================================================== + // Benchmarks for the whole parsing pipeline, incl. decryption (but excl. receive_imf()) + // =========================================================================================== + + let rt = tokio::runtime::Runtime::new().unwrap(); + let mut secrets = generate_secrets(); + + // "secret" is the shared secret that was used to encrypt text_symmetrically_encrypted.eml. + // Put it into the middle of our secrets: + secrets[NUM_SECRETS / 2] = "secret".to_string(); + + let context = rt.block_on(async { + let context = create_context().await; + for (i, secret) in secrets.iter().enumerate() { + save_broadcast_secret(&context, ChatId::new(10 + i as u32), secret) + .await + .unwrap(); + } + context + }); + + group.bench_function("Decrypt and parse a symmetrically encrypted message", |b| { + b.to_async(&rt).iter(|| { + let ctx = context.clone(); + async move { + let text = parse_and_get_text( + &ctx, + include_bytes!("../test-data/message/text_symmetrically_encrypted.eml"), + ) + .await + .unwrap(); + assert_eq!(text, "Symmetrically encrypted message"); + } + }); + }); + + group.bench_function("Decrypt and parse a public-key encrypted message", |b| { + b.to_async(&rt).iter(|| { + let ctx = context.clone(); + async move { + let text = parse_and_get_text( + &ctx, + include_bytes!("../test-data/message/text_from_alice_encrypted.eml"), + ) + .await + .unwrap(); + assert_eq!(text, "hi"); + } + }); + }); + + group.finish(); +} + +fn generate_secrets() -> Vec { + let secrets: Vec = (0..NUM_SECRETS) + .map(|_| create_broadcast_secret()) + .collect(); + secrets +} + +fn generate_plaintext() -> Vec { + let mut plain: Vec = vec![0; 500]; + rng().fill(&mut plain[..]); + plain +} + +criterion_group!(benches, criterion_benchmark); +criterion_main!(benches); diff --git a/benches/get_chat_msgs.rs b/benches/get_chat_msgs.rs new file mode 100644 index 0000000000000000000000000000000000000000..a4f8fe5896f83b7fd9f4482f892a67b471d1bedf --- /dev/null +++ b/benches/get_chat_msgs.rs @@ -0,0 +1,48 @@ +#![recursion_limit = "256"] +use std::hint::black_box; +use std::path::Path; + +use criterion::{Criterion, criterion_group, criterion_main}; +use deltachat::Events; +use deltachat::chat::{self, ChatId}; +use deltachat::chatlist::Chatlist; +use deltachat::context::Context; +use deltachat::stock_str::StockStrings; + +async fn get_chat_msgs_benchmark(dbfile: &Path, chats: &[ChatId]) { + let id = 100; + let context = Context::new(dbfile, id, Events::new(), StockStrings::new()) + .await + .unwrap(); + + for c in chats.iter().take(10) { + black_box(chat::get_chat_msgs(&context, *c).await.ok()); + } +} + +fn criterion_benchmark(c: &mut Criterion) { + // To enable this benchmark, set `DELTACHAT_BENCHMARK_DATABASE` to some large database with many + // messages, such as your primary account. + if let Ok(path) = std::env::var("DELTACHAT_BENCHMARK_DATABASE") { + let rt = tokio::runtime::Runtime::new().unwrap(); + + let chats: Vec<_> = rt.block_on(async { + let context = Context::new(Path::new(&path), 100, Events::new(), StockStrings::new()) + .await + .unwrap(); + let chatlist = Chatlist::try_load(&context, 0, None, None).await.unwrap(); + let len = chatlist.len(); + (0..len).map(|i| chatlist.get_chat_id(i).unwrap()).collect() + }); + + c.bench_function("chat::get_chat_msgs (load messages from 10 chats)", |b| { + b.to_async(&rt) + .iter(|| get_chat_msgs_benchmark(black_box(path.as_ref()), black_box(&chats))) + }); + } else { + println!("env var not set: DELTACHAT_BENCHMARK_DATABASE"); + } +} + +criterion_group!(benches, criterion_benchmark); +criterion_main!(benches); diff --git a/benches/get_chatlist.rs b/benches/get_chatlist.rs new file mode 100644 index 0000000000000000000000000000000000000000..e6c7de9cfac1c9bcd8830292fe74ef85b57b75fe --- /dev/null +++ b/benches/get_chatlist.rs @@ -0,0 +1,35 @@ +#![recursion_limit = "256"] +use std::hint::black_box; +use std::path::Path; + +use criterion::{Criterion, criterion_group, criterion_main}; +use deltachat::Events; +use deltachat::chatlist::Chatlist; +use deltachat::context::Context; +use deltachat::stock_str::StockStrings; + +async fn get_chat_list_benchmark(context: &Context) { + Chatlist::try_load(context, 0, None, None).await.unwrap(); +} + +fn criterion_benchmark(c: &mut Criterion) { + // To enable this benchmark, set `DELTACHAT_BENCHMARK_DATABASE` to some large database with many + // messages, such as your primary account. + if let Ok(path) = std::env::var("DELTACHAT_BENCHMARK_DATABASE") { + let rt = tokio::runtime::Runtime::new().unwrap(); + let context = rt.block_on(async { + Context::new(Path::new(&path), 100, Events::new(), StockStrings::new()) + .await + .unwrap() + }); + c.bench_function("chatlist:try_load (Get Chatlist)", |b| { + b.to_async(&rt) + .iter(|| get_chat_list_benchmark(black_box(&context))) + }); + } else { + println!("env var not set: DELTACHAT_BENCHMARK_DATABASE"); + } +} + +criterion_group!(benches, criterion_benchmark); +criterion_main!(benches); diff --git a/benches/marknoticed_chat.rs b/benches/marknoticed_chat.rs new file mode 100644 index 0000000000000000000000000000000000000000..46dddb4df9baf0da30d02261a57502672b109d57 --- /dev/null +++ b/benches/marknoticed_chat.rs @@ -0,0 +1,95 @@ +#![recursion_limit = "256"] +use std::hint::black_box; +use std::path::Path; + +use criterion::{BatchSize, Criterion, criterion_group, criterion_main}; +use deltachat::Events; +use deltachat::chat::{self, ChatId}; +use deltachat::chatlist::Chatlist; +use deltachat::context::Context; +use deltachat::stock_str::StockStrings; +use futures_lite::future::block_on; +use tempfile::tempdir; + +async fn marknoticed_chat_benchmark(context: &Context, chats: &[ChatId]) { + for c in chats.iter().take(20) { + chat::marknoticed_chat(context, *c).await.unwrap(); + } +} + +fn criterion_benchmark(c: &mut Criterion) { + // To enable this benchmark, set `DELTACHAT_BENCHMARK_DATABASE` to some large database with many + // messages, such as your primary account. + if let Ok(path) = std::env::var("DELTACHAT_BENCHMARK_DATABASE") { + let rt = tokio::runtime::Runtime::new().unwrap(); + + let chats: Vec<_> = rt.block_on(async { + let context = Context::new(Path::new(&path), 100, Events::new(), StockStrings::new()) + .await + .unwrap(); + let chatlist = Chatlist::try_load(&context, 0, None, None).await.unwrap(); + let len = chatlist.len(); + (1..len).map(|i| chatlist.get_chat_id(i).unwrap()).collect() + }); + + // This mainly tests the performance of marknoticed_chat() + // when nothing has to be done + c.bench_function( + "chat::marknoticed_chat (mark 20 chats as noticed repeatedly)", + |b| { + let dir = tempdir().unwrap(); + let dir = dir.path(); + let new_db = dir.join("dc.db"); + std::fs::copy(&path, &new_db).unwrap(); + + let context = block_on(async { + Context::new(Path::new(&new_db), 100, Events::new(), StockStrings::new()) + .await + .unwrap() + }); + + b.to_async(&rt) + .iter(|| marknoticed_chat_benchmark(&context, black_box(&chats))) + }, + ); + + // If the first 20 chats contain fresh messages or reactions, + // this tests the performance of marking them as noticed. + c.bench_function( + "chat::marknoticed_chat (mark 20 chats as noticed, resetting after every iteration)", + |b| { + b.to_async(&rt).iter_batched( + || { + let dir = tempdir().unwrap(); + let new_db = dir.path().join("dc.db"); + std::fs::copy(&path, &new_db).unwrap(); + + let context = block_on(async { + Context::new( + Path::new(&new_db), + 100, + Events::new(), + StockStrings::new(), + ) + .await + .unwrap() + }); + (dir, context) + }, + |(_dir, context)| { + let chats = &chats; + async move { + marknoticed_chat_benchmark(black_box(&context), black_box(chats)).await + } + }, + BatchSize::PerIteration, + ); + }, + ); + } else { + println!("env var not set: DELTACHAT_BENCHMARK_DATABASE"); + } +} + +criterion_group!(benches, criterion_benchmark); +criterion_main!(benches); diff --git a/benches/receive_emails.rs b/benches/receive_emails.rs new file mode 100644 index 0000000000000000000000000000000000000000..89a3cffee8a9d5d6650c8cb78a5f4ddf722ed23e --- /dev/null +++ b/benches/receive_emails.rs @@ -0,0 +1,160 @@ +#![recursion_limit = "256"] +use std::hint::black_box; +use std::path::PathBuf; + +use criterion::{Criterion, criterion_group, criterion_main}; +use deltachat::{ + Events, + config::Config, + context::Context, + imex::{ImexMode, imex}, + receive_imf::receive_imf, + stock_str::StockStrings, +}; +use tempfile::tempdir; + +async fn recv_all_emails(context: Context, iteration: u32) -> Context { + for i in 0..100 { + let imf_raw = format!( + "Subject: Benchmark +Message-ID: Mr.{iteration}.{i}@testrun.org +Date: Sat, 07 Dec 2019 19:00:27 +0000 +To: alice@example.com +From: sender@testrun.org +Chat-Version: 1.0 +Chat-Disposition-Notification-To: sender@testrun.org +Chat-User-Avatar: 0 +In-Reply-To: Mr.{iteration}.{i_dec}@testrun.org +MIME-Version: 1.0 + +Content-Type: text/plain; charset=utf-8; format=flowed; delsp=no + +Hello {i}", + i = i, + i_dec = i - 1, + ); + receive_imf(&context, black_box(imf_raw.as_bytes()), false) + .await + .unwrap(); + } + context +} + +/// Receive 100 emails that remove charlie@example.com and add +/// him back +async fn recv_groupmembership_emails(context: Context, iteration: u32) -> Context { + for i in 0..50 { + let imf_raw = format!( + "Subject: Benchmark +Message-ID: Gr.{iteration}.ADD.{i}@testrun.org +Date: Sat, 07 Dec 2019 19:00:27 +0000 +To: alice@example.com, b@example.com, c@example.com, d@example.com, e@example.com, f@example.com +From: sender@testrun.org +Chat-Version: 1.0 +Chat-Disposition-Notification-To: sender@testrun.org +Chat-User-Avatar: 0 +Chat-Group-Member-Added: charlie@example.com +In-Reply-To: Gr.{iteration}.REMOVE.{i_dec}@testrun.org +MIME-Version: 1.0 + +Content-Type: text/plain; charset=utf-8; format=flowed; delsp=no + +Hello {i}", + i_dec = i - 1, + ); + receive_imf(&context, black_box(imf_raw.as_bytes()), false) + .await + .unwrap(); + + let imf_raw = format!( + "Subject: Benchmark +Message-ID: Gr.{iteration}.REMOVE.{i}@testrun.org +Date: Sat, 07 Dec 2019 19:00:27 +0000 +To: alice@example.com, b@example.com, c@example.com, d@example.com, e@example.com, f@example.com +From: sender@testrun.org +Chat-Version: 1.0 +Chat-Disposition-Notification-To: sender@testrun.org +Chat-User-Avatar: 0 +Chat-Group-Member-Removed: charlie@example.com +In-Reply-To: Gr.{iteration}.ADD.{i}@testrun.org +MIME-Version: 1.0 + +Content-Type: text/plain; charset=utf-8; format=flowed; delsp=no + +Hello {i}" + ); + receive_imf(&context, black_box(imf_raw.as_bytes()), false) + .await + .unwrap(); + } + context +} + +async fn create_context() -> Context { + let dir = tempdir().unwrap(); + let dbfile = dir.path().join("db.sqlite"); + let id = 100; + let context = Context::new(dbfile.as_path(), id, Events::new(), StockStrings::new()) + .await + .unwrap(); + + let backup: PathBuf = std::env::current_dir() + .unwrap() + .join("delta-chat-backup.tar"); + + if backup.exists() { + println!("Importing backup"); + imex(&context, ImexMode::ImportBackup, backup.as_path(), None) + .await + .unwrap(); + } + + let addr = "alice@example.com"; + context.set_config(Config::Addr, Some(addr)).await.unwrap(); + context + .set_config(Config::ConfiguredAddr, Some(addr)) + .await + .unwrap(); + context + .set_config(Config::Configured, Some("1")) + .await + .unwrap(); + context +} + +fn criterion_benchmark(c: &mut Criterion) { + let mut group = c.benchmark_group("Receive messages"); + group.bench_function("Receive 100 simple text msgs", |b| { + let rt = tokio::runtime::Runtime::new().unwrap(); + let context = rt.block_on(create_context()); + let mut i = 0; + + b.to_async(&rt).iter(|| { + let ctx = context.clone(); + i += 1; + async move { + recv_all_emails(black_box(ctx), i).await; + } + }); + }); + group.bench_function( + "Receive 100 Chat-Group-Member-{Added|Removed} messages", + |b| { + let rt = tokio::runtime::Runtime::new().unwrap(); + let context = rt.block_on(create_context()); + let mut i = 0; + + b.to_async(&rt).iter(|| { + let ctx = context.clone(); + i += 1; + async move { + recv_groupmembership_emails(black_box(ctx), i).await; + } + }); + }, + ); + group.finish(); +} + +criterion_group!(benches, criterion_benchmark); +criterion_main!(benches); diff --git a/benches/search_msgs.rs b/benches/search_msgs.rs new file mode 100644 index 0000000000000000000000000000000000000000..7a640af435f848647f910b1948747e9058eb9749 --- /dev/null +++ b/benches/search_msgs.rs @@ -0,0 +1,36 @@ +#![recursion_limit = "256"] +use std::hint::black_box; +use std::path::Path; + +use criterion::{Criterion, criterion_group, criterion_main}; +use deltachat::Events; +use deltachat::context::Context; +use deltachat::stock_str::StockStrings; + +async fn search_benchmark(dbfile: impl AsRef) { + let id = 100; + let context = Context::new(dbfile.as_ref(), id, Events::new(), StockStrings::new()) + .await + .unwrap(); + + for _ in 0..10u32 { + context.search_msgs(None, "hello").await.unwrap(); + } +} + +fn criterion_benchmark(c: &mut Criterion) { + // To enable this benchmark, set `DELTACHAT_BENCHMARK_DATABASE` to some large database with many + // messages, such as your primary account. + if let Ok(path) = std::env::var("DELTACHAT_BENCHMARK_DATABASE") { + let rt = tokio::runtime::Runtime::new().unwrap(); + + c.bench_function("search hello", |b| { + b.to_async(&rt).iter(|| search_benchmark(black_box(&path))) + }); + } else { + println!("env var not set: DELTACHAT_BENCHMARK_DATABASE"); + } +} + +criterion_group!(benches, criterion_benchmark); +criterion_main!(benches); diff --git a/benches/send_events.rs b/benches/send_events.rs new file mode 100644 index 0000000000000000000000000000000000000000..76001c1770e4cbde79e820b4ef027fe015bbe956 --- /dev/null +++ b/benches/send_events.rs @@ -0,0 +1,48 @@ +#![recursion_limit = "256"] +use criterion::{Criterion, criterion_group, criterion_main}; + +use deltachat::context::Context; +use deltachat::stock_str::StockStrings; +use deltachat::{Event, EventType, Events}; +use tempfile::tempdir; + +async fn send_events_benchmark(context: &Context) { + let emitter = context.get_event_emitter(); + for _i in 0..1_000_000 { + context.emit_event(EventType::Info("interesting event...".to_string())); + } + context.emit_event(EventType::Info("DONE".to_string())); + + loop { + match emitter.recv().await.unwrap() { + Event { + typ: EventType::Info(info), + .. + } if info.contains("DONE") => { + break; + } + _ => {} + } + } +} + +fn criterion_benchmark(c: &mut Criterion) { + let dir = tempdir().unwrap(); + let dbfile = dir.path().join("db.sqlite"); + let rt = tokio::runtime::Runtime::new().unwrap(); + + let context = rt.block_on(async { + Context::new(&dbfile, 100, Events::new(), StockStrings::new()) + .await + .expect("failed to create context") + }); + let executor = tokio::runtime::Runtime::new().unwrap(); + + c.bench_function("Sending 1.000.000 events", |b| { + b.to_async(&executor) + .iter(|| send_events_benchmark(&context)) + }); +} + +criterion_group!(benches, criterion_benchmark); +criterion_main!(benches); diff --git a/cliff.toml b/cliff.toml new file mode 100644 index 0000000000000000000000000000000000000000..b264f420ef30459ec91aa8a029b1104847f95b79 --- /dev/null +++ b/cliff.toml @@ -0,0 +1,93 @@ +# configuration file for git-cliff +# see https://git-cliff.org/docs/configuration/ + + +[git] +# parse the commits based on https://www.conventionalcommits.org +conventional_commits = true +# filter out the commits that are not conventional +filter_unconventional = false +# process each line of a commit as an individual commit +split_commits = false +# regex for preprocessing the commit messages +commit_preprocessors = [ + { pattern = '\((\w+\s)?#([0-9]+)\)', replace = "([#${2}](https://github.com/chatmail/core/pull/${2}))"}, # replace pull request / issue numbers +] +# regex for parsing and grouping commits +commit_parsers = [ + { message = "^feat", group = "Features / Changes"}, + { message = "^fix", group = "Fixes"}, + { message = "^api", group = "API-Changes" }, + { message = "^refactor", group = "Refactor"}, + { message = "^perf", group = "Performance"}, + { message = "^test", group = "Tests"}, + { message = "^style", group = "Styling"}, + { message = "^chore\\(release\\): prepare for", skip = true}, + { message = "^chore", group = "Miscellaneous Tasks"}, + { message = "^build", group = "Build system"}, + { message = "^docs", group = "Documentation"}, + { message = "^ci", group = "CI"}, + { message = ".*", group = "Other"}, +# { body = ".*security", group = "Security"}, +] +# protect breaking changes from being skipped due to matching a skipping commit_parser +protect_breaking_commits = true +# filter out the commits that are not matched by commit parsers +filter_commits = true +# glob pattern for matching git tags +tag_pattern = "v[0-9]*" +# regex for skipping tags +#skip_tags = "v0.1.0-beta.1" +# regex for ignoring tags +ignore_tags = "" +# sort the tags topologically +topo_order = false +# sort the commits inside sections by oldest/newest order +sort_commits = "oldest" +# limit the number of commits included in the changelog. +# limit_commits = 42 + + +[changelog] +# changelog header +header = """ +# Changelog\n +""" +# template for the changelog body +# https://keats.github.io/tera/docs/#templates +body = """ +{% if version %}\ + ## [{{ version | trim_start_matches(pat="v") }}] - {{ timestamp | date(format="%Y-%m-%d") }} +{% else %}\ + ## [unreleased] +{% endif %}\ +{% for group, commits in commits | group_by(attribute="group") %} + ### {{ group | upper_first }} + {% for commit in commits %} + - {% if commit.breaking %}[**breaking**] {% endif %}\ + {% if commit.scope %}{{ commit.scope }}: {% endif %}\ + {{ commit.message | upper_first }}.\ + {% if commit.footers is defined %}\ + {% for footer in commit.footers %}{% if 'BREAKING CHANGE' in footer.token %} + {% raw %} {% endraw %}- {{ footer.value }}\ + {% endif %}{% endfor %}\ + {% endif%}\ + {% endfor %} +{% endfor %}\n +""" +# remove the leading and trailing whitespace from the template +trim = true +footer = """ +{% for release in releases -%} + {% if release.version -%} + {% if release.previous.version -%} + [{{ release.version | trim_start_matches(pat="v") }}]: \ + https://github.com/chatmail/core\ + /compare/{{ release.previous.version }}..{{ release.version }} + {% endif -%} + {% else -%} + [unreleased]: https://github.com/chatmail/core\ + /compare/{{ release.previous.version }}..HEAD + {% endif -%} +{% endfor %} +""" diff --git a/deltachat-contact-tools/Cargo.toml b/deltachat-contact-tools/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..ec1f4c75611df250cd34707e2ec558a97f8815a7 --- /dev/null +++ b/deltachat-contact-tools/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "deltachat-contact-tools" +version = "0.0.0" # No semver-stable versioning +edition = "2021" +description = "Contact-related tools, like parsing vcards and sanitizing name and address. Meant for internal use in the deltachat crate." +license = "MPL-2.0" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +anyhow = { workspace = true } +regex = { workspace = true } +rusqlite = { workspace = true } # Needed in order to `impl rusqlite::types::ToSql for EmailAddress`. Could easily be put behind a feature. +chrono = { workspace = true, features = ["alloc", "clock", "std"] } + +[dev-dependencies] +anyhow = { workspace = true, features = ["backtrace"] } # Enable `backtrace` feature in tests. diff --git a/deltachat-contact-tools/src/lib.rs b/deltachat-contact-tools/src/lib.rs new file mode 100644 index 0000000000000000000000000000000000000000..8ea7c0b6db52b27e6804294684f158db7bbcf71e --- /dev/null +++ b/deltachat-contact-tools/src/lib.rs @@ -0,0 +1,401 @@ +//! Contact-related tools, like parsing vcards and sanitizing name and address + +#![forbid(unsafe_code)] +#![warn( + unused, + clippy::correctness, + missing_debug_implementations, + missing_docs, + clippy::all, + clippy::wildcard_imports, + clippy::needless_borrow, + clippy::cast_lossless, + clippy::unused_async, + clippy::explicit_iter_loop, + clippy::explicit_into_iter_loop, + clippy::cloned_instead_of_copied +)] +#![cfg_attr(not(test), forbid(clippy::indexing_slicing))] +#![cfg_attr(not(test), forbid(clippy::string_slice))] +#![allow( + clippy::match_bool, + clippy::mixed_read_write_in_expression, + clippy::bool_assert_comparison, + clippy::manual_split_once, + clippy::format_push_string, + clippy::bool_to_int_with_if, + clippy::manual_range_contains +)] + +use std::fmt; +use std::ops::Deref; +use std::sync::LazyLock; + +use anyhow::bail; +use anyhow::Result; +use regex::Regex; + +mod vcard; +pub use vcard::{make_vcard, parse_vcard, VcardContact}; + +/// Valid contact address. +#[derive(Debug, Clone)] +pub struct ContactAddress(String); + +impl Deref for ContactAddress { + type Target = str; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl AsRef for ContactAddress { + fn as_ref(&self) -> &str { + &self.0 + } +} + +impl fmt::Display for ContactAddress { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "{}", self.0) + } +} + +impl ContactAddress { + /// Constructs a new contact address from string, + /// normalizing and validating it. + pub fn new(s: &str) -> Result { + let addr = addr_normalize(s); + if !may_be_valid_addr(&addr) { + bail!("invalid address {s:?}"); + } + Ok(Self(addr.to_string())) + } +} + +/// Allow converting [`ContactAddress`] to an SQLite type. +impl rusqlite::types::ToSql for ContactAddress { + fn to_sql(&self) -> rusqlite::Result> { + let val = rusqlite::types::Value::Text(self.0.to_string()); + let out = rusqlite::types::ToSqlOutput::Owned(val); + Ok(out) + } +} + +/// Takes a name and an address and sanitizes them: +/// - Extracts a name from the addr if the addr is in form "Alice " +/// - Removes special characters from the name, see [`sanitize_name()`] +/// - Removes the name if it is equal to the address by setting it to "" +pub fn sanitize_name_and_addr(name: &str, addr: &str) -> (String, String) { + static ADDR_WITH_NAME_REGEX: LazyLock = + LazyLock::new(|| Regex::new("(.*)<(.*)>").unwrap()); + let (name, addr) = if let Some(captures) = ADDR_WITH_NAME_REGEX.captures(addr.as_ref()) { + ( + if name.is_empty() { + captures.get(1).map_or("", |m| m.as_str()) + } else { + name + }, + captures + .get(2) + .map_or("".to_string(), |m| m.as_str().to_string()), + ) + } else { + (name, addr.to_string()) + }; + let mut name = sanitize_name(name); + + // If the 'display name' is just the address, remove it: + // Otherwise, the contact would sometimes be shown as "alice@example.com (alice@example.com)" (see `get_name_n_addr()`). + // If the display name is empty, DC will just show the address when it needs a display name. + if name == addr { + name = "".to_string(); + } + + (name, addr) +} + +/// Sanitizes a name. +/// +/// - Removes newlines and trims the string +/// - Removes quotes (come from some bad MUA implementations) +/// - Removes potentially-malicious bidi characters +pub fn sanitize_name(name: &str) -> String { + let name = sanitize_single_line(name); + + match name.as_bytes() { + [b'\'', .., b'\''] | [b'\"', .., b'\"'] | [b'<', .., b'>'] => name + .get(1..name.len() - 1) + .map_or("".to_string(), |s| s.trim().to_string()), + _ => name.to_string(), + } +} + +/// Sanitizes user input +/// +/// - Removes newlines and trims the string +/// - Removes potentially-malicious bidi characters +pub fn sanitize_single_line(input: &str) -> String { + sanitize_bidi_characters(input.replace(['\n', '\r'], " ").trim()) +} + +const RTLO_CHARACTERS: [char; 5] = ['\u{202A}', '\u{202B}', '\u{202C}', '\u{202D}', '\u{202E}']; +const ISOLATE_CHARACTERS: [char; 3] = ['\u{2066}', '\u{2067}', '\u{2068}']; +const POP_ISOLATE_CHARACTER: char = '\u{2069}'; +/// Some control unicode characters can influence whether adjacent text is shown from +/// left to right or from right to left. +/// +/// Since user input is not supposed to influence how adjacent text looks, +/// this function removes some of these characters. +/// +/// Also see https://github.com/deltachat/deltachat-core-rust/issues/3479. +pub fn sanitize_bidi_characters(input_str: &str) -> String { + // RTLO_CHARACTERS are apparently rarely used in practice. + // They can impact all following text, so, better remove them all: + let input_str = input_str.replace(|char| RTLO_CHARACTERS.contains(&char), ""); + + // If the ISOLATE characters are not ended with a POP DIRECTIONAL ISOLATE character, + // we regard the input as potentially malicious and simply remove all ISOLATE characters. + // See https://en.wikipedia.org/wiki/Bidirectional_text#Unicode_bidi_support + // and https://www.w3.org/International/questions/qa-bidi-unicode-controls.en + // for an explanation about ISOLATE characters. + fn isolate_characters_are_valid(input_str: &str) -> bool { + let mut isolate_character_nesting: i32 = 0; + for char in input_str.chars() { + if ISOLATE_CHARACTERS.contains(&char) { + isolate_character_nesting += 1; + } else if char == POP_ISOLATE_CHARACTER { + isolate_character_nesting -= 1; + } + + // According to Wikipedia, 125 levels are allowed: + // https://en.wikipedia.org/wiki/Unicode_control_characters + // (although, in practice, we could also significantly lower this number) + if isolate_character_nesting < 0 || isolate_character_nesting > 125 { + return false; + } + } + isolate_character_nesting == 0 + } + + if isolate_characters_are_valid(&input_str) { + input_str + } else { + input_str.replace( + |char| ISOLATE_CHARACTERS.contains(&char) || POP_ISOLATE_CHARACTER == char, + "", + ) + } +} + +/// Returns false if addr is an invalid address, otherwise true. +pub fn may_be_valid_addr(addr: &str) -> bool { + let res = EmailAddress::new(addr); + res.is_ok() +} + +/// Returns address lowercased, +/// with whitespace trimmed and `mailto:` prefix removed. +pub fn addr_normalize(addr: &str) -> String { + let norm = addr.trim().to_lowercase(); + + if norm.starts_with("mailto:") { + norm.get(7..).unwrap_or(&norm).to_string() + } else { + norm + } +} + +/// Compares two email addresses, normalizing them beforehand. +pub fn addr_cmp(addr1: &str, addr2: &str) -> bool { + let norm1 = addr_normalize(addr1); + let norm2 = addr_normalize(addr2); + + norm1 == norm2 +} + +/// +/// Represents an email address, right now just the `name@domain` portion. +/// +/// # Example +/// +/// ``` +/// use deltachat_contact_tools::EmailAddress; +/// let email = match EmailAddress::new("someone@example.com") { +/// Ok(addr) => addr, +/// Err(e) => panic!("Error parsing address, error was {}", e), +/// }; +/// assert_eq!(&email.local, "someone"); +/// assert_eq!(&email.domain, "example.com"); +/// assert_eq!(email.to_string(), "someone@example.com"); +/// ``` +#[derive(Debug, PartialEq, Eq, Clone)] +pub struct EmailAddress { + /// Local part of the email address. + pub local: String, + + /// Email address domain. + pub domain: String, +} + +impl fmt::Display for EmailAddress { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "{}@{}", self.local, self.domain) + } +} + +impl EmailAddress { + /// Performs a dead-simple parse of an email address. + pub fn new(input: &str) -> Result { + if input.is_empty() { + bail!("empty string is not valid"); + } + let parts: Vec<&str> = input.rsplitn(2, '@').collect(); + + if input + .chars() + .any(|c| c.is_whitespace() || c == '<' || c == '>') + { + bail!("Email {input:?} must not contain whitespaces, '>' or '<'"); + } + + match &parts[..] { + [domain, local] => { + if local.is_empty() { + bail!("empty string is not valid for local part in {input:?}"); + } + if domain.is_empty() { + bail!("missing domain after '@' in {input:?}"); + } + if domain.ends_with('.') { + bail!("Domain {domain:?} should not contain the dot in the end"); + } + Ok(EmailAddress { + local: (*local).to_string(), + domain: (*domain).to_string(), + }) + } + _ => bail!("Email {input:?} must contain '@' character"), + } + } +} + +impl rusqlite::types::ToSql for EmailAddress { + fn to_sql(&self) -> rusqlite::Result> { + let val = rusqlite::types::Value::Text(self.to_string()); + let out = rusqlite::types::ToSqlOutput::Owned(val); + Ok(out) + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_contact_address() -> Result<()> { + let alice_addr = "alice@example.org"; + let contact_address = ContactAddress::new(alice_addr)?; + assert_eq!(contact_address.as_ref(), alice_addr); + + let invalid_addr = "<> foobar"; + assert!(ContactAddress::new(invalid_addr).is_err()); + + Ok(()) + } + + #[test] + fn test_emailaddress_parse() { + assert_eq!(EmailAddress::new("").is_ok(), false); + assert_eq!( + EmailAddress::new("user@domain.tld").unwrap(), + EmailAddress { + local: "user".into(), + domain: "domain.tld".into(), + } + ); + assert_eq!( + EmailAddress::new("user@localhost").unwrap(), + EmailAddress { + local: "user".into(), + domain: "localhost".into() + } + ); + assert_eq!(EmailAddress::new("uuu").is_ok(), false); + assert_eq!(EmailAddress::new("dd.tt").is_ok(), false); + assert!(EmailAddress::new("tt.dd@uu").is_ok()); + assert!(EmailAddress::new("u@d").is_ok()); + assert!(EmailAddress::new("u@d.").is_err()); + assert!(EmailAddress::new("u@d.t").is_ok()); + assert_eq!( + EmailAddress::new("u@d.tt").unwrap(), + EmailAddress { + local: "u".into(), + domain: "d.tt".into(), + } + ); + assert!(EmailAddress::new("u@tt").is_ok()); + assert_eq!(EmailAddress::new("@d.tt").is_ok(), false); + } + + #[test] + fn test_sanitize_name() { + assert_eq!(&sanitize_name(" hello world "), "hello world"); + assert_eq!(&sanitize_name("<"), "<"); + assert_eq!(&sanitize_name(">"), ">"); + assert_eq!(&sanitize_name("'"), "'"); + assert_eq!(&sanitize_name("\""), "\""); + } + + #[test] + fn test_sanitize_single_line() { + assert_eq!(sanitize_single_line("Hi\naiae "), "Hi aiae"); + assert_eq!(sanitize_single_line("\r\nahte\n\r"), "ahte"); + } + + #[test] + fn test_sanitize_bidi_characters() { + // Legit inputs: + assert_eq!( + &sanitize_bidi_characters("Tes\u{2067}ting Delta Chat\u{2069}"), + "Tes\u{2067}ting Delta Chat\u{2069}" + ); + + assert_eq!( + &sanitize_bidi_characters("Tes\u{2067}ting \u{2068} Delta Chat\u{2069}\u{2069}"), + "Tes\u{2067}ting \u{2068} Delta Chat\u{2069}\u{2069}" + ); + + assert_eq!( + &sanitize_bidi_characters("Tes\u{2067}ting\u{2069} Delta Chat\u{2067}\u{2069}"), + "Tes\u{2067}ting\u{2069} Delta Chat\u{2067}\u{2069}" + ); + + // Potentially-malicious inputs: + assert_eq!( + &sanitize_bidi_characters("Tes\u{202C}ting Delta Chat"), + "Testing Delta Chat" + ); + + assert_eq!( + &sanitize_bidi_characters("Testing Delta Chat\u{2069}"), + "Testing Delta Chat" + ); + + assert_eq!( + &sanitize_bidi_characters("Tes\u{2067}ting Delta Chat"), + "Testing Delta Chat" + ); + + assert_eq!( + &sanitize_bidi_characters("Tes\u{2069}ting Delta Chat\u{2067}"), + "Testing Delta Chat" + ); + + assert_eq!( + &sanitize_bidi_characters("Tes\u{2068}ting Delta Chat"), + "Testing Delta Chat" + ); + } +} diff --git a/deltachat-contact-tools/src/vcard.rs b/deltachat-contact-tools/src/vcard.rs new file mode 100644 index 0000000000000000000000000000000000000000..77ad5bef4336881db9c4e08c0c0625a5197d28e4 --- /dev/null +++ b/deltachat-contact-tools/src/vcard.rs @@ -0,0 +1,247 @@ +use std::sync::LazyLock; + +use anyhow::Context as _; +use anyhow::Result; +use chrono::DateTime; +use chrono::NaiveDateTime; +use regex::Regex; + +use crate::sanitize_name_and_addr; + +#[derive(Debug)] +/// A Contact, as represented in a VCard. +pub struct VcardContact { + /// The email address, vcard property `email` + pub addr: String, + /// This must be the name authorized by the contact itself, not a locally given name. Vcard + /// property `fn`. Can be empty, one should use `display_name()` to obtain the display name. + pub authname: String, + /// The contact's public PGP key in Base64, vcard property `key` + pub key: Option, + /// The contact's profile image (=avatar) in Base64, vcard property `photo` + pub profile_image: Option, + /// The biography, stored in the vcard property `note` + pub biography: Option, + /// The timestamp when the vcard was created / last updated, vcard property `rev` + pub timestamp: Result, +} + +impl VcardContact { + /// Returns the contact's display name. + pub fn display_name(&self) -> &str { + match self.authname.is_empty() { + false => &self.authname, + true => &self.addr, + } + } +} + +/// Returns a vCard containing given contacts. +/// +/// Calling [`parse_vcard()`] on the returned result is a reverse operation. +pub fn make_vcard(contacts: &[VcardContact]) -> String { + fn format_timestamp(c: &VcardContact) -> Option { + let timestamp = *c.timestamp.as_ref().ok()?; + let datetime = DateTime::from_timestamp(timestamp, 0)?; + Some(datetime.format("%Y%m%dT%H%M%SZ").to_string()) + } + + fn escape(s: &str) -> String { + s.replace(',', "\\,") + } + + let mut res = "".to_string(); + for c in contacts { + // Mustn't contain ',', but it's easier to escape than to error out. + let addr = escape(&c.addr); + let display_name = escape(c.display_name()); + res += &format!( + "BEGIN:VCARD\r\n\ + VERSION:4.0\r\n\ + EMAIL:{addr}\r\n\ + FN:{display_name}\r\n" + ); + if let Some(key) = &c.key { + res += &format!("KEY:data:application/pgp-keys;base64\\,{key}\r\n"); + } + if let Some(profile_image) = &c.profile_image { + res += &format!("PHOTO:data:image/jpeg;base64\\,{profile_image}\r\n"); + } + if let Some(biography) = &c.biography { + res += &format!("NOTE:{}\r\n", escape(biography)); + } + if let Some(timestamp) = format_timestamp(c) { + res += &format!("REV:{timestamp}\r\n"); + } + res += "END:VCARD\r\n"; + } + res +} + +/// Parses `VcardContact`s from a given `&str`. +pub fn parse_vcard(vcard: &str) -> Vec { + fn remove_prefix<'a>(s: &'a str, prefix: &str) -> Option<&'a str> { + let start_of_s = s.get(..prefix.len())?; + + if start_of_s.eq_ignore_ascii_case(prefix) { + s.get(prefix.len()..) + } else { + None + } + } + /// Returns (parameters, raw value) tuple. + fn vcard_property_raw<'a>(line: &'a str, property: &str) -> Option<(&'a str, &'a str)> { + let remainder = remove_prefix(line, property)?; + // If `s` is `EMAIL;TYPE=work:alice@example.com` and `property` is `EMAIL`, + // then `remainder` is now `;TYPE=work:alice@example.com` + + // Note: This doesn't handle the case where there are quotes around a colon, + // like `NAME;Foo="Some quoted text: that contains a colon":value`. + // This could be improved in the future, but for now, the parsing is good enough. + let (mut params, value) = remainder.split_once(':')?; + // In the example from above, `params` is now `;TYPE=work` + // and `value` is now `alice@example.com` + + if params + .chars() + .next() + .filter(|c| !c.is_ascii_punctuation() || *c == '_') + .is_some() + { + // `s` started with `property`, but the next character after it was not punctuation, + // so this line's property is actually something else + return None; + } + if let Some(p) = remove_prefix(params, ";") { + params = p; + } + if let Some(p) = remove_prefix(params, "PREF=1") { + params = p; + } + Some((params, value)) + } + /// Returns (parameters, unescaped value) tuple. + fn vcard_property<'a>(line: &'a str, property: &str) -> Option<(&'a str, String)> { + let (params, value) = vcard_property_raw(line, property)?; + // Some fields can't contain commas, but unescape them everywhere for safety. + Some((params, value.replace("\\,", ","))) + } + fn base64_key(line: &str) -> Option<&str> { + let (params, value) = vcard_property_raw(line, "key")?; + if params.eq_ignore_ascii_case("PGP;ENCODING=BASE64") + || params.eq_ignore_ascii_case("TYPE=PGP;ENCODING=b") + { + return Some(value); + } + remove_prefix(value, "data:application/pgp-keys;base64\\,") + // Old Delta Chat format. + .or_else(|| remove_prefix(value, "data:application/pgp-keys;base64,")) + } + fn base64_photo(line: &str) -> Option<&str> { + let (params, value) = vcard_property_raw(line, "photo")?; + if params.eq_ignore_ascii_case("JPEG;ENCODING=BASE64") + || params.eq_ignore_ascii_case("ENCODING=BASE64;JPEG") + || params.eq_ignore_ascii_case("TYPE=JPEG;ENCODING=b") + || params.eq_ignore_ascii_case("ENCODING=b;TYPE=JPEG") + || params.eq_ignore_ascii_case("ENCODING=BASE64;TYPE=JPEG") + || params.eq_ignore_ascii_case("TYPE=JPEG;ENCODING=BASE64") + { + return Some(value); + } + remove_prefix(value, "data:image/jpeg;base64\\,") + // Old Delta Chat format. + .or_else(|| remove_prefix(value, "data:image/jpeg;base64,")) + } + fn parse_datetime(datetime: &str) -> Result { + // According to https://www.rfc-editor.org/rfc/rfc6350#section-4.3.5, the timestamp + // is in ISO.8601.2004 format. DateTime::parse_from_rfc3339() apparently parses + // ISO.8601, but fails to parse any of the examples given. + // So, instead just parse using a format string. + + // Parses 19961022T140000Z, 19961022T140000-05, or 19961022T140000-0500. + let timestamp = match DateTime::parse_from_str(datetime, "%Y%m%dT%H%M%S%#z") { + Ok(datetime) => datetime.timestamp(), + // Parses 19961022T140000. + Err(e) => match NaiveDateTime::parse_from_str(datetime, "%Y%m%dT%H%M%S") { + Ok(datetime) => datetime + .and_local_timezone(chrono::offset::Local) + .single() + .context("Could not apply local timezone to parsed date and time")? + .timestamp(), + Err(_) => return Err(e.into()), + }, + }; + Ok(timestamp) + } + + // Remove line folding, see https://datatracker.ietf.org/doc/html/rfc6350#section-3.2 + static NEWLINE_AND_SPACE_OR_TAB: LazyLock = + LazyLock::new(|| Regex::new("\r?\n[\t ]").unwrap()); + let unfolded_lines = NEWLINE_AND_SPACE_OR_TAB.replace_all(vcard, ""); + + let mut lines = unfolded_lines.lines().peekable(); + let mut contacts = Vec::new(); + + while lines.peek().is_some() { + // Skip to the start of the vcard: + for line in lines.by_ref() { + if line.eq_ignore_ascii_case("BEGIN:VCARD") { + break; + } + } + + let mut display_name = None; + let mut addr = None; + let mut key = None; + let mut photo = None; + let mut biography = None; + let mut datetime = None; + + for mut line in lines.by_ref() { + if let Some(remainder) = remove_prefix(line, "item1.") { + // Remove the group name, if the group is called "item1". + // If necessary, we can improve this to also remove groups that are called something different that "item1". + // + // Search "group name" at https://datatracker.ietf.org/doc/html/rfc6350 for more infos. + line = remainder; + } + + if let Some((_params, email)) = vcard_property(line, "email") { + addr.get_or_insert(email); + } else if let Some((_params, name)) = vcard_property(line, "fn") { + display_name.get_or_insert(name); + } else if let Some(k) = base64_key(line) { + key.get_or_insert(k); + } else if let Some(p) = base64_photo(line) { + photo.get_or_insert(p); + } else if let Some((_params, bio)) = vcard_property(line, "note") { + biography.get_or_insert(bio); + } else if let Some((_params, rev)) = vcard_property(line, "rev") { + datetime.get_or_insert(rev); + } else if line.eq_ignore_ascii_case("END:VCARD") { + let (authname, addr) = sanitize_name_and_addr( + &display_name.unwrap_or_default(), + &addr.unwrap_or_default(), + ); + + contacts.push(VcardContact { + authname, + addr, + key: key.map(|s| s.to_string()), + profile_image: photo.map(|s| s.to_string()), + biography, + timestamp: datetime + .as_deref() + .context("No timestamp in vcard") + .and_then(parse_datetime), + }); + break; + } + } + } + + contacts +} + +#[cfg(test)] +mod vcard_tests; diff --git a/deltachat-contact-tools/src/vcard/vcard_tests.rs b/deltachat-contact-tools/src/vcard/vcard_tests.rs new file mode 100644 index 0000000000000000000000000000000000000000..e8eb3afe9a38501e95e8dae4f65d335f1130dd49 --- /dev/null +++ b/deltachat-contact-tools/src/vcard/vcard_tests.rs @@ -0,0 +1,278 @@ +use chrono::TimeZone as _; + +use super::*; + +#[test] +fn test_vcard_thunderbird() { + let contacts = parse_vcard( + "BEGIN:VCARD +VERSION:4.0 +FN:'Alice Mueller' +EMAIL;PREF=1:alice.mueller@posteo.de +UID:a8083264-ca47-4be7-98a8-8ec3db1447ca +END:VCARD +BEGIN:VCARD +VERSION:4.0 +FN:'bobzzz@freenet.de' +EMAIL;PREF=1:bobzzz@freenet.de +UID:cac4fef4-6351-4854-bbe4-9b6df857eaed +END:VCARD +", + ); + + assert_eq!(contacts[0].addr, "alice.mueller@posteo.de".to_string()); + assert_eq!(contacts[0].authname, "Alice Mueller".to_string()); + assert_eq!(contacts[0].key, None); + assert_eq!(contacts[0].profile_image, None); + assert!(contacts[0].timestamp.is_err()); + + assert_eq!(contacts[1].addr, "bobzzz@freenet.de".to_string()); + assert_eq!(contacts[1].authname, "".to_string()); + assert_eq!(contacts[1].key, None); + assert_eq!(contacts[1].profile_image, None); + assert!(contacts[1].timestamp.is_err()); + + assert_eq!(contacts.len(), 2); +} + +#[test] +fn test_vcard_simple_example() { + let contacts = parse_vcard( + "BEGIN:VCARD +VERSION:4.0 +FN:Alice Wonderland +N:Wonderland;Alice;;;Ms. +GENDER:W +EMAIL;TYPE=work:alice@example.com +KEY;TYPE=PGP;ENCODING=b:[base64-data] +REV:20240418T184242Z + +END:VCARD", + ); + + assert_eq!(contacts[0].addr, "alice@example.com".to_string()); + assert_eq!(contacts[0].authname, "Alice Wonderland".to_string()); + assert_eq!(contacts[0].key, Some("[base64-data]".to_string())); + assert_eq!(contacts[0].profile_image, None); + assert_eq!(*contacts[0].timestamp.as_ref().unwrap(), 1713465762); + + assert_eq!(contacts.len(), 1); +} + +#[test] +fn test_vcard_with_trailing_newline() { + let contacts = parse_vcard( + "BEGIN:VCARD\r +VERSION:4.0\r +FN:Alice Wonderland\r +N:Wonderland;Alice;;;Ms.\r +GENDER:W\r +EMAIL;TYPE=work:alice@example.com\r +KEY;TYPE=PGP;ENCODING=b:[base64-data]\r +REV:20240418T184242Z\r +END:VCARD\r +\r", + ); + + assert_eq!(contacts[0].addr, "alice@example.com".to_string()); + assert_eq!(contacts[0].authname, "Alice Wonderland".to_string()); + assert_eq!(contacts[0].key, Some("[base64-data]".to_string())); + assert_eq!(contacts[0].profile_image, None); + assert_eq!(*contacts[0].timestamp.as_ref().unwrap(), 1713465762); + + assert_eq!(contacts.len(), 1); +} + +#[test] +fn test_make_and_parse_vcard() { + let contacts = [ + VcardContact { + addr: "alice@example.org".to_string(), + authname: "Alice Wonderland".to_string(), + key: Some("[base64-data]".to_string()), + profile_image: Some("image in Base64".to_string()), + biography: Some("Hi, I'm Alice".to_string()), + timestamp: Ok(1713465762), + }, + VcardContact { + addr: "bob@example.com".to_string(), + authname: "".to_string(), + key: None, + profile_image: None, + biography: None, + timestamp: Ok(0), + }, + ]; + let items = [ + "BEGIN:VCARD\r\n\ + VERSION:4.0\r\n\ + EMAIL:alice@example.org\r\n\ + FN:Alice Wonderland\r\n\ + KEY:data:application/pgp-keys;base64\\,[base64-data]\r\n\ + PHOTO:data:image/jpeg;base64\\,image in Base64\r\n\ + NOTE:Hi\\, I'm Alice\r\n\ + REV:20240418T184242Z\r\n\ + END:VCARD\r\n", + "BEGIN:VCARD\r\n\ + VERSION:4.0\r\n\ + EMAIL:bob@example.com\r\n\ + FN:bob@example.com\r\n\ + REV:19700101T000000Z\r\n\ + END:VCARD\r\n", + ]; + let mut expected = "".to_string(); + for len in 0..=contacts.len() { + let contacts = &contacts[0..len]; + let vcard = make_vcard(contacts); + if len > 0 { + expected += items[len - 1]; + } + assert_eq!(vcard, expected); + let parsed = parse_vcard(&vcard); + assert_eq!(parsed.len(), contacts.len()); + for i in 0..parsed.len() { + assert_eq!(parsed[i].addr, contacts[i].addr); + assert_eq!(parsed[i].authname, contacts[i].authname); + assert_eq!(parsed[i].key, contacts[i].key); + assert_eq!(parsed[i].profile_image, contacts[i].profile_image); + assert_eq!( + parsed[i].timestamp.as_ref().unwrap(), + contacts[i].timestamp.as_ref().unwrap() + ); + } + } +} + +#[test] +fn test_vcard_android() { + let contacts = parse_vcard( + "BEGIN:VCARD +VERSION:2.1 +N:;Bob;;; +FN:Bob +TEL;CELL:+1-234-567-890 +EMAIL;HOME:bob@example.org +END:VCARD +BEGIN:VCARD +VERSION:2.1 +N:;Alice;;; +FN:Alice +EMAIL;HOME:alice@example.org +END:VCARD +", + ); + + assert_eq!(contacts[0].addr, "bob@example.org".to_string()); + assert_eq!(contacts[0].authname, "Bob".to_string()); + assert_eq!(contacts[0].key, None); + assert_eq!(contacts[0].profile_image, None); + + assert_eq!(contacts[1].addr, "alice@example.org".to_string()); + assert_eq!(contacts[1].authname, "Alice".to_string()); + assert_eq!(contacts[1].key, None); + assert_eq!(contacts[1].profile_image, None); + + assert_eq!(contacts.len(), 2); +} + +#[test] +fn test_vcard_local_datetime() { + let contacts = parse_vcard( + "BEGIN:VCARD\n\ + VERSION:4.0\n\ + FN:Alice Wonderland\n\ + EMAIL;TYPE=work:alice@example.org\n\ + REV:20240418T184242\n\ + END:VCARD", + ); + assert_eq!(contacts.len(), 1); + assert_eq!(contacts[0].addr, "alice@example.org".to_string()); + assert_eq!(contacts[0].authname, "Alice Wonderland".to_string()); + assert_eq!( + *contacts[0].timestamp.as_ref().unwrap(), + chrono::offset::Local + .with_ymd_and_hms(2024, 4, 18, 18, 42, 42) + .unwrap() + .timestamp() + ); +} + +#[test] +fn test_vcard_with_base64_avatar() { + // This is not an actual base64-encoded avatar, it's just to test the parsing. + // This one is Android-like. + let vcard0 = "BEGIN:VCARD +VERSION:2.1 +N:;Bob;;; +FN:Bob +EMAIL;HOME:bob@example.org +PHOTO;ENCODING=BASE64;JPEG:/9j/4AAQSkZJRgABAQAAAQABAAD/4gIoSUNDX1BST0ZJTEU + AAQEAAAIYAAAAAAQwAABtbnRyUkdCIFhZWiAAAAAAAAAAAAAAAABhY3NwAAAAAAAAAAAAAAAA + L8bRuAJYoZUYrI4ZY3VWwxw4Ay28AAGBISScmf/2Q== + +END:VCARD +"; + // This one is DOS-like. + let vcard1 = vcard0.replace('\n', "\r\n"); + for vcard in [vcard0, vcard1.as_str()] { + let contacts = parse_vcard(vcard); + assert_eq!(contacts.len(), 1); + assert_eq!(contacts[0].addr, "bob@example.org".to_string()); + assert_eq!(contacts[0].authname, "Bob".to_string()); + assert_eq!(contacts[0].key, None); + assert_eq!(contacts[0].profile_image.as_deref().unwrap(), "/9j/4AAQSkZJRgABAQAAAQABAAD/4gIoSUNDX1BST0ZJTEUAAQEAAAIYAAAAAAQwAABtbnRyUkdCIFhZWiAAAAAAAAAAAAAAAABhY3NwAAAAAAAAAAAAAAAAL8bRuAJYoZUYrI4ZY3VWwxw4Ay28AAGBISScmf/2Q=="); + } +} + +#[test] +fn test_protonmail_vcard() { + let contacts = parse_vcard( + "BEGIN:VCARD +VERSION:4.0 +FN;PREF=1:Alice Wonderland +UID:proton-web-03747582-328d-38dc-5ddd-000000000000 +ITEM1.EMAIL;PREF=1:alice@example.org +ITEM1.KEY;PREF=1:data:application/pgp-keys;base64,aaaaaaaaaaaaaaaaaaaaaaaaa + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +ITEM1.KEY;PREF=2:data:application/pgp-keys;base64,bbbbbbbbbbbbbbbbbbbbbbbbb + bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb +ITEM1.X-PM-ENCRYPT:true +ITEM1.X-PM-SIGN:true +END:VCARD", + ); + + assert_eq!(contacts.len(), 1); + assert_eq!(&contacts[0].addr, "alice@example.org"); + assert_eq!(&contacts[0].authname, "Alice Wonderland"); + assert_eq!(contacts[0].key.as_ref().unwrap(), "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"); + assert!(contacts[0].timestamp.is_err()); + assert_eq!(contacts[0].profile_image, None); +} + +/// Proton at some point slightly changed the format of their vcards. +/// This also tests unescaped commas in PHOTO and KEY (old Delta Chat format). +#[test] +fn test_protonmail_vcard2() { + let contacts = parse_vcard( + r"BEGIN:VCARD +VERSION:4.0 +FN;PREF=1:Alice +PHOTO;PREF=1:data:image/jpeg;base64,/9aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/Z +REV:Invalid Date +ITEM1.EMAIL;PREF=1:alice@example.org +KEY;PREF=1:data:application/pgp-keys;base64,xsaaaaaaaaaaaaaaaaaaaaaaaaaaaa + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa + aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa== +UID:proton-web-aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa +END:VCARD", + ); + + assert_eq!(contacts.len(), 1); + assert_eq!(&contacts[0].addr, "alice@example.org"); + assert_eq!(&contacts[0].authname, "Alice"); + assert_eq!(contacts[0].key.as_ref().unwrap(), "xsaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa=="); + assert!(contacts[0].timestamp.is_err()); + assert_eq!(contacts[0].profile_image.as_ref().unwrap(), "/9aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/Z"); +} diff --git a/deltachat-ffi/.gitignore b/deltachat-ffi/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..9c4a538dc2ec34ec4363994bb371fac73242dd47 --- /dev/null +++ b/deltachat-ffi/.gitignore @@ -0,0 +1,4 @@ +/target/ +**/*.rs.bk +Cargo.lock +.profile diff --git a/deltachat-ffi/Cargo.toml b/deltachat-ffi/Cargo.toml new file mode 100644 index 0000000000000000000000000000000000000000..df756728d5024e937ec663a229f15c102d79ffa2 --- /dev/null +++ b/deltachat-ffi/Cargo.toml @@ -0,0 +1,32 @@ +[package] +name = "deltachat_ffi" +version = "2.36.0" +description = "Deltachat FFI" +edition = "2018" +readme = "README.md" +license = "MPL-2.0" + +keywords = ["deltachat", "chat", "openpgp", "email", "encryption"] +categories = ["cryptography", "std", "email"] + +[lib] +name = "deltachat" +crate-type = ["cdylib", "staticlib"] + +[dependencies] +deltachat = { workspace = true, default-features = false } +deltachat-jsonrpc = { workspace = true } +libc = { workspace = true } +human-panic = { version = "2", default-features = false } +num-traits = { workspace = true } +serde_json = { workspace = true } +tokio = { workspace = true, features = ["rt-multi-thread"] } +anyhow = { workspace = true } +thiserror = { workspace = true } +rand = { workspace = true } +yerpc = { workspace = true, features = ["anyhow_expose"] } + +[features] +default = ["vendored"] +vendored = ["deltachat/vendored", "deltachat-jsonrpc/vendored"] + diff --git a/deltachat-ffi/Doxyfile b/deltachat-ffi/Doxyfile new file mode 100644 index 0000000000000000000000000000000000000000..8ef948710e9cb3bc46ef49523b6b5d519951b0cd --- /dev/null +++ b/deltachat-ffi/Doxyfile @@ -0,0 +1,2973 @@ +# Doxyfile 1.13.2 + +# This file describes the settings to be used by the documentation system +# Doxygen (www.doxygen.org) for a project. +# +# All text after a double hash (##) is considered a comment and is placed in +# front of the TAG it is preceding. +# +# All text after a single hash (#) is considered a comment and will be ignored. +# The format is: +# TAG = value [value, ...] +# For lists, items can also be appended using: +# TAG += value [value, ...] +# Values that contain spaces should be placed between quotes (\" \"). +# +# Note: +# +# Use Doxygen to compare the used configuration file with the template +# configuration file: +# doxygen -x [configFile] +# Use Doxygen to compare the used configuration file with the template +# configuration file without replacing the environment variables or CMake type +# replacement variables: +# doxygen -x_noenv [configFile] + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- + +# This tag specifies the encoding used for all characters in the configuration +# file that follow. The default is UTF-8 which is also the encoding used for all +# text before the first occurrence of this tag. Doxygen uses libiconv (or the +# iconv built into libc) for the transcoding. See +# https://www.gnu.org/software/libiconv/ for the list of possible encodings. +# The default value is: UTF-8. + +DOXYFILE_ENCODING = UTF-8 + +# The PROJECT_NAME tag is a single word (or a sequence of words surrounded by +# double-quotes, unless you are using Doxywizard) that should identify the +# project for which the documentation is generated. This name is used in the +# title of most generated pages and in a few other places. +# The default value is: My Project. + +###################################################### + +PROJECT_NAME = "Delta Chat Core C Interface" + +# The PROJECT_NUMBER tag can be used to enter a project or revision number. This +# could be handy for archiving the generated documentation or if some version +# control system is used. + +###################################################### + +PROJECT_NUMBER = + +# Using the PROJECT_BRIEF tag one can provide an optional one line description +# for a project that appears at the top of each page and should give viewers a +# quick idea about the purpose of the project. Keep the description short. + +PROJECT_BRIEF = + +# With the PROJECT_LOGO tag one can specify a logo or an icon that is included +# in the documentation. The maximum height of the logo should not exceed 55 +# pixels and the maximum width should not exceed 200 pixels. Doxygen will copy +# the logo to the output directory. + +PROJECT_LOGO = Doxyfile-logo.png + +# With the PROJECT_ICON tag one can specify an icon that is included in the tabs +# when the HTML document is shown. Doxygen will copy the logo to the output +# directory. + +PROJECT_ICON = + +# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) path +# into which the generated documentation will be written. If a relative path is +# entered, it will be relative to the location where Doxygen was started. If +# left blank the current directory will be used. + +###################################################### + +OUTPUT_DIRECTORY = . + +# If the CREATE_SUBDIRS tag is set to YES then Doxygen will create up to 4096 +# sub-directories (in 2 levels) under the output directory of each output format +# and will distribute the generated files over these directories. Enabling this +# option can be useful when feeding Doxygen a huge amount of source files, where +# putting all generated files in the same directory would otherwise cause +# performance problems for the file system. Adapt CREATE_SUBDIRS_LEVEL to +# control the number of sub-directories. +# The default value is: NO. + +###################################################### + +CREATE_SUBDIRS = NO + +# Controls the number of sub-directories that will be created when +# CREATE_SUBDIRS tag is set to YES. Level 0 represents 16 directories, and every +# level increment doubles the number of directories, resulting in 4096 +# directories at level 8 which is the default and also the maximum value. The +# sub-directories are organized in 2 levels, the first level always has a fixed +# number of 16 directories. +# Minimum value: 0, maximum value: 8, default value: 8. +# This tag requires that the tag CREATE_SUBDIRS is set to YES. + +CREATE_SUBDIRS_LEVEL = 8 + +# If the ALLOW_UNICODE_NAMES tag is set to YES, Doxygen will allow non-ASCII +# characters to appear in the names of generated files. If set to NO, non-ASCII +# characters will be escaped, for example _xE3_x81_x84 will be used for Unicode +# U+3044. +# The default value is: NO. + +ALLOW_UNICODE_NAMES = NO + +# The OUTPUT_LANGUAGE tag is used to specify the language in which all +# documentation generated by Doxygen is written. Doxygen will use this +# information to generate all constant output in the proper language. +# Possible values are: Afrikaans, Arabic, Armenian, Brazilian, Bulgarian, +# Catalan, Chinese, Chinese-Traditional, Croatian, Czech, Danish, Dutch, English +# (United States), Esperanto, Farsi (Persian), Finnish, French, German, Greek, +# Hindi, Hungarian, Indonesian, Italian, Japanese, Japanese-en (Japanese with +# English messages), Korean, Korean-en (Korean with English messages), Latvian, +# Lithuanian, Macedonian, Norwegian, Persian (Farsi), Polish, Portuguese, +# Romanian, Russian, Serbian, Serbian-Cyrillic, Slovak, Slovene, Spanish, +# Swedish, Turkish, Ukrainian and Vietnamese. +# The default value is: English. + +OUTPUT_LANGUAGE = English + +# If the BRIEF_MEMBER_DESC tag is set to YES, Doxygen will include brief member +# descriptions after the members that are listed in the file and class +# documentation (similar to Javadoc). Set to NO to disable this. +# The default value is: YES. + +BRIEF_MEMBER_DESC = YES + +# If the REPEAT_BRIEF tag is set to YES, Doxygen will prepend the brief +# description of a member or function before the detailed description +# +# Note: If both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the +# brief descriptions will be completely suppressed. +# The default value is: YES. + +REPEAT_BRIEF = YES + +# This tag implements a quasi-intelligent brief description abbreviator that is +# used to form the text in various listings. Each string in this list, if found +# as the leading text of the brief description, will be stripped from the text +# and the result, after processing the whole list, is used as the annotated +# text. Otherwise, the brief description is used as-is. If left blank, the +# following values are used ($name is automatically replaced with the name of +# the entity):The $name class, The $name widget, The $name file, is, provides, +# specifies, contains, represents, a, an and the. + +ABBREVIATE_BRIEF = + +# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then +# Doxygen will generate a detailed section even if there is only a brief +# description. +# The default value is: NO. + +ALWAYS_DETAILED_SEC = NO + +# If the INLINE_INHERITED_MEMB tag is set to YES, Doxygen will show all +# inherited members of a class in the documentation of that class as if those +# members were ordinary class members. Constructors, destructors and assignment +# operators of the base classes will not be shown. +# The default value is: NO. + +INLINE_INHERITED_MEMB = NO + +# If the FULL_PATH_NAMES tag is set to YES, Doxygen will prepend the full path +# before files name in the file list and in the header files. If set to NO the +# shortest path that makes the file name unique will be used +# The default value is: YES. + +FULL_PATH_NAMES = YES + +# The STRIP_FROM_PATH tag can be used to strip a user-defined part of the path. +# Stripping is only done if one of the specified strings matches the left-hand +# part of the path. The tag can be used to show relative paths in the file list. +# If left blank the directory from which Doxygen is run is used as the path to +# strip. +# +# Note that you can specify absolute paths here, but also relative paths, which +# will be relative from the directory where Doxygen is started. +# This tag requires that the tag FULL_PATH_NAMES is set to YES. + +STRIP_FROM_PATH = + +# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of the +# path mentioned in the documentation of a class, which tells the reader which +# header file to include in order to use a class. If left blank only the name of +# the header file containing the class definition is used. Otherwise one should +# specify the list of include paths that are normally passed to the compiler +# using the -I flag. + +STRIP_FROM_INC_PATH = + +# If the SHORT_NAMES tag is set to YES, Doxygen will generate much shorter (but +# less readable) file names. This can be useful if your file system doesn't +# support long names like on DOS, Mac, or CD-ROM. +# The default value is: NO. + +SHORT_NAMES = NO + +# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen will interpret the +# first line (until the first dot, question mark or exclamation mark) of a +# Javadoc-style comment as the brief description. If set to NO, the Javadoc- +# style will behave just like regular Qt-style comments (thus requiring an +# explicit @brief command for a brief description.) +# The default value is: NO. + +###################################################### + +JAVADOC_AUTOBRIEF = YES + +# If the JAVADOC_BANNER tag is set to YES then Doxygen will interpret a line +# such as +# /*************** +# as being the beginning of a Javadoc-style comment "banner". If set to NO, the +# Javadoc-style will behave just like regular comments and it will not be +# interpreted by Doxygen. +# The default value is: NO. + +JAVADOC_BANNER = NO + +# If the QT_AUTOBRIEF tag is set to YES then Doxygen will interpret the first +# line (until the first dot, question mark or exclamation mark) of a Qt-style +# comment as the brief description. If set to NO, the Qt-style will behave just +# like regular Qt-style comments (thus requiring an explicit \brief command for +# a brief description.) +# The default value is: NO. + +###################################################### + +QT_AUTOBRIEF = NO + +# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen treat a +# multi-line C++ special comment block (i.e. a block of //! or /// comments) as +# a brief description. This used to be the default behavior. The new default is +# to treat a multi-line C++ comment block as a detailed description. Set this +# tag to YES if you prefer the old behavior instead. +# +# Note that setting this tag to YES also means that rational rose comments are +# not recognized any more. +# The default value is: NO. + +MULTILINE_CPP_IS_BRIEF = NO + +# By default Python docstrings are displayed as preformatted text and Doxygen's +# special commands cannot be used. By setting PYTHON_DOCSTRING to NO the +# Doxygen's special commands can be used and the contents of the docstring +# documentation blocks is shown as Doxygen documentation. +# The default value is: YES. + +PYTHON_DOCSTRING = YES + +# If the INHERIT_DOCS tag is set to YES then an undocumented member inherits the +# documentation from any documented member that it re-implements. +# The default value is: YES. + +INHERIT_DOCS = YES + +# If the SEPARATE_MEMBER_PAGES tag is set to YES then Doxygen will produce a new +# page for each member. If set to NO, the documentation of a member will be part +# of the file/class/namespace that contains it. +# The default value is: NO. + +SEPARATE_MEMBER_PAGES = NO + +# The TAB_SIZE tag can be used to set the number of spaces in a tab. Doxygen +# uses this value to replace tabs by spaces in code fragments. +# Minimum value: 1, maximum value: 16, default value: 4. + +TAB_SIZE = 4 + +# This tag can be used to specify a number of aliases that act as commands in +# the documentation. An alias has the form: +# name=value +# For example adding +# "sideeffect=@par Side Effects:^^" +# will allow you to put the command \sideeffect (or @sideeffect) in the +# documentation, which will result in a user-defined paragraph with heading +# "Side Effects:". Note that you cannot put \n's in the value part of an alias +# to insert newlines (in the resulting output). You can put ^^ in the value part +# of an alias to insert a newline as if a physical newline was in the original +# file. When you need a literal { or } or , in the value part of an alias you +# have to escape them by means of a backslash (\), this can lead to conflicts +# with the commands \{ and \} for these it is advised to use the version @{ and +# @} or use a double escape (\\{ and \\}) + +ALIASES = + +# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources +# only. Doxygen will then generate output that is more tailored for C. For +# instance, some of the names that are used will be different. The list of all +# members will be omitted, etc. +# The default value is: NO. + +###################################################### + +OPTIMIZE_OUTPUT_FOR_C = NO + +# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java or +# Python sources only. Doxygen will then generate output that is more tailored +# for that language. For instance, namespaces will be presented as packages, +# qualified scopes will look different, etc. +# The default value is: NO. + +###################################################### + +OPTIMIZE_OUTPUT_JAVA = NO + +# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran +# sources. Doxygen will then generate output that is tailored for Fortran. +# The default value is: NO. + +OPTIMIZE_FOR_FORTRAN = NO + +# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL +# sources. Doxygen will then generate output that is tailored for VHDL. +# The default value is: NO. + +OPTIMIZE_OUTPUT_VHDL = NO + +# Set the OPTIMIZE_OUTPUT_SLICE tag to YES if your project consists of Slice +# sources only. Doxygen will then generate output that is more tailored for that +# language. For instance, namespaces will be presented as modules, types will be +# separated into more groups, etc. +# The default value is: NO. + +OPTIMIZE_OUTPUT_SLICE = NO + +# Doxygen selects the parser to use depending on the extension of the files it +# parses. With this tag you can assign which parser to use for a given +# extension. Doxygen has a built-in mapping, but you can override or extend it +# using this tag. The format is ext=language, where ext is a file extension, and +# language is one of the parsers supported by Doxygen: IDL, Java, JavaScript, +# Csharp (C#), C, C++, Lex, D, PHP, md (Markdown), Objective-C, Python, Slice, +# VHDL, Fortran (fixed format Fortran: FortranFixed, free formatted Fortran: +# FortranFree, unknown formatted Fortran: Fortran. In the later case the parser +# tries to guess whether the code is fixed or free formatted code, this is the +# default for Fortran type files). For instance to make Doxygen treat .inc files +# as Fortran files (default is PHP), and .f files as C (default is Fortran), +# use: inc=Fortran f=C. +# +# Note: For files without extension you can use no_extension as a placeholder. +# +# Note that for custom extensions you also need to set FILE_PATTERNS otherwise +# the files are not read by Doxygen. When specifying no_extension you should add +# * to the FILE_PATTERNS. +# +# Note see also the list of default file extension mappings. + +EXTENSION_MAPPING = + +# If the MARKDOWN_SUPPORT tag is enabled then Doxygen pre-processes all comments +# according to the Markdown format, which allows for more readable +# documentation. See https://daringfireball.net/projects/markdown/ for details. +# The output of markdown processing is further processed by Doxygen, so you can +# mix Doxygen, HTML, and XML commands with Markdown formatting. Disable only in +# case of backward compatibilities issues. +# The default value is: YES. + +MARKDOWN_SUPPORT = YES + +# When the TOC_INCLUDE_HEADINGS tag is set to a non-zero value, all headings up +# to that level are automatically included in the table of contents, even if +# they do not have an id attribute. +# Note: This feature currently applies only to Markdown headings. +# Minimum value: 0, maximum value: 99, default value: 6. +# This tag requires that the tag MARKDOWN_SUPPORT is set to YES. + +TOC_INCLUDE_HEADINGS = 6 + +# The MARKDOWN_ID_STYLE tag can be used to specify the algorithm used to +# generate identifiers for the Markdown headings. Note: Every identifier is +# unique. +# Possible values are: DOXYGEN use a fixed 'autotoc_md' string followed by a +# sequence number starting at 0 and GITHUB use the lower case version of title +# with any whitespace replaced by '-' and punctuation characters removed. +# The default value is: DOXYGEN. +# This tag requires that the tag MARKDOWN_SUPPORT is set to YES. + +MARKDOWN_ID_STYLE = DOXYGEN + +# When enabled Doxygen tries to link words that correspond to documented +# classes, or namespaces to their corresponding documentation. Such a link can +# be prevented in individual cases by putting a % sign in front of the word or +# globally by setting AUTOLINK_SUPPORT to NO. Words listed in the +# AUTOLINK_IGNORE_WORDS tag are excluded from automatic linking. +# The default value is: YES. + +AUTOLINK_SUPPORT = YES + +# This tag specifies a list of words that, when matching the start of a word in +# the documentation, will suppress auto links generation, if it is enabled via +# AUTOLINK_SUPPORT. This list does not affect affect links explicitly created +# using \# or the \link or commands. +# This tag requires that the tag AUTOLINK_SUPPORT is set to YES. + +AUTOLINK_IGNORE_WORDS = + +# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want +# to include (a tag file for) the STL sources as input, then you should set this +# tag to YES in order to let Doxygen match functions declarations and +# definitions whose arguments contain STL classes (e.g. func(std::string); +# versus func(std::string) {}). This also makes the inheritance and +# collaboration diagrams that involve STL classes more complete and accurate. +# The default value is: NO. + +BUILTIN_STL_SUPPORT = NO + +# If you use Microsoft's C++/CLI language, you should set this option to YES to +# enable parsing support. +# The default value is: NO. + +CPP_CLI_SUPPORT = NO + +# Set the SIP_SUPPORT tag to YES if your project consists of sip (see: +# https://www.riverbankcomputing.com/software) sources only. Doxygen will parse +# them like normal C++ but will assume all classes use public instead of private +# inheritance when no explicit protection keyword is present. +# The default value is: NO. + +SIP_SUPPORT = NO + +# For Microsoft's IDL there are propget and propput attributes to indicate +# getter and setter methods for a property. Setting this option to YES will make +# Doxygen to replace the get and set methods by a property in the documentation. +# This will only work if the methods are indeed getting or setting a simple +# type. If this is not the case, or you want to show the methods anyway, you +# should set this option to NO. +# The default value is: YES. + +IDL_PROPERTY_SUPPORT = YES + +# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC +# tag is set to YES then Doxygen will reuse the documentation of the first +# member in the group (if any) for the other members of the group. By default +# all members of a group must be documented explicitly. +# The default value is: NO. + +DISTRIBUTE_GROUP_DOC = NO + +# If one adds a struct or class to a group and this option is enabled, then also +# any nested class or struct is added to the same group. By default this option +# is disabled and one has to add nested compounds explicitly via \ingroup. +# The default value is: NO. + +GROUP_NESTED_COMPOUNDS = NO + +# Set the SUBGROUPING tag to YES to allow class member groups of the same type +# (for instance a group of public functions) to be put as a subgroup of that +# type (e.g. under the Public Functions section). Set it to NO to prevent +# subgrouping. Alternatively, this can be done per class using the +# \nosubgrouping command. +# The default value is: YES. + +SUBGROUPING = YES + +# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and unions +# are shown inside the group in which they are included (e.g. using \ingroup) +# instead of on a separate page (for HTML and Man pages) or section (for LaTeX +# and RTF). +# +# Note that this feature does not work in combination with +# SEPARATE_MEMBER_PAGES. +# The default value is: NO. + +INLINE_GROUPED_CLASSES = NO + +# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and unions +# with only public data fields or simple typedef fields will be shown inline in +# the documentation of the scope in which they are defined (i.e. file, +# namespace, or group documentation), provided this scope is documented. If set +# to NO, structs, classes, and unions are shown on a separate page (for HTML and +# Man pages) or section (for LaTeX and RTF). +# The default value is: NO. + +INLINE_SIMPLE_STRUCTS = NO + +# When TYPEDEF_HIDES_STRUCT tag is enabled, a typedef of a struct, union, or +# enum is documented as struct, union, or enum with the name of the typedef. So +# typedef struct TypeS {} TypeT, will appear in the documentation as a struct +# with name TypeT. When disabled the typedef will appear as a member of a file, +# namespace, or class. And the struct will be named TypeS. This can typically be +# useful for C code in case the coding convention dictates that all compound +# types are typedef'ed and only the typedef is referenced, never the tag name. +# The default value is: NO. + +TYPEDEF_HIDES_STRUCT = NO + +# The size of the symbol lookup cache can be set using LOOKUP_CACHE_SIZE. This +# cache is used to resolve symbols given their name and scope. Since this can be +# an expensive process and often the same symbol appears multiple times in the +# code, Doxygen keeps a cache of pre-resolved symbols. If the cache is too small +# Doxygen will become slower. If the cache is too large, memory is wasted. The +# cache size is given by this formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range +# is 0..9, the default is 0, corresponding to a cache size of 2^16=65536 +# symbols. At the end of a run Doxygen will report the cache usage and suggest +# the optimal cache size from a speed point of view. +# Minimum value: 0, maximum value: 9, default value: 0. + +LOOKUP_CACHE_SIZE = 0 + +# The NUM_PROC_THREADS specifies the number of threads Doxygen is allowed to use +# during processing. When set to 0 Doxygen will based this on the number of +# cores available in the system. You can set it explicitly to a value larger +# than 0 to get more control over the balance between CPU load and processing +# speed. At this moment only the input processing can be done using multiple +# threads. Since this is still an experimental feature the default is set to 1, +# which effectively disables parallel processing. Please report any issues you +# encounter. Generating dot graphs in parallel is controlled by the +# DOT_NUM_THREADS setting. +# Minimum value: 0, maximum value: 32, default value: 1. + +NUM_PROC_THREADS = 1 + +# If the TIMESTAMP tag is set different from NO then each generated page will +# contain the date or date and time when the page was generated. Setting this to +# NO can help when comparing the output of multiple runs. +# Possible values are: YES, NO, DATETIME and DATE. +# The default value is: NO. + +TIMESTAMP = NO + +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- + +# If the EXTRACT_ALL tag is set to YES, Doxygen will assume all entities in +# documentation are documented, even if no documentation was available. Private +# class members and static file members will be hidden unless the +# EXTRACT_PRIVATE respectively EXTRACT_STATIC tags are set to YES. +# Note: This will also disable the warnings about undocumented members that are +# normally produced when WARNINGS is set to YES. +# The default value is: NO. + +EXTRACT_ALL = NO + +# If the EXTRACT_PRIVATE tag is set to YES, all private members of a class will +# be included in the documentation. +# The default value is: NO. + +EXTRACT_PRIVATE = NO + +# If the EXTRACT_PRIV_VIRTUAL tag is set to YES, documented private virtual +# methods of a class will be included in the documentation. +# The default value is: NO. + +EXTRACT_PRIV_VIRTUAL = NO + +# If the EXTRACT_PACKAGE tag is set to YES, all members with package or internal +# scope will be included in the documentation. +# The default value is: NO. + +EXTRACT_PACKAGE = NO + +# If the EXTRACT_STATIC tag is set to YES, all static members of a file will be +# included in the documentation. +# The default value is: NO. + +EXTRACT_STATIC = NO + +# If the EXTRACT_LOCAL_CLASSES tag is set to YES, classes (and structs) defined +# locally in source files will be included in the documentation. If set to NO, +# only classes defined in header files are included. Does not have any effect +# for Java sources. +# The default value is: YES. + +###################################################### + +EXTRACT_LOCAL_CLASSES = NO + +# This flag is only useful for Objective-C code. If set to YES, local methods, +# which are defined in the implementation section but not in the interface are +# included in the documentation. If set to NO, only methods in the interface are +# included. +# The default value is: NO. + +###################################################### + +EXTRACT_LOCAL_METHODS = NO + +# If this flag is set to YES, the members of anonymous namespaces will be +# extracted and appear in the documentation as a namespace called +# 'anonymous_namespace{file}', where file will be replaced with the base name of +# the file that contains the anonymous namespace. By default anonymous namespace +# are hidden. +# The default value is: NO. + +EXTRACT_ANON_NSPACES = NO + +# If this flag is set to YES, the name of an unnamed parameter in a declaration +# will be determined by the corresponding definition. By default unnamed +# parameters remain unnamed in the output. +# The default value is: YES. + +RESOLVE_UNNAMED_PARAMS = YES + +# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all +# undocumented members inside documented classes or files. If set to NO these +# members will be included in the various overviews, but no documentation +# section is generated. This option has no effect if EXTRACT_ALL is enabled. +# The default value is: NO. + +HIDE_UNDOC_MEMBERS = NO + +# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all +# undocumented classes that are normally visible in the class hierarchy. If set +# to NO, these classes will be included in the various overviews. This option +# will also hide undocumented C++ concepts if enabled. This option has no effect +# if EXTRACT_ALL is enabled. +# The default value is: NO. + +HIDE_UNDOC_CLASSES = NO + +# If the HIDE_UNDOC_NAMESPACES tag is set to YES, Doxygen will hide all +# undocumented namespaces that are normally visible in the namespace hierarchy. +# If set to NO, these namespaces will be included in the various overviews. This +# option has no effect if EXTRACT_ALL is enabled. +# The default value is: YES. + +HIDE_UNDOC_NAMESPACES = YES + +# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all friend +# declarations. If set to NO, these declarations will be included in the +# documentation. +# The default value is: NO. + +HIDE_FRIEND_COMPOUNDS = NO + +# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any +# documentation blocks found inside the body of a function. If set to NO, these +# blocks will be appended to the function's detailed documentation block. +# The default value is: NO. + +HIDE_IN_BODY_DOCS = NO + +# The INTERNAL_DOCS tag determines if documentation that is typed after a +# \internal command is included. If the tag is set to NO then the documentation +# will be excluded. Set it to YES to include the internal documentation. +# The default value is: NO. + +INTERNAL_DOCS = NO + +# With the correct setting of option CASE_SENSE_NAMES Doxygen will better be +# able to match the capabilities of the underlying filesystem. In case the +# filesystem is case sensitive (i.e. it supports files in the same directory +# whose names only differ in casing), the option must be set to YES to properly +# deal with such files in case they appear in the input. For filesystems that +# are not case sensitive the option should be set to NO to properly deal with +# output files written for symbols that only differ in casing, such as for two +# classes, one named CLASS and the other named Class, and to also support +# references to files without having to specify the exact matching casing. On +# Windows (including Cygwin) and macOS, users should typically set this option +# to NO, whereas on Linux or other Unix flavors it should typically be set to +# YES. +# Possible values are: SYSTEM, NO and YES. +# The default value is: SYSTEM. + +CASE_SENSE_NAMES = YES + +# If the HIDE_SCOPE_NAMES tag is set to NO then Doxygen will show members with +# their full class and namespace scopes in the documentation. If set to YES, the +# scope will be hidden. +# The default value is: NO. + +HIDE_SCOPE_NAMES = NO + +# If the HIDE_COMPOUND_REFERENCE tag is set to NO (default) then Doxygen will +# append additional text to a page's title, such as Class Reference. If set to +# YES the compound reference will be hidden. +# The default value is: NO. + +HIDE_COMPOUND_REFERENCE= NO + +# If the SHOW_HEADERFILE tag is set to YES then the documentation for a class +# will show which file needs to be included to use the class. +# The default value is: YES. + +SHOW_HEADERFILE = YES + +# If the SHOW_INCLUDE_FILES tag is set to YES then Doxygen will put a list of +# the files that are included by a file in the documentation of that file. +# The default value is: YES. + +SHOW_INCLUDE_FILES = YES + +# If the SHOW_GROUPED_MEMB_INC tag is set to YES then Doxygen will add for each +# grouped member an include statement to the documentation, telling the reader +# which file to include in order to use the member. +# The default value is: NO. + +SHOW_GROUPED_MEMB_INC = NO + +# If the FORCE_LOCAL_INCLUDES tag is set to YES then Doxygen will list include +# files with double quotes in the documentation rather than with sharp brackets. +# The default value is: NO. + +FORCE_LOCAL_INCLUDES = NO + +# If the INLINE_INFO tag is set to YES then a tag [inline] is inserted in the +# documentation for inline members. +# The default value is: YES. + +INLINE_INFO = YES + +# If the SORT_MEMBER_DOCS tag is set to YES then Doxygen will sort the +# (detailed) documentation of file and class members alphabetically by member +# name. If set to NO, the members will appear in declaration order. +# The default value is: YES. + +SORT_MEMBER_DOCS = YES + +# If the SORT_BRIEF_DOCS tag is set to YES then Doxygen will sort the brief +# descriptions of file, namespace and class members alphabetically by member +# name. If set to NO, the members will appear in declaration order. Note that +# this will also influence the order of the classes in the class list. +# The default value is: NO. + +SORT_BRIEF_DOCS = YES + +# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then Doxygen will sort the +# (brief and detailed) documentation of class members so that constructors and +# destructors are listed first. If set to NO the constructors will appear in the +# respective orders defined by SORT_BRIEF_DOCS and SORT_MEMBER_DOCS. +# Note: If SORT_BRIEF_DOCS is set to NO this option is ignored for sorting brief +# member documentation. +# Note: If SORT_MEMBER_DOCS is set to NO this option is ignored for sorting +# detailed member documentation. +# The default value is: NO. + +SORT_MEMBERS_CTORS_1ST = NO + +# If the SORT_GROUP_NAMES tag is set to YES then Doxygen will sort the hierarchy +# of group names into alphabetical order. If set to NO the group names will +# appear in their defined order. +# The default value is: NO. + +SORT_GROUP_NAMES = YES + +# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be sorted by +# fully-qualified names, including namespaces. If set to NO, the class list will +# be sorted only by class name, not including the namespace part. +# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. +# Note: This option applies only to the class list, not to the alphabetical +# list. +# The default value is: NO. + +SORT_BY_SCOPE_NAME = NO + +# If the STRICT_PROTO_MATCHING option is enabled and Doxygen fails to do proper +# type resolution of all parameters of a function it will reject a match between +# the prototype and the implementation of a member function even if there is +# only one candidate or it is obvious which candidate to choose by doing a +# simple string match. By disabling STRICT_PROTO_MATCHING Doxygen will still +# accept a match between prototype and implementation in such cases. +# The default value is: NO. + +STRICT_PROTO_MATCHING = NO + +# The GENERATE_TODOLIST tag can be used to enable (YES) or disable (NO) the todo +# list. This list is created by putting \todo commands in the documentation. +# The default value is: YES. + +GENERATE_TODOLIST = YES + +# The GENERATE_TESTLIST tag can be used to enable (YES) or disable (NO) the test +# list. This list is created by putting \test commands in the documentation. +# The default value is: YES. + +GENERATE_TESTLIST = YES + +# The GENERATE_BUGLIST tag can be used to enable (YES) or disable (NO) the bug +# list. This list is created by putting \bug commands in the documentation. +# The default value is: YES. + +GENERATE_BUGLIST = YES + +# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or disable (NO) +# the deprecated list. This list is created by putting \deprecated commands in +# the documentation. +# The default value is: YES. + +GENERATE_DEPRECATEDLIST= YES + +# The ENABLED_SECTIONS tag can be used to enable conditional documentation +# sections, marked by \if ... \endif and \cond +# ... \endcond blocks. + +ENABLED_SECTIONS = + +# The MAX_INITIALIZER_LINES tag determines the maximum number of lines that the +# initial value of a variable or macro / define can have for it to appear in the +# documentation. If the initializer consists of more lines than specified here +# it will be hidden. Use a value of 0 to hide initializers completely. The +# appearance of the value of individual variables and macros / defines can be +# controlled using \showinitializer or \hideinitializer command in the +# documentation regardless of this setting. +# Minimum value: 0, maximum value: 10000, default value: 30. + +MAX_INITIALIZER_LINES = 30 + +# Set the SHOW_USED_FILES tag to NO to disable the list of files generated at +# the bottom of the documentation of classes and structs. If set to YES, the +# list will mention the files that were used to generate the documentation. +# The default value is: YES. + +SHOW_USED_FILES = YES + +# Set the SHOW_FILES tag to NO to disable the generation of the Files page. This +# will remove the Files entry from the Quick Index and from the Folder Tree View +# (if specified). +# The default value is: YES. + +SHOW_FILES = NO + +# Set the SHOW_NAMESPACES tag to NO to disable the generation of the Namespaces +# page. This will remove the Namespaces entry from the Quick Index and from the +# Folder Tree View (if specified). +# The default value is: YES. + +SHOW_NAMESPACES = YES + +# The FILE_VERSION_FILTER tag can be used to specify a program or script that +# Doxygen should invoke to get the current version for each file (typically from +# the version control system). Doxygen will invoke the program by executing (via +# popen()) the command command input-file, where command is the value of the +# FILE_VERSION_FILTER tag, and input-file is the name of an input file provided +# by Doxygen. Whatever the program writes to standard output is used as the file +# version. For an example see the documentation. + +FILE_VERSION_FILTER = + +# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed +# by Doxygen. The layout file controls the global structure of the generated +# output files in an output format independent way. To create the layout file +# that represents Doxygen's defaults, run Doxygen with the -l option. You can +# optionally specify a file name after the option, if omitted DoxygenLayout.xml +# will be used as the name of the layout file. See also section "Changing the +# layout of pages" for information. +# +# Note that if you run Doxygen from a directory containing a file called +# DoxygenLayout.xml, Doxygen will parse it automatically even if the LAYOUT_FILE +# tag is left empty. + +LAYOUT_FILE = + +# The CITE_BIB_FILES tag can be used to specify one or more bib files containing +# the reference definitions. This must be a list of .bib files. The .bib +# extension is automatically appended if omitted. This requires the bibtex tool +# to be installed. See also https://en.wikipedia.org/wiki/BibTeX for more info. +# For LaTeX the style of the bibliography can be controlled using +# LATEX_BIB_STYLE. To use this feature you need bibtex and perl available in the +# search path. See also \cite for info how to create references. + +CITE_BIB_FILES = + +# The EXTERNAL_TOOL_PATH tag can be used to extend the search path (PATH +# environment variable) so that external tools such as latex and gs can be +# found. +# Note: Directories specified with EXTERNAL_TOOL_PATH are added in front of the +# path already specified by the PATH variable, and are added in the order +# specified. +# Note: This option is particularly useful for macOS version 14 (Sonoma) and +# higher, when running Doxygen from Doxywizard, because in this case any user- +# defined changes to the PATH are ignored. A typical example on macOS is to set +# EXTERNAL_TOOL_PATH = /Library/TeX/texbin /usr/local/bin +# together with the standard path, the full search path used by doxygen when +# launching external tools will then become +# PATH=/Library/TeX/texbin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin + +EXTERNAL_TOOL_PATH = + +#--------------------------------------------------------------------------- +# Configuration options related to warning and progress messages +#--------------------------------------------------------------------------- + +# The QUIET tag can be used to turn on/off the messages that are generated to +# standard output by Doxygen. If QUIET is set to YES this implies that the +# messages are off. +# The default value is: NO. + +QUIET = YES + +# The WARNINGS tag can be used to turn on/off the warning messages that are +# generated to standard error (stderr) by Doxygen. If WARNINGS is set to YES +# this implies that the warnings are on. +# +# Tip: Turn warnings on while writing the documentation. +# The default value is: YES. + +WARNINGS = YES + +# If the WARN_IF_UNDOCUMENTED tag is set to YES then Doxygen will generate +# warnings for undocumented members. If EXTRACT_ALL is set to YES then this flag +# will automatically be disabled. +# The default value is: YES. + +WARN_IF_UNDOCUMENTED = YES + +# If the WARN_IF_DOC_ERROR tag is set to YES, Doxygen will generate warnings for +# potential errors in the documentation, such as documenting some parameters in +# a documented function twice, or documenting parameters that don't exist or +# using markup commands wrongly. +# The default value is: YES. + +WARN_IF_DOC_ERROR = YES + +# If WARN_IF_INCOMPLETE_DOC is set to YES, Doxygen will warn about incomplete +# function parameter documentation. If set to NO, Doxygen will accept that some +# parameters have no documentation without warning. +# The default value is: YES. + +WARN_IF_INCOMPLETE_DOC = YES + +# This WARN_NO_PARAMDOC option can be enabled to get warnings for functions that +# are documented, but have no documentation for their parameters or return +# value. If set to NO, Doxygen will only warn about wrong parameter +# documentation, but not about the absence of documentation. If EXTRACT_ALL is +# set to YES then this flag will automatically be disabled. See also +# WARN_IF_INCOMPLETE_DOC +# The default value is: NO. + +WARN_NO_PARAMDOC = NO + +# If WARN_IF_UNDOC_ENUM_VAL option is set to YES, Doxygen will warn about +# undocumented enumeration values. If set to NO, Doxygen will accept +# undocumented enumeration values. If EXTRACT_ALL is set to YES then this flag +# will automatically be disabled. +# The default value is: NO. + +WARN_IF_UNDOC_ENUM_VAL = NO + +# If WARN_LAYOUT_FILE option is set to YES, Doxygen will warn about issues found +# while parsing the user defined layout file, such as missing or wrong elements. +# See also LAYOUT_FILE for details. If set to NO, problems with the layout file +# will be suppressed. +# The default value is: YES. + +WARN_LAYOUT_FILE = YES + +# If the WARN_AS_ERROR tag is set to YES then Doxygen will immediately stop when +# a warning is encountered. If the WARN_AS_ERROR tag is set to FAIL_ON_WARNINGS +# then Doxygen will continue running as if WARN_AS_ERROR tag is set to NO, but +# at the end of the Doxygen process Doxygen will return with a non-zero status. +# If the WARN_AS_ERROR tag is set to FAIL_ON_WARNINGS_PRINT then Doxygen behaves +# like FAIL_ON_WARNINGS but in case no WARN_LOGFILE is defined Doxygen will not +# write the warning messages in between other messages but write them at the end +# of a run, in case a WARN_LOGFILE is defined the warning messages will be +# besides being in the defined file also be shown at the end of a run, unless +# the WARN_LOGFILE is defined as - i.e. standard output (stdout) in that case +# the behavior will remain as with the setting FAIL_ON_WARNINGS. +# Possible values are: NO, YES, FAIL_ON_WARNINGS and FAIL_ON_WARNINGS_PRINT. +# The default value is: NO. + +WARN_AS_ERROR = NO + +# The WARN_FORMAT tag determines the format of the warning messages that Doxygen +# can produce. The string should contain the $file, $line, and $text tags, which +# will be replaced by the file and line number from which the warning originated +# and the warning text. Optionally the format may contain $version, which will +# be replaced by the version of the file (if it could be obtained via +# FILE_VERSION_FILTER) +# See also: WARN_LINE_FORMAT +# The default value is: $file:$line: $text. + +WARN_FORMAT = "$file:$line: $text" + +# In the $text part of the WARN_FORMAT command it is possible that a reference +# to a more specific place is given. To make it easier to jump to this place +# (outside of Doxygen) the user can define a custom "cut" / "paste" string. +# Example: +# WARN_LINE_FORMAT = "'vi $file +$line'" +# See also: WARN_FORMAT +# The default value is: at line $line of file $file. + +WARN_LINE_FORMAT = "at line $line of file $file" + +# The WARN_LOGFILE tag can be used to specify a file to which warning and error +# messages should be written. If left blank the output is written to standard +# error (stderr). In case the file specified cannot be opened for writing the +# warning and error messages are written to standard error. When as file - is +# specified the warning and error messages are written to standard output +# (stdout). + +WARN_LOGFILE = + +#--------------------------------------------------------------------------- +# Configuration options related to the input files +#--------------------------------------------------------------------------- + +# The INPUT tag is used to specify the files and/or directories that contain +# documented source files. You may enter file names like myfile.cpp or +# directories like /usr/src/myproject. Separate the files or directories with +# spaces. See also FILE_PATTERNS and EXTENSION_MAPPING +# Note: If this tag is empty the current directory is searched. + +###################################################### + +INPUT = deltachat.h + +# This tag can be used to specify the character encoding of the source files +# that Doxygen parses. Internally Doxygen uses the UTF-8 encoding. Doxygen uses +# libiconv (or the iconv built into libc) for the transcoding. See the libiconv +# documentation (see: +# https://www.gnu.org/software/libiconv/) for the list of possible encodings. +# See also: INPUT_FILE_ENCODING +# The default value is: UTF-8. + +###################################################### + +INPUT_ENCODING = UTF-8 + +# This tag can be used to specify the character encoding of the source files +# that Doxygen parses. The INPUT_FILE_ENCODING tag can be used to specify +# character encoding on a per file pattern basis. Doxygen will compare the file +# name with each pattern and apply the encoding instead of the default +# INPUT_ENCODING if there is a match. The character encodings are a list of the +# form: pattern=encoding (like *.php=ISO-8859-1). +# See also: INPUT_ENCODING for further information on supported encodings. + +INPUT_FILE_ENCODING = + +# If the value of the INPUT tag contains directories, you can use the +# FILE_PATTERNS tag to specify one or more wildcard patterns (like *.cpp and +# *.h) to filter out the source-files in the directories. +# +# Note that for custom extensions or not directly supported extensions you also +# need to set EXTENSION_MAPPING for the extension otherwise the files are not +# read by Doxygen. +# +# Note the list of default checked file patterns might differ from the list of +# default file extension mappings. +# +# If left blank the following patterns are tested:*.c, *.cc, *.cxx, *.cxxm, +# *.cpp, *.cppm, *.ccm, *.c++, *.c++m, *.java, *.ii, *.ixx, *.ipp, *.i++, *.inl, +# *.idl, *.ddl, *.odl, *.h, *.hh, *.hxx, *.hpp, *.h++, *.ixx, *.l, *.cs, *.d, +# *.php, *.php4, *.php5, *.phtml, *.inc, *.m, *.markdown, *.md, *.mm, *.dox (to +# be provided as Doxygen C comment), *.py, *.pyw, *.f90, *.f95, *.f03, *.f08, +# *.f18, *.f, *.for, *.vhd, *.vhdl, *.ucf, *.qsf and *.ice. + +FILE_PATTERNS = + +# The RECURSIVE tag can be used to specify whether or not subdirectories should +# be searched for input files as well. +# The default value is: NO. + +RECURSIVE = NO + +# The EXCLUDE tag can be used to specify files and/or directories that should be +# excluded from the INPUT source files. This way you can easily exclude a +# subdirectory from a directory tree whose root is specified with the INPUT tag. +# +# Note that relative paths are relative to the directory from which Doxygen is +# run. + +EXCLUDE = + +# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or +# directories that are symbolic links (a Unix file system feature) are excluded +# from the input. +# The default value is: NO. + +EXCLUDE_SYMLINKS = NO + +# If the value of the INPUT tag contains directories, you can use the +# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude +# certain files from those directories. +# +# Note that the wildcards are matched against the file with absolute path, so to +# exclude all test directories for example use the pattern */test/* + +EXCLUDE_PATTERNS = + +# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names +# (namespaces, classes, functions, etc.) that should be excluded from the +# output. The symbol name can be a fully qualified name, a word, or if the +# wildcard * is used, a substring. Examples: ANamespace, AClass, +# ANamespace::AClass, ANamespace::*Test + +###################################################### + +EXCLUDE_SYMBOLS = dc_aheader_t \ + dc_apeerstate_t \ + dc_e2ee_helper_t \ + dc_imap_t \ + dc_job*_t \ + dc_key_t \ + dc_loginparam_t \ + dc_mime*_t \ + dc_saxparser_t \ + dc_simplify_t \ + dc_smtp_t \ + dc_sqlite3_t \ + dc_strbuilder_t \ + dc_param_t \ + dc_hash_t \ + dc_hashelem_t \ + _dc_* \ + jsmn* + +# The EXAMPLE_PATH tag can be used to specify one or more files or directories +# that contain example code fragments that are included (see the \include +# command). + +###################################################### + +EXAMPLE_PATH = + +# If the value of the EXAMPLE_PATH tag contains directories, you can use the +# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp and +# *.h) to filter out the source-files in the directories. If left blank all +# files are included. + +EXAMPLE_PATTERNS = + +# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be +# searched for input files to be used with the \include or \dontinclude commands +# irrespective of the value of the RECURSIVE tag. +# The default value is: NO. + +EXAMPLE_RECURSIVE = NO + +# The IMAGE_PATH tag can be used to specify one or more files or directories +# that contain images that are to be included in the documentation (see the +# \image command). + +IMAGE_PATH = + +# The INPUT_FILTER tag can be used to specify a program that Doxygen should +# invoke to filter for each input file. Doxygen will invoke the filter program +# by executing (via popen()) the command: +# +# +# +# where is the value of the INPUT_FILTER tag, and is the +# name of an input file. Doxygen will then use the output that the filter +# program writes to standard output. If FILTER_PATTERNS is specified, this tag +# will be ignored. +# +# Note that the filter must not add or remove lines; it is applied before the +# code is scanned, but not when the output code is generated. If lines are added +# or removed, the anchors will not be placed correctly. +# +# Note that Doxygen will use the data processed and written to standard output +# for further processing, therefore nothing else, like debug statements or used +# commands (so in case of a Windows batch file always use @echo OFF), should be +# written to standard output. +# +# Note that for custom extensions or not directly supported extensions you also +# need to set EXTENSION_MAPPING for the extension otherwise the files are not +# properly processed by Doxygen. + +INPUT_FILTER = + +# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern +# basis. Doxygen will compare the file name with each pattern and apply the +# filter if there is a match. The filters are a list of the form: pattern=filter +# (like *.cpp=my_cpp_filter). See INPUT_FILTER for further information on how +# filters are used. If the FILTER_PATTERNS tag is empty or if none of the +# patterns match the file name, INPUT_FILTER is applied. +# +# Note that for custom extensions or not directly supported extensions you also +# need to set EXTENSION_MAPPING for the extension otherwise the files are not +# properly processed by Doxygen. + +FILTER_PATTERNS = + +# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using +# INPUT_FILTER) will also be used to filter the input files that are used for +# producing the source files to browse (i.e. when SOURCE_BROWSER is set to YES). +# The default value is: NO. + +FILTER_SOURCE_FILES = NO + +# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file +# pattern. A pattern will override the setting for FILTER_PATTERN (if any) and +# it is also possible to disable source filtering for a specific pattern using +# *.ext= (so without naming a filter). +# This tag requires that the tag FILTER_SOURCE_FILES is set to YES. + +FILTER_SOURCE_PATTERNS = + +# If the USE_MDFILE_AS_MAINPAGE tag refers to the name of a markdown file that +# is part of the input, its contents will be placed on the main page +# (index.html). This can be useful if you have a project on for instance GitHub +# and want to reuse the introduction page also for the Doxygen output. + +USE_MDFILE_AS_MAINPAGE = + +# If the IMPLICIT_DIR_DOCS tag is set to YES, any README.md file found in sub- +# directories of the project's root, is used as the documentation for that sub- +# directory, except when the README.md starts with a \dir, \page or \mainpage +# command. If set to NO, the README.md file needs to start with an explicit \dir +# command in order to be used as directory documentation. +# The default value is: YES. + +IMPLICIT_DIR_DOCS = YES + +# The Fortran standard specifies that for fixed formatted Fortran code all +# characters from position 72 are to be considered as comment. A common +# extension is to allow longer lines before the automatic comment starts. The +# setting FORTRAN_COMMENT_AFTER will also make it possible that longer lines can +# be processed before the automatic comment starts. +# Minimum value: 7, maximum value: 10000, default value: 72. + +FORTRAN_COMMENT_AFTER = 72 + +#--------------------------------------------------------------------------- +# Configuration options related to source browsing +#--------------------------------------------------------------------------- + +# If the SOURCE_BROWSER tag is set to YES then a list of source files will be +# generated. Documented entities will be cross-referenced with these sources. +# +# Note: To get rid of all source code in the generated output, make sure that +# also VERBATIM_HEADERS is set to NO. +# The default value is: NO. + +###################################################### + +SOURCE_BROWSER = NO + +# Setting the INLINE_SOURCES tag to YES will include the body of functions, +# multi-line macros, enums or list initialized variables directly into the +# documentation. +# The default value is: NO. + +###################################################### + +INLINE_SOURCES = NO + +# Setting the STRIP_CODE_COMMENTS tag to YES will instruct Doxygen to hide any +# special comment blocks from generated source code fragments. Normal C, C++ and +# Fortran comments will always remain visible. +# The default value is: YES. + +STRIP_CODE_COMMENTS = YES + +# If the REFERENCED_BY_RELATION tag is set to YES then for each documented +# entity all documented functions referencing it will be listed. +# The default value is: NO. + +REFERENCED_BY_RELATION = NO + +# If the REFERENCES_RELATION tag is set to YES then for each documented function +# all documented entities called/used by that function will be listed. +# The default value is: NO. + +REFERENCES_RELATION = NO + +# If the REFERENCES_LINK_SOURCE tag is set to YES and SOURCE_BROWSER tag is set +# to YES then the hyperlinks from functions in REFERENCES_RELATION and +# REFERENCED_BY_RELATION lists will link to the source code. Otherwise they will +# link to the documentation. +# The default value is: YES. + +REFERENCES_LINK_SOURCE = YES + +# If SOURCE_TOOLTIPS is enabled (the default) then hovering a hyperlink in the +# source code will show a tooltip with additional information such as prototype, +# brief description and links to the definition and documentation. Since this +# will make the HTML file larger and loading of large files a bit slower, you +# can opt to disable this feature. +# The default value is: YES. +# This tag requires that the tag SOURCE_BROWSER is set to YES. + +SOURCE_TOOLTIPS = YES + +# If the USE_HTAGS tag is set to YES then the references to source code will +# point to the HTML generated by the htags(1) tool instead of Doxygen built-in +# source browser. The htags tool is part of GNU's global source tagging system +# (see https://www.gnu.org/software/global/global.html). You will need version +# 4.8.6 or higher. +# +# To use it do the following: +# - Install the latest version of global +# - Enable SOURCE_BROWSER and USE_HTAGS in the configuration file +# - Make sure the INPUT points to the root of the source tree +# - Run doxygen as normal +# +# Doxygen will invoke htags (and that will in turn invoke gtags), so these +# tools must be available from the command line (i.e. in the search path). +# +# The result: instead of the source browser generated by Doxygen, the links to +# source code will now point to the output of htags. +# The default value is: NO. +# This tag requires that the tag SOURCE_BROWSER is set to YES. + +USE_HTAGS = NO + +# If the VERBATIM_HEADERS tag is set the YES then Doxygen will generate a +# verbatim copy of the header file for each class for which an include is +# specified. Set to NO to disable this. +# See also: Section \class. +# The default value is: YES. + +VERBATIM_HEADERS = YES + +# If the CLANG_ASSISTED_PARSING tag is set to YES then Doxygen will use the +# clang parser (see: +# http://clang.llvm.org/) for more accurate parsing at the cost of reduced +# performance. This can be particularly helpful with template rich C++ code for +# which Doxygen's built-in parser lacks the necessary type information. +# Note: The availability of this option depends on whether or not Doxygen was +# generated with the -Duse_libclang=ON option for CMake. +# The default value is: NO. + +CLANG_ASSISTED_PARSING = NO + +# If the CLANG_ASSISTED_PARSING tag is set to YES and the CLANG_ADD_INC_PATHS +# tag is set to YES then Doxygen will add the directory of each input to the +# include path. +# The default value is: YES. +# This tag requires that the tag CLANG_ASSISTED_PARSING is set to YES. + +CLANG_ADD_INC_PATHS = YES + +# If clang assisted parsing is enabled you can provide the compiler with command +# line options that you would normally use when invoking the compiler. Note that +# the include paths will already be set by Doxygen for the files and directories +# specified with INPUT and INCLUDE_PATH. +# This tag requires that the tag CLANG_ASSISTED_PARSING is set to YES. + +CLANG_OPTIONS = + +# If clang assisted parsing is enabled you can provide the clang parser with the +# path to the directory containing a file called compile_commands.json. This +# file is the compilation database (see: +# http://clang.llvm.org/docs/HowToSetupToolingForLLVM.html) containing the +# options used when the source files were built. This is equivalent to +# specifying the -p option to a clang tool, such as clang-check. These options +# will then be passed to the parser. Any options specified with CLANG_OPTIONS +# will be added as well. +# Note: The availability of this option depends on whether or not Doxygen was +# generated with the -Duse_libclang=ON option for CMake. + +CLANG_DATABASE_PATH = + +#--------------------------------------------------------------------------- +# Configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- + +# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index of all +# compounds will be generated. Enable this if the project contains a lot of +# classes, structs, unions or interfaces. +# The default value is: YES. + +###################################################### + +ALPHABETICAL_INDEX = NO + +# The IGNORE_PREFIX tag can be used to specify a prefix (or a list of prefixes) +# that should be ignored while generating the index headers. The IGNORE_PREFIX +# tag works for classes, function and member names. The entity will be placed in +# the alphabetical list under the first letter of the entity name that remains +# after removing the prefix. +# This tag requires that the tag ALPHABETICAL_INDEX is set to YES. + +IGNORE_PREFIX = + +#--------------------------------------------------------------------------- +# Configuration options related to the HTML output +#--------------------------------------------------------------------------- + +# If the GENERATE_HTML tag is set to YES, Doxygen will generate HTML output +# The default value is: YES. + +GENERATE_HTML = YES + +# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. If a +# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of +# it. +# The default directory is: html. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_OUTPUT = html + +# The HTML_FILE_EXTENSION tag can be used to specify the file extension for each +# generated HTML page (for example: .htm, .php, .asp). +# The default value is: .html. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_FILE_EXTENSION = .html + +# The HTML_HEADER tag can be used to specify a user-defined HTML header file for +# each generated HTML page. If the tag is left blank Doxygen will generate a +# standard header. +# +# To get valid HTML the header file that includes any scripts and style sheets +# that Doxygen needs, which is dependent on the configuration options used (e.g. +# the setting GENERATE_TREEVIEW). It is highly recommended to start with a +# default header using +# doxygen -w html new_header.html new_footer.html new_stylesheet.css +# YourConfigFile +# and then modify the file new_header.html. See also section "Doxygen usage" +# for information on how to generate the default header that Doxygen normally +# uses. +# Note: The header is subject to change so you typically have to regenerate the +# default header when upgrading to a newer version of Doxygen. For a description +# of the possible markers and block names see the documentation. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_HEADER = + +# The HTML_FOOTER tag can be used to specify a user-defined HTML footer for each +# generated HTML page. If the tag is left blank Doxygen will generate a standard +# footer. See HTML_HEADER for more information on how to generate a default +# footer and what special commands can be used inside the footer. See also +# section "Doxygen usage" for information on how to generate the default footer +# that Doxygen normally uses. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_FOOTER = + +# The HTML_STYLESHEET tag can be used to specify a user-defined cascading style +# sheet that is used by each HTML page. It can be used to fine-tune the look of +# the HTML output. If left blank Doxygen will generate a default style sheet. +# See also section "Doxygen usage" for information on how to generate the style +# sheet that Doxygen normally uses. +# Note: It is recommended to use HTML_EXTRA_STYLESHEET instead of this tag, as +# it is more robust and this tag (HTML_STYLESHEET) will in the future become +# obsolete. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_STYLESHEET = + +# The HTML_EXTRA_STYLESHEET tag can be used to specify additional user-defined +# cascading style sheets that are included after the standard style sheets +# created by Doxygen. Using this option one can overrule certain style aspects. +# This is preferred over using HTML_STYLESHEET since it does not replace the +# standard style sheet and is therefore more robust against future updates. +# Doxygen will copy the style sheet files to the output directory. +# Note: The order of the extra style sheet files is of importance (e.g. the last +# style sheet in the list overrules the setting of the previous ones in the +# list). +# Note: Since the styling of scrollbars can currently not be overruled in +# Webkit/Chromium, the styling will be left out of the default doxygen.css if +# one or more extra stylesheets have been specified. So if scrollbar +# customization is desired it has to be added explicitly. For an example see the +# documentation. +# This tag requires that the tag GENERATE_HTML is set to YES. + +###################################################### + +HTML_EXTRA_STYLESHEET = Doxyfile.css + +# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or +# other source files which should be copied to the HTML output directory. Note +# that these files will be copied to the base HTML output directory. Use the +# $relpath^ marker in the HTML_HEADER and/or HTML_FOOTER files to load these +# files. In the HTML_STYLESHEET file, use the file name only. Also note that the +# files will be copied as-is; there are no commands or markers available. +# This tag requires that the tag GENERATE_HTML is set to YES. + +###################################################### + +HTML_EXTRA_FILES = + +# The HTML_COLORSTYLE tag can be used to specify if the generated HTML output +# should be rendered with a dark or light theme. +# Possible values are: LIGHT always generates light mode output, DARK always +# generates dark mode output, AUTO_LIGHT automatically sets the mode according +# to the user preference, uses light mode if no preference is set (the default), +# AUTO_DARK automatically sets the mode according to the user preference, uses +# dark mode if no preference is set and TOGGLE allows a user to switch between +# light and dark mode via a button. +# The default value is: AUTO_LIGHT. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_COLORSTYLE = AUTO_LIGHT + +# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen +# will adjust the colors in the style sheet and background images according to +# this color. Hue is specified as an angle on a color-wheel, see +# https://en.wikipedia.org/wiki/Hue for more information. For instance the value +# 0 represents red, 60 is yellow, 120 is green, 180 is cyan, 240 is blue, 300 +# purple, and 360 is red again. +# Minimum value: 0, maximum value: 359, default value: 220. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_COLORSTYLE_HUE = 220 + +# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of the colors +# in the HTML output. For a value of 0 the output will use gray-scales only. A +# value of 255 will produce the most vivid colors. +# Minimum value: 0, maximum value: 255, default value: 100. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_COLORSTYLE_SAT = 100 + +# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to the +# luminance component of the colors in the HTML output. Values below 100 +# gradually make the output lighter, whereas values above 100 make the output +# darker. The value divided by 100 is the actual gamma applied, so 80 represents +# a gamma of 0.8, The value 220 represents a gamma of 2.2, and 100 does not +# change the gamma. +# Minimum value: 40, maximum value: 240, default value: 80. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_COLORSTYLE_GAMMA = 80 + +# If the HTML_DYNAMIC_MENUS tag is set to YES then the generated HTML +# documentation will contain a main index with vertical navigation menus that +# are dynamically created via JavaScript. If disabled, the navigation index will +# consists of multiple levels of tabs that are statically embedded in every HTML +# page. Disable this option to support browsers that do not have JavaScript, +# like the Qt help browser. +# The default value is: YES. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_DYNAMIC_MENUS = YES + +# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML +# documentation will contain sections that can be hidden and shown after the +# page has loaded. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_DYNAMIC_SECTIONS = NO + +# If the HTML_CODE_FOLDING tag is set to YES then classes and functions can be +# dynamically folded and expanded in the generated HTML source code. +# The default value is: YES. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_CODE_FOLDING = YES + +# If the HTML_COPY_CLIPBOARD tag is set to YES then Doxygen will show an icon in +# the top right corner of code and text fragments that allows the user to copy +# its content to the clipboard. Note this only works if supported by the browser +# and the web page is served via a secure context (see: +# https://www.w3.org/TR/secure-contexts/), i.e. using the https: or file: +# protocol. +# The default value is: YES. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_COPY_CLIPBOARD = YES + +# Doxygen stores a couple of settings persistently in the browser (via e.g. +# cookies). By default these settings apply to all HTML pages generated by +# Doxygen across all projects. The HTML_PROJECT_COOKIE tag can be used to store +# the settings under a project specific key, such that the user preferences will +# be stored separately. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_PROJECT_COOKIE = + +# With HTML_INDEX_NUM_ENTRIES one can control the preferred number of entries +# shown in the various tree structured indices initially; the user can expand +# and collapse entries dynamically later on. Doxygen will expand the tree to +# such a level that at most the specified number of entries are visible (unless +# a fully collapsed tree already exceeds this amount). So setting the number of +# entries 1 will produce a full collapsed tree by default. 0 is a special value +# representing an infinite number of entries and will result in a full expanded +# tree by default. +# Minimum value: 0, maximum value: 9999, default value: 100. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_INDEX_NUM_ENTRIES = 100 + +# If the GENERATE_DOCSET tag is set to YES, additional index files will be +# generated that can be used as input for Apple's Xcode 3 integrated development +# environment (see: +# https://developer.apple.com/xcode/), introduced with OSX 10.5 (Leopard). To +# create a documentation set, Doxygen will generate a Makefile in the HTML +# output directory. Running make will produce the docset in that directory and +# running make install will install the docset in +# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find it at +# startup. See https://developer.apple.com/library/archive/featuredarticles/Doxy +# genXcode/_index.html for more information. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_DOCSET = NO + +# This tag determines the name of the docset feed. A documentation feed provides +# an umbrella under which multiple documentation sets from a single provider +# (such as a company or product suite) can be grouped. +# The default value is: Doxygen generated docs. +# This tag requires that the tag GENERATE_DOCSET is set to YES. + +DOCSET_FEEDNAME = "Doxygen generated docs" + +# This tag determines the URL of the docset feed. A documentation feed provides +# an umbrella under which multiple documentation sets from a single provider +# (such as a company or product suite) can be grouped. +# This tag requires that the tag GENERATE_DOCSET is set to YES. + +DOCSET_FEEDURL = + +# This tag specifies a string that should uniquely identify the documentation +# set bundle. This should be a reverse domain-name style string, e.g. +# com.mycompany.MyDocSet. Doxygen will append .docset to the name. +# The default value is: org.doxygen.Project. +# This tag requires that the tag GENERATE_DOCSET is set to YES. + +DOCSET_BUNDLE_ID = org.doxygen.Project + +# The DOCSET_PUBLISHER_ID tag specifies a string that should uniquely identify +# the documentation publisher. This should be a reverse domain-name style +# string, e.g. com.mycompany.MyDocSet.documentation. +# The default value is: org.doxygen.Publisher. +# This tag requires that the tag GENERATE_DOCSET is set to YES. + +DOCSET_PUBLISHER_ID = org.doxygen.Publisher + +# The DOCSET_PUBLISHER_NAME tag identifies the documentation publisher. +# The default value is: Publisher. +# This tag requires that the tag GENERATE_DOCSET is set to YES. + +DOCSET_PUBLISHER_NAME = Publisher + +# If the GENERATE_HTMLHELP tag is set to YES then Doxygen generates three +# additional HTML index files: index.hhp, index.hhc, and index.hhk. The +# index.hhp is a project file that can be read by Microsoft's HTML Help Workshop +# on Windows. In the beginning of 2021 Microsoft took the original page, with +# a.o. the download links, offline (the HTML help workshop was already many +# years in maintenance mode). You can download the HTML help workshop from the +# web archives at Installation executable (see: +# http://web.archive.org/web/20160201063255/http://download.microsoft.com/downlo +# ad/0/A/9/0A939EF6-E31C-430F-A3DF-DFAE7960D564/htmlhelp.exe). +# +# The HTML Help Workshop contains a compiler that can convert all HTML output +# generated by Doxygen into a single compiled HTML file (.chm). Compiled HTML +# files are now used as the Windows 98 help format, and will replace the old +# Windows help format (.hlp) on all Windows platforms in the future. Compressed +# HTML files also contain an index, a table of contents, and you can search for +# words in the documentation. The HTML workshop also contains a viewer for +# compressed HTML files. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_HTMLHELP = NO + +# The CHM_FILE tag can be used to specify the file name of the resulting .chm +# file. You can add a path in front of the file if the result should not be +# written to the html output directory. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +CHM_FILE = + +# The HHC_LOCATION tag can be used to specify the location (absolute path +# including file name) of the HTML help compiler (hhc.exe). If non-empty, +# Doxygen will try to run the HTML help compiler on the generated index.hhp. +# The file has to be specified with full path. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +HHC_LOCATION = + +# The GENERATE_CHI flag controls if a separate .chi index file is generated +# (YES) or that it should be included in the main .chm file (NO). +# The default value is: NO. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +GENERATE_CHI = NO + +# The CHM_INDEX_ENCODING is used to encode HtmlHelp index (hhk), content (hhc) +# and project file content. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +CHM_INDEX_ENCODING = + +# The BINARY_TOC flag controls whether a binary table of contents is generated +# (YES) or a normal table of contents (NO) in the .chm file. Furthermore it +# enables the Previous and Next buttons. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +BINARY_TOC = NO + +# The TOC_EXPAND flag can be set to YES to add extra items for group members to +# the table of contents of the HTML help documentation and to the tree view. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTMLHELP is set to YES. + +TOC_EXPAND = NO + +# The SITEMAP_URL tag is used to specify the full URL of the place where the +# generated documentation will be placed on the server by the user during the +# deployment of the documentation. The generated sitemap is called sitemap.xml +# and placed on the directory specified by HTML_OUTPUT. In case no SITEMAP_URL +# is specified no sitemap is generated. For information about the sitemap +# protocol see https://www.sitemaps.org +# This tag requires that the tag GENERATE_HTML is set to YES. + +SITEMAP_URL = + +# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and +# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated that +# can be used as input for Qt's qhelpgenerator to generate a Qt Compressed Help +# (.qch) of the generated HTML documentation. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_QHP = NO + +# If the QHG_LOCATION tag is specified, the QCH_FILE tag can be used to specify +# the file name of the resulting .qch file. The path specified is relative to +# the HTML output folder. +# This tag requires that the tag GENERATE_QHP is set to YES. + +QCH_FILE = + +# The QHP_NAMESPACE tag specifies the namespace to use when generating Qt Help +# Project output. For more information please see Qt Help Project / Namespace +# (see: +# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#namespace). +# The default value is: org.doxygen.Project. +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_NAMESPACE = org.doxygen.Project + +# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating Qt +# Help Project output. For more information please see Qt Help Project / Virtual +# Folders (see: +# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#virtual-folders). +# The default value is: doc. +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_VIRTUAL_FOLDER = doc + +# If the QHP_CUST_FILTER_NAME tag is set, it specifies the name of a custom +# filter to add. For more information please see Qt Help Project / Custom +# Filters (see: +# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#custom-filters). +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_CUST_FILTER_NAME = + +# The QHP_CUST_FILTER_ATTRS tag specifies the list of the attributes of the +# custom filter to add. For more information please see Qt Help Project / Custom +# Filters (see: +# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#custom-filters). +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_CUST_FILTER_ATTRS = + +# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this +# project's filter section matches. Qt Help Project / Filter Attributes (see: +# https://doc.qt.io/archives/qt-4.8/qthelpproject.html#filter-attributes). +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHP_SECT_FILTER_ATTRS = + +# The QHG_LOCATION tag can be used to specify the location (absolute path +# including file name) of Qt's qhelpgenerator. If non-empty Doxygen will try to +# run qhelpgenerator on the generated .qhp file. +# This tag requires that the tag GENERATE_QHP is set to YES. + +QHG_LOCATION = + +# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files will be +# generated, together with the HTML files, they form an Eclipse help plugin. To +# install this plugin and make it available under the help contents menu in +# Eclipse, the contents of the directory containing the HTML and XML files needs +# to be copied into the plugins directory of eclipse. The name of the directory +# within the plugins directory should be the same as the ECLIPSE_DOC_ID value. +# After copying Eclipse needs to be restarted before the help appears. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_ECLIPSEHELP = NO + +# A unique identifier for the Eclipse help plugin. When installing the plugin +# the directory name containing the HTML and XML files should also have this +# name. Each documentation set should have its own identifier. +# The default value is: org.doxygen.Project. +# This tag requires that the tag GENERATE_ECLIPSEHELP is set to YES. + +ECLIPSE_DOC_ID = org.doxygen.Project + +# If you want full control over the layout of the generated HTML pages it might +# be necessary to disable the index and replace it with your own. The +# DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) at top +# of each HTML page. A value of NO enables the index and the value YES disables +# it. Since the tabs in the index contain the same information as the navigation +# tree, you can set this option to YES if you also set GENERATE_TREEVIEW to YES. +# The default value is: YES. +# This tag requires that the tag GENERATE_HTML is set to YES. + +DISABLE_INDEX = NO + +# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index +# structure should be generated to display hierarchical information. If the tag +# value is set to YES, a side panel will be generated containing a tree-like +# index structure (just like the one that is generated for HTML Help). For this +# to work a browser that supports JavaScript, DHTML, CSS and frames is required +# (i.e. any modern browser). Windows users are probably better off using the +# HTML help feature. Via custom style sheets (see HTML_EXTRA_STYLESHEET) one can +# further fine tune the look of the index (see "Fine-tuning the output"). As an +# example, the default style sheet generated by Doxygen has an example that +# shows how to put an image at the root of the tree instead of the PROJECT_NAME. +# Since the tree basically has the same information as the tab index, you could +# consider setting DISABLE_INDEX to YES when enabling this option. +# The default value is: YES. +# This tag requires that the tag GENERATE_HTML is set to YES. + +GENERATE_TREEVIEW = NO + +# When both GENERATE_TREEVIEW and DISABLE_INDEX are set to YES, then the +# FULL_SIDEBAR option determines if the side bar is limited to only the treeview +# area (value NO) or if it should extend to the full height of the window (value +# YES). Setting this to YES gives a layout similar to +# https://docs.readthedocs.io with more room for contents, but less room for the +# project logo, title, and description. If either GENERATE_TREEVIEW or +# DISABLE_INDEX is set to NO, this option has no effect. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +FULL_SIDEBAR = NO + +# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values that +# Doxygen will group on one line in the generated HTML documentation. +# +# Note that a value of 0 will completely suppress the enum values from appearing +# in the overview section. +# Minimum value: 0, maximum value: 20, default value: 4. +# This tag requires that the tag GENERATE_HTML is set to YES. + +ENUM_VALUES_PER_LINE = 4 + +# When the SHOW_ENUM_VALUES tag is set doxygen will show the specified +# enumeration values besides the enumeration mnemonics. +# The default value is: NO. + +SHOW_ENUM_VALUES = NO + +# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be used +# to set the initial width (in pixels) of the frame in which the tree is shown. +# Minimum value: 0, maximum value: 1500, default value: 250. +# This tag requires that the tag GENERATE_HTML is set to YES. + +TREEVIEW_WIDTH = 250 + +# If the EXT_LINKS_IN_WINDOW option is set to YES, Doxygen will open links to +# external symbols imported via tag files in a separate window. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +EXT_LINKS_IN_WINDOW = NO + +# If the OBFUSCATE_EMAILS tag is set to YES, Doxygen will obfuscate email +# addresses. +# The default value is: YES. +# This tag requires that the tag GENERATE_HTML is set to YES. + +OBFUSCATE_EMAILS = YES + +# If the HTML_FORMULA_FORMAT option is set to svg, Doxygen will use the pdf2svg +# tool (see https://github.com/dawbarton/pdf2svg) or inkscape (see +# https://inkscape.org) to generate formulas as SVG images instead of PNGs for +# the HTML output. These images will generally look nicer at scaled resolutions. +# Possible values are: png (the default) and svg (looks nicer but requires the +# pdf2svg or inkscape tool). +# The default value is: png. +# This tag requires that the tag GENERATE_HTML is set to YES. + +HTML_FORMULA_FORMAT = png + +# Use this tag to change the font size of LaTeX formulas included as images in +# the HTML documentation. When you change the font size after a successful +# Doxygen run you need to manually remove any form_*.png images from the HTML +# output directory to force them to be regenerated. +# Minimum value: 8, maximum value: 50, default value: 10. +# This tag requires that the tag GENERATE_HTML is set to YES. + +FORMULA_FONTSIZE = 10 + +# The FORMULA_MACROFILE can contain LaTeX \newcommand and \renewcommand commands +# to create new LaTeX commands to be used in formulas as building blocks. See +# the section "Including formulas" for details. + +FORMULA_MACROFILE = + +# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax (see +# https://www.mathjax.org) which uses client side JavaScript for the rendering +# instead of using pre-rendered bitmaps. Use this if you do not have LaTeX +# installed or if you want to formulas look prettier in the HTML output. When +# enabled you may also need to install MathJax separately and configure the path +# to it using the MATHJAX_RELPATH option. +# The default value is: NO. +# This tag requires that the tag GENERATE_HTML is set to YES. + +USE_MATHJAX = NO + +# With MATHJAX_VERSION it is possible to specify the MathJax version to be used. +# Note that the different versions of MathJax have different requirements with +# regards to the different settings, so it is possible that also other MathJax +# settings have to be changed when switching between the different MathJax +# versions. +# Possible values are: MathJax_2 and MathJax_3. +# The default value is: MathJax_2. +# This tag requires that the tag USE_MATHJAX is set to YES. + +MATHJAX_VERSION = MathJax_2 + +# When MathJax is enabled you can set the default output format to be used for +# the MathJax output. For more details about the output format see MathJax +# version 2 (see: +# http://docs.mathjax.org/en/v2.7-latest/output.html) and MathJax version 3 +# (see: +# http://docs.mathjax.org/en/latest/web/components/output.html). +# Possible values are: HTML-CSS (which is slower, but has the best +# compatibility. This is the name for Mathjax version 2, for MathJax version 3 +# this will be translated into chtml), NativeMML (i.e. MathML. Only supported +# for MathJax 2. For MathJax version 3 chtml will be used instead.), chtml (This +# is the name for Mathjax version 3, for MathJax version 2 this will be +# translated into HTML-CSS) and SVG. +# The default value is: HTML-CSS. +# This tag requires that the tag USE_MATHJAX is set to YES. + +MATHJAX_FORMAT = HTML-CSS + +# When MathJax is enabled you need to specify the location relative to the HTML +# output directory using the MATHJAX_RELPATH option. The destination directory +# should contain the MathJax.js script. For instance, if the mathjax directory +# is located at the same level as the HTML output directory, then +# MATHJAX_RELPATH should be ../mathjax. The default value points to the MathJax +# Content Delivery Network so you can quickly see the result without installing +# MathJax. However, it is strongly recommended to install a local copy of +# MathJax from https://www.mathjax.org before deployment. The default value is: +# - in case of MathJax version 2: https://cdn.jsdelivr.net/npm/mathjax@2 +# - in case of MathJax version 3: https://cdn.jsdelivr.net/npm/mathjax@3 +# This tag requires that the tag USE_MATHJAX is set to YES. + +MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest + +# The MATHJAX_EXTENSIONS tag can be used to specify one or more MathJax +# extension names that should be enabled during MathJax rendering. For example +# for MathJax version 2 (see +# https://docs.mathjax.org/en/v2.7-latest/tex.html#tex-and-latex-extensions): +# MATHJAX_EXTENSIONS = TeX/AMSmath TeX/AMSsymbols +# For example for MathJax version 3 (see +# http://docs.mathjax.org/en/latest/input/tex/extensions/index.html): +# MATHJAX_EXTENSIONS = ams +# This tag requires that the tag USE_MATHJAX is set to YES. + +MATHJAX_EXTENSIONS = + +# The MATHJAX_CODEFILE tag can be used to specify a file with JavaScript pieces +# of code that will be used on startup of the MathJax code. See the MathJax site +# (see: +# http://docs.mathjax.org/en/v2.7-latest/output.html) for more details. For an +# example see the documentation. +# This tag requires that the tag USE_MATHJAX is set to YES. + +MATHJAX_CODEFILE = + +# When the SEARCHENGINE tag is enabled Doxygen will generate a search box for +# the HTML output. The underlying search engine uses JavaScript and DHTML and +# should work on any modern browser. Note that when using HTML help +# (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets (GENERATE_DOCSET) +# there is already a search function so this one should typically be disabled. +# For large projects the JavaScript based search engine can be slow, then +# enabling SERVER_BASED_SEARCH may provide a better solution. It is possible to +# search using the keyboard; to jump to the search box use + S +# (what the is depends on the OS and browser, but it is typically +# , /