├── .dockerignore ├── .editorconfig ├── .env.dist ├── .github ├── FUNDING.yml └── workflows │ ├── dev-publish.yml │ ├── publish.yml │ ├── rust.yml │ └── validate.yml ├── .gitignore ├── Cargo.lock ├── Cargo.toml ├── LICENSE ├── Makefile ├── README.md ├── docker └── Dockerfile ├── src ├── build.rs ├── host_header.rs ├── main.rs ├── resources.rs ├── resources │ ├── AppleResponse.rs │ ├── AutoDiscoverJson.rs │ ├── AutoDiscoverXml.rs │ ├── DnsTxtResponse.rs │ └── Version.rs ├── routes.rs ├── routes │ ├── autoconfig.rs │ ├── dns.rs │ └── tech.rs └── util.rs ├── templates ├── apple.html.tera ├── dns │ └── zone.txt.tera ├── index.html.tera └── xml │ ├── autodiscover-error.xml.tera │ ├── autodiscover-mobilesync.xml.tera │ ├── autodiscover.xml.tera │ ├── config-v1.1.xml.tera │ └── email_mobileconfig.tera └── xml ├── autodiscover ├── AutodiscoverExchangeResponse.xml ├── AutodiscoverRequest.xml ├── AutodiscoverResponse.xml ├── AutodiscoverResponseError.xml └── AutodiscoverResponseRedirect.xml ├── mobilesync └── AutodiscoverRequest.xml └── xsd ├── autodiscover ├── AutodiscoverExchangeResponse.xsd ├── AutodiscoverExchangeResponseRedirect.xsd ├── AutodiscoverRequest.xsd ├── AutodiscoverResponse.xsd ├── AutodiscoverResponseError.xsd └── AutodiscoverResponseRedirect.xsd └── mobilesync ├── AutodiscoverMobileSyncResponse.xsd ├── AutodiscoverRequest.xsd └── AutodiscoverResponse.xsd /.dockerignore: -------------------------------------------------------------------------------- 1 | /* 2 | !/src 3 | !/templates 4 | !/Cargo.toml 5 | !/Cargo.lock 6 | !/.git 7 | /.git/*config* 8 | /.git/smartgit 9 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | indent_style = space 5 | indent_size = 4 6 | end_of_line = lf 7 | charset = utf-8 8 | trim_trailing_whitespace = true 9 | insert_final_newline = true 10 | 11 | [Makefile] 12 | indent_style = tab 13 | 14 | [*.yml] 15 | indent_size = 2 16 | -------------------------------------------------------------------------------- /.env.dist: -------------------------------------------------------------------------------- 1 | # https://www.uuidgenerator.net/ 2 | APPLE_MAIL_UUID= 3 | APPLE_PROFILE_UUID= 4 | CUSTOM_DOMAINS=foo.tld 5 | IMAP_HOSTNAME=imap.mails.provider.tld 6 | POP_HOSTNAME=pop.mails.provider.tld 7 | SMTP_HOSTNAME=smtp.mails.provider.tld 8 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | github: wdes 2 | custom: https://www.paypal.com/donate/?hosted_button_id=7K4QTYD6E9976 3 | -------------------------------------------------------------------------------- /.github/workflows/dev-publish.yml: -------------------------------------------------------------------------------- 1 | name: Publish Docker image 2 | 3 | permissions: 4 | contents: read 5 | packages: write 6 | 7 | on: 8 | push: 9 | 10 | jobs: 11 | untagged-cleanup: 12 | name: Cleanup not tagged refs 13 | environment: 14 | name: "github-registry" 15 | url: https://github.com/orgs/wdes/packages?repo_name=mail-autodiscover-autoconfig 16 | runs-on: ubuntu-latest 17 | permissions: 18 | packages: write 19 | steps: 20 | - name: Delete not tagged refs 21 | uses: bots-house/ghcr-delete-image-action@v1.1.0 22 | with: 23 | owner: wdes 24 | name: mail-autodiscover-autoconfig/mail-autodiscover-autoconfig 25 | token: ${{ secrets.GITHUB_TOKEN }} 26 | # Keep latest N untagged images 27 | untagged-keep-latest: 6 28 | 29 | build-binaries: 30 | name: Build multi arch binaries (${{ matrix.arch }}-${{ matrix.variant }}) for ${{ matrix.os }} 31 | environment: 32 | name: "github-registry" 33 | url: https://github.com/orgs/wdes/packages?repo_name=mail-autodiscover-autoconfig 34 | runs-on: ubuntu-latest 35 | strategy: 36 | fail-fast: false 37 | max-parallel: 1 38 | matrix: 39 | include: 40 | - { os: linux, arch: x86_64, variant: gnu } 41 | - { os: linux, arch: x86_64, variant: musl } 42 | 43 | - { os: linux, arch: aarch64, variant: gnu } 44 | - { os: linux, arch: aarch64, variant: musl } 45 | 46 | - { os: linux, arch: riscv64gc, variant: gnu } 47 | # Toolchain not found 48 | #- { os: linux, arch: riscv64gc, variant: musl } 49 | 50 | # Toolchain not found 51 | #- { os: linux, arch: riscv32gc, variant: gnu } 52 | # Toolchain not found 53 | #- { os: linux, arch: riscv32gc, variant: musl } 54 | 55 | - { os: linux, arch: arm, variant: gnueabi } 56 | - { os: linux, arch: arm, variant: gnueabihf } 57 | - { os: linux, arch: arm, variant: musleabi } 58 | - { os: linux, arch: arm, variant: musleabihf } 59 | 60 | - { os: linux, arch: armv7, variant: gnueabi } 61 | - { os: linux, arch: armv7, variant: gnueabihf } 62 | - { os: linux, arch: armv7, variant: musleabi } 63 | - { os: linux, arch: armv7, variant: musleabihf } 64 | 65 | - { os: linux, arch: s390x, variant: gnu } 66 | 67 | - { os: linux, arch: armv5te, variant: gnueabi } 68 | - { os: linux, arch: armv5te, variant: musleabi } 69 | 70 | - { os: linux, arch: i586, variant: gnu } 71 | - { os: linux, arch: i586, variant: musl } 72 | 73 | - { os: linux, arch: i686, variant: gnu } 74 | 75 | - { os: linux, arch: powerpc, variant: gnu } 76 | - { os: linux, arch: powerpc64, variant: gnu } 77 | - { os: linux, arch: powerpc64le, variant: gnu } 78 | 79 | - { os: linux, arch: sparc64, variant: gnu } 80 | 81 | steps: 82 | - name: Cache cargo registry 83 | uses: actions/cache@v3 84 | with: 85 | path: ~/.cargo/registry 86 | key: ${{ runner.os }}-cargo-registry-${{ hashFiles('**/Cargo.lock') }} 87 | - name: Cache cargo index 88 | uses: actions/cache@v3 89 | with: 90 | path: ~/.cargo/git 91 | key: ${{ runner.os }}-cargo-index-${{ hashFiles('**/Cargo.lock') }} 92 | - name: Cache cargo build 93 | uses: actions/cache@v3 94 | with: 95 | path: target 96 | key: ${{ runner.os }}-cargo-build-target-${{ hashFiles('**/Cargo.lock') }} 97 | - name: Checkout repository 98 | uses: actions/checkout@v4 99 | - name: Set up toolchain 100 | uses: actions-rs/toolchain@v1 101 | with: 102 | profile: minimal 103 | toolchain: 1.72 104 | override: true 105 | target: ${{ matrix.arch }}-unknown-${{ matrix.os }}-${{ matrix.variant }} 106 | - name: Build 107 | uses: actions-rs/cargo@v1 108 | with: 109 | use-cross: true 110 | command: build 111 | args: --release --locked --target ${{ matrix.arch }}-unknown-${{ matrix.os }}-${{ matrix.variant }} 112 | 113 | - name: Create builds folder 114 | run: mkdir ./builds 115 | 116 | - name: Rename file 117 | run: mv ./target/${{ matrix.arch }}-unknown-${{ matrix.os }}-${{ matrix.variant }}/release/mail-autodiscover-autoconfig ./builds/mail-autodiscover-autoconfig_${{ matrix.arch }}-unknown-${{ matrix.os }}-${{ matrix.variant }} 118 | 119 | - name: Upload Artifact 120 | uses: actions/upload-artifact@v3 121 | with: 122 | name: mail-autodiscover-autoconfig_${{ matrix.arch }}-unknown-${{ matrix.os }}-${{ matrix.variant }}.tgz 123 | path: ./builds/* 124 | if-no-files-found: error 125 | retention-days: 1 126 | 127 | build-image: 128 | runs-on: ubuntu-latest 129 | environment: 130 | name: "github-registry" 131 | url: https://github.com/orgs/wdes/packages?repo_name=mail-autodiscover-autoconfig 132 | strategy: 133 | fail-fast: false 134 | max-parallel: 4 135 | matrix: 136 | include: 137 | - { platform: "linux/arm/v6", internal-tag: "armv6" } 138 | - { platform: "linux/arm/v7", internal-tag: "armv7" } 139 | # Does not finish building 140 | #- { platform: "linux/arm64/v8", internal-tag: "arm64v8" } 141 | - { platform: "linux/386", internal-tag: "386" } 142 | # Does not finish building 143 | #- { platform: "linux/ppc64le", internal-tag: "ppc64le" } 144 | - { platform: "linux/amd64", internal-tag: "amd64" } 145 | steps: 146 | - name: Checkout repository 147 | uses: actions/checkout@v4 148 | # https://github.com/docker/setup-qemu-action 149 | - name: Set up QEMU 150 | uses: docker/setup-qemu-action@v3 151 | # https://github.com/docker/setup-buildx-action 152 | - name: Set up Docker Buildx 153 | uses: docker/setup-buildx-action@v3 154 | - name: Login to the registry 155 | uses: docker/login-action@v3 156 | with: 157 | registry: ghcr.io 158 | username: ${{ github.actor }} 159 | password: ${{ secrets.GITHUB_TOKEN }} 160 | - name: Build and push image 161 | run: make docker-build 162 | env: 163 | DOCKER_BUILDKIT: 1 164 | BUILDKIT_MULTI_PLATFORM: "false" 165 | PLATFORM: ${{ matrix.platform }} 166 | IMAGE_TAG: "ghcr.io/wdes/mail-autodiscover-autoconfig/mail-autodiscover-autoconfig:${{ matrix.internal-tag }}-edge" 167 | ACTION: push 168 | # Disable provenance to remove the attestation from the pushed image 169 | # See: https://github.com/docker/buildx/issues/1509 170 | # It makes: ghcr.io/wdes/mail-autodiscover-autoconfig/mail-autodiscover-autoconfig:-edge a manifest list 171 | # And docker manifest create does not like that 172 | EXTRA_ARGS: "--provenance=false" 173 | 174 | create-final-image: 175 | runs-on: ubuntu-latest 176 | needs: build-image 177 | name: Create the image manifest 178 | environment: 179 | name: "github-registry" 180 | url: https://github.com/orgs/wdes/packages?repo_name=mail-autodiscover-autoconfig 181 | steps: 182 | - name: Login to the registry 183 | uses: docker/login-action@v3 184 | with: 185 | registry: ghcr.io 186 | username: ${{ github.actor }} 187 | password: ${{ secrets.GITHUB_TOKEN }} 188 | - name: Create the manifest 189 | # ghcr.io/wdes/mail-autodiscover-autoconfig/mail-autodiscover-autoconfig:arm64v8-edge \ 190 | # ghcr.io/wdes/mail-autodiscover-autoconfig/mail-autodiscover-autoconfig:ppc64le-edge \ 191 | run: | 192 | docker manifest create ghcr.io/wdes/mail-autodiscover-autoconfig/mail-autodiscover-autoconfig:edge \ 193 | ghcr.io/wdes/mail-autodiscover-autoconfig/mail-autodiscover-autoconfig:armv6-edge \ 194 | ghcr.io/wdes/mail-autodiscover-autoconfig/mail-autodiscover-autoconfig:armv7-edge \ 195 | ghcr.io/wdes/mail-autodiscover-autoconfig/mail-autodiscover-autoconfig:386-edge \ 196 | ghcr.io/wdes/mail-autodiscover-autoconfig/mail-autodiscover-autoconfig:amd64-edge 197 | - name: Push the manifest 198 | run: docker manifest push ghcr.io/wdes/mail-autodiscover-autoconfig/mail-autodiscover-autoconfig:edge 199 | - name: Inspect the manifest 200 | run: docker manifest inspect ghcr.io/wdes/mail-autodiscover-autoconfig/mail-autodiscover-autoconfig:edge 201 | 202 | tags-cleanup: 203 | runs-on: ubuntu-latest 204 | needs: create-final-image 205 | name: Cleanup build tags 206 | environment: 207 | name: "github-registry" 208 | url: https://github.com/orgs/wdes/packages?repo_name=mail-autodiscover-autoconfig 209 | strategy: 210 | fail-fast: false 211 | max-parallel: 1 212 | matrix: 213 | include: 214 | - { platform: "linux/arm/v6", internal-tag: "armv6" } 215 | - { platform: "linux/arm/v7", internal-tag: "armv7" } 216 | # Does not finish building 217 | #- { platform: "linux/arm64/v8", internal-tag: "arm64v8" } 218 | - { platform: "linux/386", internal-tag: "386" } 219 | # Does not finish building 220 | #- { platform: "linux/ppc64le", internal-tag: "ppc64le" } 221 | - { platform: "linux/amd64", internal-tag: "amd64" } 222 | steps: 223 | - name: Delete build tag 224 | uses: bots-house/ghcr-delete-image-action@v1.1.0 225 | with: 226 | owner: wdes 227 | name: mail-autodiscover-autoconfig/mail-autodiscover-autoconfig 228 | token: ${{ secrets.GITHUB_TOKEN }} 229 | tag: ${{ matrix.internal-tag }}-edge 230 | -------------------------------------------------------------------------------- /.github/workflows/publish.yml: -------------------------------------------------------------------------------- 1 | name: Publish release artifacts and Docker image 2 | 3 | permissions: 4 | contents: read 5 | 6 | on: 7 | release: 8 | types: 9 | - published 10 | 11 | jobs: 12 | build-image: 13 | name: Build the Docker image on Docker Hub 14 | environment: 15 | name: "docker-hub" 16 | url: https://hub.docker.com/r/wdes/mail-autodiscover-autoconfig 17 | runs-on: ubuntu-latest 18 | strategy: 19 | fail-fast: false 20 | max-parallel: 4 21 | matrix: 22 | include: 23 | - { platform: "linux/arm/v6", internal-tag: "armv6" } 24 | - { platform: "linux/arm/v7", internal-tag: "armv7" } 25 | # Does not finish building 26 | #- { platform: "linux/arm64/v8", internal-tag: "arm64v8" } 27 | - { platform: "linux/386", internal-tag: "386" } 28 | # Does not finish building 29 | #- { platform: "linux/ppc64le", internal-tag: "ppc64le" } 30 | - { platform: "linux/amd64", internal-tag: "amd64" } 31 | steps: 32 | - name: Checkout repository 33 | uses: actions/checkout@v4 34 | # https://github.com/docker/setup-qemu-action 35 | - name: Set up QEMU 36 | uses: docker/setup-qemu-action@v3 37 | # https://github.com/docker/setup-buildx-action 38 | - name: Set up Docker Buildx 39 | uses: docker/setup-buildx-action@v3 40 | - name: Login to the registry 41 | uses: docker/login-action@v3 42 | with: 43 | registry: docker.io 44 | username: ${{ secrets.DOCKER_HUB_USER }} 45 | password: ${{ secrets.DOCKER_HUB_PASSWORD }} 46 | - name: Build and push image 47 | run: make docker-build 48 | env: 49 | DOCKER_BUILDKIT: 1 50 | BUILDKIT_MULTI_PLATFORM: "false" 51 | PLATFORM: ${{ matrix.platform }} 52 | IMAGE_TAG: "docker.io/wdes/mail-autodiscover-autoconfig:${{ matrix.internal-tag }}-latest" 53 | ACTION: push 54 | # Disable provenance to remove the attestation from the pushed image 55 | # See: https://github.com/docker/buildx/issues/1509 56 | # It makes: docker.io/wdes/mail-autodiscover-autoconfig:-latest a manifest list 57 | # And docker manifest create does not like that 58 | EXTRA_ARGS: "--provenance=false" 59 | 60 | create-final-image: 61 | environment: 62 | name: "docker-hub" 63 | url: https://hub.docker.com/r/wdes/mail-autodiscover-autoconfig 64 | runs-on: ubuntu-latest 65 | needs: build-image 66 | name: Create the image manifest 67 | steps: 68 | - name: Login to the registry 69 | uses: docker/login-action@v3 70 | with: 71 | registry: docker.io 72 | username: ${{ secrets.DOCKER_HUB_USER }} 73 | password: ${{ secrets.DOCKER_HUB_PASSWORD }} 74 | - name: Create the manifest 75 | # docker.io/wdes/mail-autodiscover-autoconfig:arm64v8-latest \ 76 | # docker.io/wdes/mail-autodiscover-autoconfig:ppc64le-latest \ 77 | run: | 78 | docker manifest create docker.io/wdes/mail-autodiscover-autoconfig:latest \ 79 | docker.io/wdes/mail-autodiscover-autoconfig:armv6-latest \ 80 | docker.io/wdes/mail-autodiscover-autoconfig:armv7-latest \ 81 | docker.io/wdes/mail-autodiscover-autoconfig:386-latest \ 82 | docker.io/wdes/mail-autodiscover-autoconfig:amd64-latest \ 83 | --amend 84 | - name: Push the manifest 85 | run: docker manifest push docker.io/wdes/mail-autodiscover-autoconfig:latest 86 | - name: Inspect the manifest 87 | run: docker manifest inspect docker.io/wdes/mail-autodiscover-autoconfig:latest 88 | 89 | tags-cleanup: 90 | environment: 91 | name: "docker-hub" 92 | url: https://hub.docker.com/r/wdes/mail-autodiscover-autoconfig 93 | runs-on: ubuntu-latest 94 | needs: create-final-image 95 | name: Cleanup build tags 96 | strategy: 97 | fail-fast: false 98 | max-parallel: 1 99 | matrix: 100 | include: 101 | - { platform: "linux/arm/v6", internal-tag: "armv6" } 102 | - { platform: "linux/arm/v7", internal-tag: "armv7" } 103 | # Does not finish building 104 | #- { platform: "linux/arm64/v8", internal-tag: "arm64v8" } 105 | - { platform: "linux/386", internal-tag: "386" } 106 | # Does not finish building 107 | #- { platform: "linux/ppc64le", internal-tag: "ppc64le" } 108 | - { platform: "linux/amd64", internal-tag: "amd64" } 109 | steps: 110 | - name: Install Docker hub-tool 111 | run: | 112 | curl -sL https://github.com/docker/hub-tool/releases/download/v0.4.5/hub-tool-linux-amd64.tar.gz -o hub-tool-linux.tar.gz 113 | tar --strip-components=1 -xzf ./hub-tool-linux.tar.gz 114 | ./hub-tool --version 115 | - name: Login hub-tool 116 | run: | 117 | # Fool the login command (https://github.com/docker/hub-tool/pull/198) 118 | # ./hub-tool login 119 | # Token commands thank to https://stackoverflow.com/a/59334315/5155484 120 | HUB_TOKEN=$(curl -s -H "Content-Type: application/json" -X POST -d "{\"username\": \"$DOCKER_USERNAME\", \"password\": \"$DOCKER_PASSWORD\"}" https://hub.docker.com/v2/users/login/ | jq -r .token) 121 | USERNAME="$(printf '%s:' "$DOCKER_USERNAME" | base64 -w0)" 122 | USER_PASS="$(printf '%s:%s' "$DOCKER_USERNAME" "$DOCKER_PASSWORD" | base64 -w0)" 123 | mkdir -p ~/.docker/ 124 | printf '{"auths": {"hub-tool": {"auth": "%s"}, "hub-tool-refresh-token": {"auth": "%s"}, "hub-tool-token": { "auth": "%s", "identitytoken": "%s"}}}' \ 125 | "$USER_PASS" "$USERNAME" \ 126 | "$USERNAME" "$HUB_TOKEN" \ 127 | > ~/.docker/config.json 128 | env: 129 | DOCKER_USERNAME: ${{ secrets.DOCKER_HUB_USER }} 130 | DOCKER_PASSWORD: ${{ secrets.DOCKER_HUB_PASSWORD }} 131 | - name: Remove PR container image via hub-tool 132 | run: | 133 | ./hub-tool tag rm --verbose --force docker.io/wdes/mail-autodiscover-autoconfig:${{ matrix.internal-tag }}-latest || true 134 | ./hub-tool tag ls --verbose ocker.io/wdes/mail-autodiscover-autoconfig 135 | - name: Logout hub-tool 136 | if: always() 137 | run: rm ~/.docker/config.json 138 | 139 | publish-binaries: 140 | name: Publish multi arch binaries on the release draft (${{ matrix.arch }}-${{ matrix.variant }}) for ${{ matrix.os }} 141 | runs-on: ubuntu-latest 142 | permissions: 143 | contents: write # Edit release artifacts 144 | strategy: 145 | fail-fast: false 146 | max-parallel: 4 147 | matrix: 148 | include: 149 | - { os: linux, arch: x86_64, variant: gnu } 150 | - { os: linux, arch: x86_64, variant: musl } 151 | 152 | - { os: linux, arch: aarch64, variant: gnu } 153 | - { os: linux, arch: aarch64, variant: musl } 154 | 155 | - { os: linux, arch: riscv64gc, variant: gnu } 156 | 157 | - { os: linux, arch: arm, variant: gnueabi } 158 | - { os: linux, arch: arm, variant: gnueabihf } 159 | - { os: linux, arch: arm, variant: musleabi } 160 | - { os: linux, arch: arm, variant: musleabihf } 161 | 162 | - { os: linux, arch: armv7, variant: gnueabi } 163 | - { os: linux, arch: armv7, variant: gnueabihf } 164 | - { os: linux, arch: armv7, variant: musleabi } 165 | - { os: linux, arch: armv7, variant: musleabihf } 166 | 167 | - { os: linux, arch: s390x, variant: gnu } 168 | 169 | - { os: linux, arch: armv5te, variant: gnueabi } 170 | - { os: linux, arch: armv5te, variant: musleabi } 171 | 172 | - { os: linux, arch: i586, variant: gnu } 173 | - { os: linux, arch: i586, variant: musl } 174 | 175 | - { os: linux, arch: i686, variant: gnu } 176 | 177 | - { os: linux, arch: powerpc, variant: gnu } 178 | - { os: linux, arch: powerpc64, variant: gnu } 179 | - { os: linux, arch: powerpc64le, variant: gnu } 180 | 181 | - { os: linux, arch: sparc64, variant: gnu } 182 | 183 | 184 | steps: 185 | - name: Cache cargo registry 186 | uses: actions/cache@v3 187 | with: 188 | path: ~/.cargo/registry 189 | key: ${{ runner.os }}-cargo-registry-${{ hashFiles('**/Cargo.lock') }} 190 | - name: Cache cargo index 191 | uses: actions/cache@v3 192 | with: 193 | path: ~/.cargo/git 194 | key: ${{ runner.os }}-cargo-index-${{ hashFiles('**/Cargo.lock') }} 195 | - name: Cache cargo build 196 | uses: actions/cache@v3 197 | with: 198 | path: target 199 | key: ${{ runner.os }}-cargo-build-target-${{ hashFiles('**/Cargo.lock') }} 200 | - name: Checkout repository 201 | uses: actions/checkout@v4 202 | - name: Set up toolchain 203 | uses: actions-rs/toolchain@v1 204 | with: 205 | profile: minimal 206 | toolchain: 1.72 207 | override: true 208 | target: ${{ matrix.arch }}-unknown-${{ matrix.os }}-${{ matrix.variant }} 209 | - name: Build 210 | uses: actions-rs/cargo@v1 211 | with: 212 | use-cross: true 213 | command: build 214 | args: --release --locked --target ${{ matrix.arch }}-unknown-${{ matrix.os }}-${{ matrix.variant }} 215 | 216 | - name: Create builds folder 217 | run: mkdir ./builds 218 | 219 | - name: Rename file 220 | run: mv ./target/${{ matrix.arch }}-unknown-${{ matrix.os }}-${{ matrix.variant }}/release/mail-autodiscover-autoconfig ./builds/mail-autodiscover-autoconfig_${{ matrix.arch }}-unknown-${{ matrix.os }}-${{ matrix.variant }} 221 | 222 | - name: Upload Artifact 223 | uses: actions/upload-artifact@v3 224 | with: 225 | name: mail-autodiscover-autoconfig_${{ matrix.arch }}-unknown-${{ matrix.os }}-${{ matrix.variant }}.tgz 226 | path: ./builds/* 227 | if-no-files-found: error 228 | retention-days: 1 229 | 230 | - name: Upload binaries to release 231 | uses: svenstaro/upload-release-action@v2 232 | with: 233 | repo_token: ${{ secrets.GITHUB_TOKEN }} 234 | file: builds/* 235 | file_glob: true 236 | tag: ${{ github.ref }} 237 | -------------------------------------------------------------------------------- /.github/workflows/rust.yml: -------------------------------------------------------------------------------- 1 | name: Build and test rust code 2 | 3 | on: 4 | push: 5 | pull_request: 6 | 7 | permissions: 8 | contents: read 9 | 10 | jobs: 11 | build_and_test: 12 | runs-on: ubuntu-latest 13 | name: Build and test binary 14 | steps: 15 | - name: Cache cargo registry 16 | uses: actions/cache@v3 17 | with: 18 | path: ~/.cargo/registry 19 | key: ${{ runner.os }}-cargo-registry-${{ hashFiles('**/Cargo.lock') }} 20 | - name: Cache cargo index 21 | uses: actions/cache@v3 22 | with: 23 | path: ~/.cargo/git 24 | key: ${{ runner.os }}-cargo-index-${{ hashFiles('**/Cargo.lock') }} 25 | - name: Cache cargo build 26 | uses: actions/cache@v3 27 | with: 28 | path: target 29 | key: ${{ runner.os }}-cargo-build-target-${{ hashFiles('**/Cargo.lock') }} 30 | - name: Checkout repository 31 | uses: actions/checkout@v4 32 | - name: Set up toolchain 33 | uses: actions-rs/toolchain@v1 34 | with: 35 | profile: minimal 36 | toolchain: 1.72 37 | override: true 38 | - name: Build 39 | uses: actions-rs/cargo@v1 40 | with: 41 | command: build 42 | args: --release 43 | - name: Test 44 | uses: actions-rs/cargo@v1 45 | with: 46 | command: test 47 | args: --release 48 | -------------------------------------------------------------------------------- /.github/workflows/validate.yml: -------------------------------------------------------------------------------- 1 | name: Validate XML files 2 | 3 | on: 4 | push: 5 | pull_request: 6 | 7 | permissions: 8 | contents: read 9 | 10 | jobs: 11 | Validate: 12 | runs-on: ubuntu-latest 13 | steps: 14 | - name: Checkout repository 15 | uses: actions/checkout@v4 16 | - name: Install xmllint 17 | run: sudo apt-get -y --no-install-recommends install libxml2-utils 18 | - name: Check 19 | run: make validate 20 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Generated by Cargo 2 | # will have compiled files and executables 3 | /target/ 4 | 5 | # These are backup files generated by rustfmt 6 | **/*.rs.bk 7 | 8 | /.vscode 9 | /.env 10 | !/.env.dist 11 | -------------------------------------------------------------------------------- /Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 3 4 | 5 | [[package]] 6 | name = "addr" 7 | version = "0.15.6" 8 | source = "registry+https://github.com/rust-lang/crates.io-index" 9 | checksum = "a93b8a41dbe230ad5087cc721f8d41611de654542180586b315d9f4cf6b72bef" 10 | dependencies = [ 11 | "psl", 12 | "psl-types", 13 | ] 14 | 15 | [[package]] 16 | name = "addr2line" 17 | version = "0.21.0" 18 | source = "registry+https://github.com/rust-lang/crates.io-index" 19 | checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" 20 | dependencies = [ 21 | "gimli", 22 | ] 23 | 24 | [[package]] 25 | name = "adler" 26 | version = "1.0.2" 27 | source = "registry+https://github.com/rust-lang/crates.io-index" 28 | checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" 29 | 30 | [[package]] 31 | name = "aho-corasick" 32 | version = "1.1.2" 33 | source = "registry+https://github.com/rust-lang/crates.io-index" 34 | checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0" 35 | dependencies = [ 36 | "memchr", 37 | ] 38 | 39 | [[package]] 40 | name = "android-tzdata" 41 | version = "0.1.1" 42 | source = "registry+https://github.com/rust-lang/crates.io-index" 43 | checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" 44 | 45 | [[package]] 46 | name = "android_system_properties" 47 | version = "0.1.5" 48 | source = "registry+https://github.com/rust-lang/crates.io-index" 49 | checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" 50 | dependencies = [ 51 | "libc", 52 | ] 53 | 54 | [[package]] 55 | name = "anyhow" 56 | version = "1.0.79" 57 | source = "registry+https://github.com/rust-lang/crates.io-index" 58 | checksum = "080e9890a082662b09c1ad45f567faeeb47f22b5fb23895fbe1e651e718e25ca" 59 | 60 | [[package]] 61 | name = "async-stream" 62 | version = "0.3.5" 63 | source = "registry+https://github.com/rust-lang/crates.io-index" 64 | checksum = "cd56dd203fef61ac097dd65721a419ddccb106b2d2b70ba60a6b529f03961a51" 65 | dependencies = [ 66 | "async-stream-impl", 67 | "futures-core", 68 | "pin-project-lite", 69 | ] 70 | 71 | [[package]] 72 | name = "async-stream-impl" 73 | version = "0.3.5" 74 | source = "registry+https://github.com/rust-lang/crates.io-index" 75 | checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193" 76 | dependencies = [ 77 | "proc-macro2", 78 | "quote", 79 | "syn", 80 | ] 81 | 82 | [[package]] 83 | name = "async-trait" 84 | version = "0.1.77" 85 | source = "registry+https://github.com/rust-lang/crates.io-index" 86 | checksum = "c980ee35e870bd1a4d2c8294d4c04d0499e67bca1e4b5cefcc693c2fa00caea9" 87 | dependencies = [ 88 | "proc-macro2", 89 | "quote", 90 | "syn", 91 | ] 92 | 93 | [[package]] 94 | name = "atomic" 95 | version = "0.5.3" 96 | source = "registry+https://github.com/rust-lang/crates.io-index" 97 | checksum = "c59bdb34bc650a32731b31bd8f0829cc15d24a708ee31559e0bb34f2bc320cba" 98 | 99 | [[package]] 100 | name = "atomic" 101 | version = "0.6.0" 102 | source = "registry+https://github.com/rust-lang/crates.io-index" 103 | checksum = "8d818003e740b63afc82337e3160717f4f63078720a810b7b903e70a5d1d2994" 104 | dependencies = [ 105 | "bytemuck", 106 | ] 107 | 108 | [[package]] 109 | name = "autocfg" 110 | version = "1.1.0" 111 | source = "registry+https://github.com/rust-lang/crates.io-index" 112 | checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" 113 | 114 | [[package]] 115 | name = "backtrace" 116 | version = "0.3.69" 117 | source = "registry+https://github.com/rust-lang/crates.io-index" 118 | checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837" 119 | dependencies = [ 120 | "addr2line", 121 | "cc", 122 | "cfg-if", 123 | "libc", 124 | "miniz_oxide", 125 | "object", 126 | "rustc-demangle", 127 | ] 128 | 129 | [[package]] 130 | name = "binascii" 131 | version = "0.1.4" 132 | source = "registry+https://github.com/rust-lang/crates.io-index" 133 | checksum = "383d29d513d8764dcdc42ea295d979eb99c3c9f00607b3692cf68a431f7dca72" 134 | 135 | [[package]] 136 | name = "bitflags" 137 | version = "1.3.2" 138 | source = "registry+https://github.com/rust-lang/crates.io-index" 139 | checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" 140 | 141 | [[package]] 142 | name = "bitflags" 143 | version = "2.4.2" 144 | source = "registry+https://github.com/rust-lang/crates.io-index" 145 | checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf" 146 | 147 | [[package]] 148 | name = "block-buffer" 149 | version = "0.10.4" 150 | source = "registry+https://github.com/rust-lang/crates.io-index" 151 | checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" 152 | dependencies = [ 153 | "generic-array", 154 | ] 155 | 156 | [[package]] 157 | name = "bstr" 158 | version = "1.9.0" 159 | source = "registry+https://github.com/rust-lang/crates.io-index" 160 | checksum = "c48f0051a4b4c5e0b6d365cd04af53aeaa209e3cc15ec2cdb69e73cc87fbd0dc" 161 | dependencies = [ 162 | "memchr", 163 | "serde", 164 | ] 165 | 166 | [[package]] 167 | name = "bumpalo" 168 | version = "3.14.0" 169 | source = "registry+https://github.com/rust-lang/crates.io-index" 170 | checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec" 171 | 172 | [[package]] 173 | name = "bytemuck" 174 | version = "1.14.3" 175 | source = "registry+https://github.com/rust-lang/crates.io-index" 176 | checksum = "a2ef034f05691a48569bd920a96c81b9d91bbad1ab5ac7c4616c1f6ef36cb79f" 177 | 178 | [[package]] 179 | name = "bytes" 180 | version = "1.5.0" 181 | source = "registry+https://github.com/rust-lang/crates.io-index" 182 | checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223" 183 | 184 | [[package]] 185 | name = "camino" 186 | version = "1.1.6" 187 | source = "registry+https://github.com/rust-lang/crates.io-index" 188 | checksum = "c59e92b5a388f549b863a7bea62612c09f24c8393560709a54558a9abdfb3b9c" 189 | dependencies = [ 190 | "serde", 191 | ] 192 | 193 | [[package]] 194 | name = "cargo-platform" 195 | version = "0.1.7" 196 | source = "registry+https://github.com/rust-lang/crates.io-index" 197 | checksum = "694c8807f2ae16faecc43dc17d74b3eb042482789fd0eb64b39a2e04e087053f" 198 | dependencies = [ 199 | "serde", 200 | ] 201 | 202 | [[package]] 203 | name = "cargo_metadata" 204 | version = "0.18.1" 205 | source = "registry+https://github.com/rust-lang/crates.io-index" 206 | checksum = "2d886547e41f740c616ae73108f6eb70afe6d940c7bc697cb30f13daec073037" 207 | dependencies = [ 208 | "camino", 209 | "cargo-platform", 210 | "semver", 211 | "serde", 212 | "serde_json", 213 | "thiserror", 214 | ] 215 | 216 | [[package]] 217 | name = "cc" 218 | version = "1.0.83" 219 | source = "registry+https://github.com/rust-lang/crates.io-index" 220 | checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" 221 | dependencies = [ 222 | "libc", 223 | ] 224 | 225 | [[package]] 226 | name = "cfg-if" 227 | version = "1.0.0" 228 | source = "registry+https://github.com/rust-lang/crates.io-index" 229 | checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" 230 | 231 | [[package]] 232 | name = "chrono" 233 | version = "0.4.34" 234 | source = "registry+https://github.com/rust-lang/crates.io-index" 235 | checksum = "5bc015644b92d5890fab7489e49d21f879d5c990186827d42ec511919404f38b" 236 | dependencies = [ 237 | "android-tzdata", 238 | "iana-time-zone", 239 | "js-sys", 240 | "num-traits", 241 | "wasm-bindgen", 242 | "windows-targets 0.52.0", 243 | ] 244 | 245 | [[package]] 246 | name = "chrono-tz" 247 | version = "0.8.6" 248 | source = "registry+https://github.com/rust-lang/crates.io-index" 249 | checksum = "d59ae0466b83e838b81a54256c39d5d7c20b9d7daa10510a242d9b75abd5936e" 250 | dependencies = [ 251 | "chrono", 252 | "chrono-tz-build", 253 | "phf", 254 | ] 255 | 256 | [[package]] 257 | name = "chrono-tz-build" 258 | version = "0.2.1" 259 | source = "registry+https://github.com/rust-lang/crates.io-index" 260 | checksum = "433e39f13c9a060046954e0592a8d0a4bcb1040125cbf91cb8ee58964cfb350f" 261 | dependencies = [ 262 | "parse-zoneinfo", 263 | "phf", 264 | "phf_codegen", 265 | ] 266 | 267 | [[package]] 268 | name = "cookie" 269 | version = "0.18.0" 270 | source = "registry+https://github.com/rust-lang/crates.io-index" 271 | checksum = "3cd91cf61412820176e137621345ee43b3f4423e589e7ae4e50d601d93e35ef8" 272 | dependencies = [ 273 | "percent-encoding", 274 | "time", 275 | "version_check", 276 | ] 277 | 278 | [[package]] 279 | name = "core-foundation-sys" 280 | version = "0.8.6" 281 | source = "registry+https://github.com/rust-lang/crates.io-index" 282 | checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" 283 | 284 | [[package]] 285 | name = "cpufeatures" 286 | version = "0.2.12" 287 | source = "registry+https://github.com/rust-lang/crates.io-index" 288 | checksum = "53fe5e26ff1b7aef8bca9c6080520cfb8d9333c7568e1829cef191a9723e5504" 289 | dependencies = [ 290 | "libc", 291 | ] 292 | 293 | [[package]] 294 | name = "crossbeam-channel" 295 | version = "0.5.11" 296 | source = "registry+https://github.com/rust-lang/crates.io-index" 297 | checksum = "176dc175b78f56c0f321911d9c8eb2b77a78a4860b9c19db83835fea1a46649b" 298 | dependencies = [ 299 | "crossbeam-utils", 300 | ] 301 | 302 | [[package]] 303 | name = "crossbeam-deque" 304 | version = "0.8.5" 305 | source = "registry+https://github.com/rust-lang/crates.io-index" 306 | checksum = "613f8cc01fe9cf1a3eb3d7f488fd2fa8388403e97039e2f73692932e291a770d" 307 | dependencies = [ 308 | "crossbeam-epoch", 309 | "crossbeam-utils", 310 | ] 311 | 312 | [[package]] 313 | name = "crossbeam-epoch" 314 | version = "0.9.18" 315 | source = "registry+https://github.com/rust-lang/crates.io-index" 316 | checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" 317 | dependencies = [ 318 | "crossbeam-utils", 319 | ] 320 | 321 | [[package]] 322 | name = "crossbeam-utils" 323 | version = "0.8.19" 324 | source = "registry+https://github.com/rust-lang/crates.io-index" 325 | checksum = "248e3bacc7dc6baa3b21e405ee045c3047101a49145e7e9eca583ab4c2ca5345" 326 | 327 | [[package]] 328 | name = "crypto-common" 329 | version = "0.1.6" 330 | source = "registry+https://github.com/rust-lang/crates.io-index" 331 | checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" 332 | dependencies = [ 333 | "generic-array", 334 | "typenum", 335 | ] 336 | 337 | [[package]] 338 | name = "deranged" 339 | version = "0.3.11" 340 | source = "registry+https://github.com/rust-lang/crates.io-index" 341 | checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4" 342 | dependencies = [ 343 | "powerfmt", 344 | ] 345 | 346 | [[package]] 347 | name = "deunicode" 348 | version = "1.4.2" 349 | source = "registry+https://github.com/rust-lang/crates.io-index" 350 | checksum = "3ae2a35373c5c74340b79ae6780b498b2b183915ec5dacf263aac5a099bf485a" 351 | 352 | [[package]] 353 | name = "devise" 354 | version = "0.4.1" 355 | source = "registry+https://github.com/rust-lang/crates.io-index" 356 | checksum = "d6eacefd3f541c66fc61433d65e54e0e46e0a029a819a7dbbc7a7b489e8a85f8" 357 | dependencies = [ 358 | "devise_codegen", 359 | "devise_core", 360 | ] 361 | 362 | [[package]] 363 | name = "devise_codegen" 364 | version = "0.4.1" 365 | source = "registry+https://github.com/rust-lang/crates.io-index" 366 | checksum = "9c8cf4b8dd484ede80fd5c547592c46c3745a617c8af278e2b72bea86b2dfed6" 367 | dependencies = [ 368 | "devise_core", 369 | "quote", 370 | ] 371 | 372 | [[package]] 373 | name = "devise_core" 374 | version = "0.4.1" 375 | source = "registry+https://github.com/rust-lang/crates.io-index" 376 | checksum = "35b50dba0afdca80b187392b24f2499a88c336d5a8493e4b4ccfb608708be56a" 377 | dependencies = [ 378 | "bitflags 2.4.2", 379 | "proc-macro2", 380 | "proc-macro2-diagnostics", 381 | "quote", 382 | "syn", 383 | ] 384 | 385 | [[package]] 386 | name = "digest" 387 | version = "0.10.7" 388 | source = "registry+https://github.com/rust-lang/crates.io-index" 389 | checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" 390 | dependencies = [ 391 | "block-buffer", 392 | "crypto-common", 393 | ] 394 | 395 | [[package]] 396 | name = "dotenv" 397 | version = "0.15.0" 398 | source = "registry+https://github.com/rust-lang/crates.io-index" 399 | checksum = "77c90badedccf4105eca100756a0b1289e191f6fcbdadd3cee1d2f614f97da8f" 400 | 401 | [[package]] 402 | name = "either" 403 | version = "1.10.0" 404 | source = "registry+https://github.com/rust-lang/crates.io-index" 405 | checksum = "11157ac094ffbdde99aa67b23417ebdd801842852b500e395a45a9c0aac03e4a" 406 | 407 | [[package]] 408 | name = "encoding_rs" 409 | version = "0.8.33" 410 | source = "registry+https://github.com/rust-lang/crates.io-index" 411 | checksum = "7268b386296a025e474d5140678f75d6de9493ae55a5d709eeb9dd08149945e1" 412 | dependencies = [ 413 | "cfg-if", 414 | ] 415 | 416 | [[package]] 417 | name = "equivalent" 418 | version = "1.0.1" 419 | source = "registry+https://github.com/rust-lang/crates.io-index" 420 | checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" 421 | 422 | [[package]] 423 | name = "errno" 424 | version = "0.3.8" 425 | source = "registry+https://github.com/rust-lang/crates.io-index" 426 | checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245" 427 | dependencies = [ 428 | "libc", 429 | "windows-sys 0.52.0", 430 | ] 431 | 432 | [[package]] 433 | name = "fastrand" 434 | version = "2.0.1" 435 | source = "registry+https://github.com/rust-lang/crates.io-index" 436 | checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5" 437 | 438 | [[package]] 439 | name = "figment" 440 | version = "0.10.14" 441 | source = "registry+https://github.com/rust-lang/crates.io-index" 442 | checksum = "2b6e5bc7bd59d60d0d45a6ccab6cf0f4ce28698fb4e81e750ddf229c9b824026" 443 | dependencies = [ 444 | "atomic 0.6.0", 445 | "pear", 446 | "serde", 447 | "toml", 448 | "uncased", 449 | "version_check", 450 | ] 451 | 452 | [[package]] 453 | name = "filetime" 454 | version = "0.2.23" 455 | source = "registry+https://github.com/rust-lang/crates.io-index" 456 | checksum = "1ee447700ac8aa0b2f2bd7bc4462ad686ba06baa6727ac149a2d6277f0d240fd" 457 | dependencies = [ 458 | "cfg-if", 459 | "libc", 460 | "redox_syscall", 461 | "windows-sys 0.52.0", 462 | ] 463 | 464 | [[package]] 465 | name = "fnv" 466 | version = "1.0.7" 467 | source = "registry+https://github.com/rust-lang/crates.io-index" 468 | checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" 469 | 470 | [[package]] 471 | name = "fsevent-sys" 472 | version = "4.1.0" 473 | source = "registry+https://github.com/rust-lang/crates.io-index" 474 | checksum = "76ee7a02da4d231650c7cea31349b889be2f45ddb3ef3032d2ec8185f6313fd2" 475 | dependencies = [ 476 | "libc", 477 | ] 478 | 479 | [[package]] 480 | name = "futures" 481 | version = "0.3.30" 482 | source = "registry+https://github.com/rust-lang/crates.io-index" 483 | checksum = "645c6916888f6cb6350d2550b80fb63e734897a8498abe35cfb732b6487804b0" 484 | dependencies = [ 485 | "futures-channel", 486 | "futures-core", 487 | "futures-io", 488 | "futures-sink", 489 | "futures-task", 490 | "futures-util", 491 | ] 492 | 493 | [[package]] 494 | name = "futures-channel" 495 | version = "0.3.30" 496 | source = "registry+https://github.com/rust-lang/crates.io-index" 497 | checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78" 498 | dependencies = [ 499 | "futures-core", 500 | "futures-sink", 501 | ] 502 | 503 | [[package]] 504 | name = "futures-core" 505 | version = "0.3.30" 506 | source = "registry+https://github.com/rust-lang/crates.io-index" 507 | checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" 508 | 509 | [[package]] 510 | name = "futures-io" 511 | version = "0.3.30" 512 | source = "registry+https://github.com/rust-lang/crates.io-index" 513 | checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" 514 | 515 | [[package]] 516 | name = "futures-sink" 517 | version = "0.3.30" 518 | source = "registry+https://github.com/rust-lang/crates.io-index" 519 | checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5" 520 | 521 | [[package]] 522 | name = "futures-task" 523 | version = "0.3.30" 524 | source = "registry+https://github.com/rust-lang/crates.io-index" 525 | checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" 526 | 527 | [[package]] 528 | name = "futures-util" 529 | version = "0.3.30" 530 | source = "registry+https://github.com/rust-lang/crates.io-index" 531 | checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" 532 | dependencies = [ 533 | "futures-channel", 534 | "futures-core", 535 | "futures-io", 536 | "futures-sink", 537 | "futures-task", 538 | "memchr", 539 | "pin-project-lite", 540 | "pin-utils", 541 | "slab", 542 | ] 543 | 544 | [[package]] 545 | name = "generator" 546 | version = "0.7.5" 547 | source = "registry+https://github.com/rust-lang/crates.io-index" 548 | checksum = "5cc16584ff22b460a382b7feec54b23d2908d858152e5739a120b949293bd74e" 549 | dependencies = [ 550 | "cc", 551 | "libc", 552 | "log", 553 | "rustversion", 554 | "windows", 555 | ] 556 | 557 | [[package]] 558 | name = "generic-array" 559 | version = "0.14.7" 560 | source = "registry+https://github.com/rust-lang/crates.io-index" 561 | checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" 562 | dependencies = [ 563 | "typenum", 564 | "version_check", 565 | ] 566 | 567 | [[package]] 568 | name = "getrandom" 569 | version = "0.2.12" 570 | source = "registry+https://github.com/rust-lang/crates.io-index" 571 | checksum = "190092ea657667030ac6a35e305e62fc4dd69fd98ac98631e5d3a2b1575a12b5" 572 | dependencies = [ 573 | "cfg-if", 574 | "libc", 575 | "wasi", 576 | ] 577 | 578 | [[package]] 579 | name = "gimli" 580 | version = "0.28.1" 581 | source = "registry+https://github.com/rust-lang/crates.io-index" 582 | checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" 583 | 584 | [[package]] 585 | name = "glob" 586 | version = "0.3.1" 587 | source = "registry+https://github.com/rust-lang/crates.io-index" 588 | checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" 589 | 590 | [[package]] 591 | name = "globset" 592 | version = "0.4.14" 593 | source = "registry+https://github.com/rust-lang/crates.io-index" 594 | checksum = "57da3b9b5b85bd66f31093f8c408b90a74431672542466497dcbdfdc02034be1" 595 | dependencies = [ 596 | "aho-corasick", 597 | "bstr", 598 | "log", 599 | "regex-automata 0.4.5", 600 | "regex-syntax 0.8.2", 601 | ] 602 | 603 | [[package]] 604 | name = "globwalk" 605 | version = "0.8.1" 606 | source = "registry+https://github.com/rust-lang/crates.io-index" 607 | checksum = "93e3af942408868f6934a7b85134a3230832b9977cf66125df2f9edcfce4ddcc" 608 | dependencies = [ 609 | "bitflags 1.3.2", 610 | "ignore", 611 | "walkdir", 612 | ] 613 | 614 | [[package]] 615 | name = "h2" 616 | version = "0.3.24" 617 | source = "registry+https://github.com/rust-lang/crates.io-index" 618 | checksum = "bb2c4422095b67ee78da96fbb51a4cc413b3b25883c7717ff7ca1ab31022c9c9" 619 | dependencies = [ 620 | "bytes", 621 | "fnv", 622 | "futures-core", 623 | "futures-sink", 624 | "futures-util", 625 | "http", 626 | "indexmap", 627 | "slab", 628 | "tokio", 629 | "tokio-util", 630 | "tracing", 631 | ] 632 | 633 | [[package]] 634 | name = "hashbrown" 635 | version = "0.14.3" 636 | source = "registry+https://github.com/rust-lang/crates.io-index" 637 | checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" 638 | 639 | [[package]] 640 | name = "hermit-abi" 641 | version = "0.3.5" 642 | source = "registry+https://github.com/rust-lang/crates.io-index" 643 | checksum = "d0c62115964e08cb8039170eb33c1d0e2388a256930279edca206fff675f82c3" 644 | 645 | [[package]] 646 | name = "http" 647 | version = "0.2.11" 648 | source = "registry+https://github.com/rust-lang/crates.io-index" 649 | checksum = "8947b1a6fad4393052c7ba1f4cd97bed3e953a95c79c92ad9b051a04611d9fbb" 650 | dependencies = [ 651 | "bytes", 652 | "fnv", 653 | "itoa", 654 | ] 655 | 656 | [[package]] 657 | name = "http-body" 658 | version = "0.4.6" 659 | source = "registry+https://github.com/rust-lang/crates.io-index" 660 | checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" 661 | dependencies = [ 662 | "bytes", 663 | "http", 664 | "pin-project-lite", 665 | ] 666 | 667 | [[package]] 668 | name = "httparse" 669 | version = "1.8.0" 670 | source = "registry+https://github.com/rust-lang/crates.io-index" 671 | checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" 672 | 673 | [[package]] 674 | name = "httpdate" 675 | version = "1.0.3" 676 | source = "registry+https://github.com/rust-lang/crates.io-index" 677 | checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" 678 | 679 | [[package]] 680 | name = "humansize" 681 | version = "2.1.3" 682 | source = "registry+https://github.com/rust-lang/crates.io-index" 683 | checksum = "6cb51c9a029ddc91b07a787f1d86b53ccfa49b0e86688c946ebe8d3555685dd7" 684 | dependencies = [ 685 | "libm", 686 | ] 687 | 688 | [[package]] 689 | name = "hyper" 690 | version = "0.14.28" 691 | source = "registry+https://github.com/rust-lang/crates.io-index" 692 | checksum = "bf96e135eb83a2a8ddf766e426a841d8ddd7449d5f00d34ea02b41d2f19eef80" 693 | dependencies = [ 694 | "bytes", 695 | "futures-channel", 696 | "futures-core", 697 | "futures-util", 698 | "h2", 699 | "http", 700 | "http-body", 701 | "httparse", 702 | "httpdate", 703 | "itoa", 704 | "pin-project-lite", 705 | "socket2", 706 | "tokio", 707 | "tower-service", 708 | "tracing", 709 | "want", 710 | ] 711 | 712 | [[package]] 713 | name = "iana-time-zone" 714 | version = "0.1.60" 715 | source = "registry+https://github.com/rust-lang/crates.io-index" 716 | checksum = "e7ffbb5a1b541ea2561f8c41c087286cc091e21e556a4f09a8f6cbf17b69b141" 717 | dependencies = [ 718 | "android_system_properties", 719 | "core-foundation-sys", 720 | "iana-time-zone-haiku", 721 | "js-sys", 722 | "wasm-bindgen", 723 | "windows-core", 724 | ] 725 | 726 | [[package]] 727 | name = "iana-time-zone-haiku" 728 | version = "0.1.2" 729 | source = "registry+https://github.com/rust-lang/crates.io-index" 730 | checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" 731 | dependencies = [ 732 | "cc", 733 | ] 734 | 735 | [[package]] 736 | name = "ignore" 737 | version = "0.4.22" 738 | source = "registry+https://github.com/rust-lang/crates.io-index" 739 | checksum = "b46810df39e66e925525d6e38ce1e7f6e1d208f72dc39757880fcb66e2c58af1" 740 | dependencies = [ 741 | "crossbeam-deque", 742 | "globset", 743 | "log", 744 | "memchr", 745 | "regex-automata 0.4.5", 746 | "same-file", 747 | "walkdir", 748 | "winapi-util", 749 | ] 750 | 751 | [[package]] 752 | name = "indexmap" 753 | version = "2.2.3" 754 | source = "registry+https://github.com/rust-lang/crates.io-index" 755 | checksum = "233cf39063f058ea2caae4091bf4a3ef70a653afbc026f5c4a4135d114e3c177" 756 | dependencies = [ 757 | "equivalent", 758 | "hashbrown", 759 | "serde", 760 | ] 761 | 762 | [[package]] 763 | name = "inlinable_string" 764 | version = "0.1.15" 765 | source = "registry+https://github.com/rust-lang/crates.io-index" 766 | checksum = "c8fae54786f62fb2918dcfae3d568594e50eb9b5c25bf04371af6fe7516452fb" 767 | 768 | [[package]] 769 | name = "inotify" 770 | version = "0.9.6" 771 | source = "registry+https://github.com/rust-lang/crates.io-index" 772 | checksum = "f8069d3ec154eb856955c1c0fbffefbf5f3c40a104ec912d4797314c1801abff" 773 | dependencies = [ 774 | "bitflags 1.3.2", 775 | "inotify-sys", 776 | "libc", 777 | ] 778 | 779 | [[package]] 780 | name = "inotify-sys" 781 | version = "0.1.5" 782 | source = "registry+https://github.com/rust-lang/crates.io-index" 783 | checksum = "e05c02b5e89bff3b946cedeca278abc628fe811e604f027c45a8aa3cf793d0eb" 784 | dependencies = [ 785 | "libc", 786 | ] 787 | 788 | [[package]] 789 | name = "is-terminal" 790 | version = "0.4.12" 791 | source = "registry+https://github.com/rust-lang/crates.io-index" 792 | checksum = "f23ff5ef2b80d608d61efee834934d862cd92461afc0560dedf493e4c033738b" 793 | dependencies = [ 794 | "hermit-abi", 795 | "libc", 796 | "windows-sys 0.52.0", 797 | ] 798 | 799 | [[package]] 800 | name = "itoa" 801 | version = "1.0.10" 802 | source = "registry+https://github.com/rust-lang/crates.io-index" 803 | checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c" 804 | 805 | [[package]] 806 | name = "js-sys" 807 | version = "0.3.68" 808 | source = "registry+https://github.com/rust-lang/crates.io-index" 809 | checksum = "406cda4b368d531c842222cf9d2600a9a4acce8d29423695379c6868a143a9ee" 810 | dependencies = [ 811 | "wasm-bindgen", 812 | ] 813 | 814 | [[package]] 815 | name = "kqueue" 816 | version = "1.0.8" 817 | source = "registry+https://github.com/rust-lang/crates.io-index" 818 | checksum = "7447f1ca1b7b563588a205fe93dea8df60fd981423a768bc1c0ded35ed147d0c" 819 | dependencies = [ 820 | "kqueue-sys", 821 | "libc", 822 | ] 823 | 824 | [[package]] 825 | name = "kqueue-sys" 826 | version = "1.0.4" 827 | source = "registry+https://github.com/rust-lang/crates.io-index" 828 | checksum = "ed9625ffda8729b85e45cf04090035ac368927b8cebc34898e7c120f52e4838b" 829 | dependencies = [ 830 | "bitflags 1.3.2", 831 | "libc", 832 | ] 833 | 834 | [[package]] 835 | name = "lazy_static" 836 | version = "1.4.0" 837 | source = "registry+https://github.com/rust-lang/crates.io-index" 838 | checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" 839 | 840 | [[package]] 841 | name = "libc" 842 | version = "0.2.153" 843 | source = "registry+https://github.com/rust-lang/crates.io-index" 844 | checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" 845 | 846 | [[package]] 847 | name = "libm" 848 | version = "0.2.8" 849 | source = "registry+https://github.com/rust-lang/crates.io-index" 850 | checksum = "4ec2a862134d2a7d32d7983ddcdd1c4923530833c9f2ea1a44fc5fa473989058" 851 | 852 | [[package]] 853 | name = "linux-raw-sys" 854 | version = "0.4.13" 855 | source = "registry+https://github.com/rust-lang/crates.io-index" 856 | checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c" 857 | 858 | [[package]] 859 | name = "lock_api" 860 | version = "0.4.11" 861 | source = "registry+https://github.com/rust-lang/crates.io-index" 862 | checksum = "3c168f8615b12bc01f9c17e2eb0cc07dcae1940121185446edc3744920e8ef45" 863 | dependencies = [ 864 | "autocfg", 865 | "scopeguard", 866 | ] 867 | 868 | [[package]] 869 | name = "log" 870 | version = "0.4.20" 871 | source = "registry+https://github.com/rust-lang/crates.io-index" 872 | checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" 873 | 874 | [[package]] 875 | name = "loom" 876 | version = "0.5.6" 877 | source = "registry+https://github.com/rust-lang/crates.io-index" 878 | checksum = "ff50ecb28bb86013e935fb6683ab1f6d3a20016f123c76fd4c27470076ac30f5" 879 | dependencies = [ 880 | "cfg-if", 881 | "generator", 882 | "scoped-tls", 883 | "serde", 884 | "serde_json", 885 | "tracing", 886 | "tracing-subscriber", 887 | ] 888 | 889 | [[package]] 890 | name = "mail-autodiscover-autoconfig" 891 | version = "1.6.1" 892 | dependencies = [ 893 | "addr", 894 | "anyhow", 895 | "chrono", 896 | "dotenv", 897 | "quick-xml", 898 | "rocket", 899 | "rocket_dyn_templates", 900 | "serde", 901 | "serde_json", 902 | "temp-env", 903 | "tera", 904 | "vergen", 905 | ] 906 | 907 | [[package]] 908 | name = "matchers" 909 | version = "0.1.0" 910 | source = "registry+https://github.com/rust-lang/crates.io-index" 911 | checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558" 912 | dependencies = [ 913 | "regex-automata 0.1.10", 914 | ] 915 | 916 | [[package]] 917 | name = "memchr" 918 | version = "2.7.1" 919 | source = "registry+https://github.com/rust-lang/crates.io-index" 920 | checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149" 921 | 922 | [[package]] 923 | name = "mime" 924 | version = "0.3.17" 925 | source = "registry+https://github.com/rust-lang/crates.io-index" 926 | checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" 927 | 928 | [[package]] 929 | name = "miniz_oxide" 930 | version = "0.7.2" 931 | source = "registry+https://github.com/rust-lang/crates.io-index" 932 | checksum = "9d811f3e15f28568be3407c8e7fdb6514c1cda3cb30683f15b6a1a1dc4ea14a7" 933 | dependencies = [ 934 | "adler", 935 | ] 936 | 937 | [[package]] 938 | name = "mio" 939 | version = "0.8.10" 940 | source = "registry+https://github.com/rust-lang/crates.io-index" 941 | checksum = "8f3d0b296e374a4e6f3c7b0a1f5a51d748a0d34c85e7dc48fc3fa9a87657fe09" 942 | dependencies = [ 943 | "libc", 944 | "log", 945 | "wasi", 946 | "windows-sys 0.48.0", 947 | ] 948 | 949 | [[package]] 950 | name = "multer" 951 | version = "2.1.0" 952 | source = "registry+https://github.com/rust-lang/crates.io-index" 953 | checksum = "01acbdc23469fd8fe07ab135923371d5f5a422fbf9c522158677c8eb15bc51c2" 954 | dependencies = [ 955 | "bytes", 956 | "encoding_rs", 957 | "futures-util", 958 | "http", 959 | "httparse", 960 | "log", 961 | "memchr", 962 | "mime", 963 | "spin", 964 | "tokio", 965 | "tokio-util", 966 | "version_check", 967 | ] 968 | 969 | [[package]] 970 | name = "normpath" 971 | version = "1.1.1" 972 | source = "registry+https://github.com/rust-lang/crates.io-index" 973 | checksum = "ec60c60a693226186f5d6edf073232bfb6464ed97eb22cf3b01c1e8198fd97f5" 974 | dependencies = [ 975 | "windows-sys 0.48.0", 976 | ] 977 | 978 | [[package]] 979 | name = "notify" 980 | version = "6.1.1" 981 | source = "registry+https://github.com/rust-lang/crates.io-index" 982 | checksum = "6205bd8bb1e454ad2e27422015fb5e4f2bcc7e08fa8f27058670d208324a4d2d" 983 | dependencies = [ 984 | "bitflags 2.4.2", 985 | "crossbeam-channel", 986 | "filetime", 987 | "fsevent-sys", 988 | "inotify", 989 | "kqueue", 990 | "libc", 991 | "log", 992 | "mio", 993 | "walkdir", 994 | "windows-sys 0.48.0", 995 | ] 996 | 997 | [[package]] 998 | name = "nu-ansi-term" 999 | version = "0.46.0" 1000 | source = "registry+https://github.com/rust-lang/crates.io-index" 1001 | checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84" 1002 | dependencies = [ 1003 | "overload", 1004 | "winapi", 1005 | ] 1006 | 1007 | [[package]] 1008 | name = "num-conv" 1009 | version = "0.1.0" 1010 | source = "registry+https://github.com/rust-lang/crates.io-index" 1011 | checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" 1012 | 1013 | [[package]] 1014 | name = "num-traits" 1015 | version = "0.2.18" 1016 | source = "registry+https://github.com/rust-lang/crates.io-index" 1017 | checksum = "da0df0e5185db44f69b44f26786fe401b6c293d1907744beaa7fa62b2e5a517a" 1018 | dependencies = [ 1019 | "autocfg", 1020 | ] 1021 | 1022 | [[package]] 1023 | name = "num_cpus" 1024 | version = "1.16.0" 1025 | source = "registry+https://github.com/rust-lang/crates.io-index" 1026 | checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" 1027 | dependencies = [ 1028 | "hermit-abi", 1029 | "libc", 1030 | ] 1031 | 1032 | [[package]] 1033 | name = "num_threads" 1034 | version = "0.1.6" 1035 | source = "registry+https://github.com/rust-lang/crates.io-index" 1036 | checksum = "2819ce041d2ee131036f4fc9d6ae7ae125a3a40e97ba64d04fe799ad9dabbb44" 1037 | dependencies = [ 1038 | "libc", 1039 | ] 1040 | 1041 | [[package]] 1042 | name = "object" 1043 | version = "0.32.2" 1044 | source = "registry+https://github.com/rust-lang/crates.io-index" 1045 | checksum = "a6a622008b6e321afc04970976f62ee297fdbaa6f95318ca343e3eebb9648441" 1046 | dependencies = [ 1047 | "memchr", 1048 | ] 1049 | 1050 | [[package]] 1051 | name = "once_cell" 1052 | version = "1.19.0" 1053 | source = "registry+https://github.com/rust-lang/crates.io-index" 1054 | checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" 1055 | 1056 | [[package]] 1057 | name = "overload" 1058 | version = "0.1.1" 1059 | source = "registry+https://github.com/rust-lang/crates.io-index" 1060 | checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" 1061 | 1062 | [[package]] 1063 | name = "parking_lot" 1064 | version = "0.12.1" 1065 | source = "registry+https://github.com/rust-lang/crates.io-index" 1066 | checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" 1067 | dependencies = [ 1068 | "lock_api", 1069 | "parking_lot_core", 1070 | ] 1071 | 1072 | [[package]] 1073 | name = "parking_lot_core" 1074 | version = "0.9.9" 1075 | source = "registry+https://github.com/rust-lang/crates.io-index" 1076 | checksum = "4c42a9226546d68acdd9c0a280d17ce19bfe27a46bf68784e4066115788d008e" 1077 | dependencies = [ 1078 | "cfg-if", 1079 | "libc", 1080 | "redox_syscall", 1081 | "smallvec", 1082 | "windows-targets 0.48.5", 1083 | ] 1084 | 1085 | [[package]] 1086 | name = "parse-zoneinfo" 1087 | version = "0.3.0" 1088 | source = "registry+https://github.com/rust-lang/crates.io-index" 1089 | checksum = "c705f256449c60da65e11ff6626e0c16a0a0b96aaa348de61376b249bc340f41" 1090 | dependencies = [ 1091 | "regex", 1092 | ] 1093 | 1094 | [[package]] 1095 | name = "pear" 1096 | version = "0.2.8" 1097 | source = "registry+https://github.com/rust-lang/crates.io-index" 1098 | checksum = "4ccca0f6c17acc81df8e242ed473ec144cbf5c98037e69aa6d144780aad103c8" 1099 | dependencies = [ 1100 | "inlinable_string", 1101 | "pear_codegen", 1102 | "yansi", 1103 | ] 1104 | 1105 | [[package]] 1106 | name = "pear_codegen" 1107 | version = "0.2.8" 1108 | source = "registry+https://github.com/rust-lang/crates.io-index" 1109 | checksum = "2e22670e8eb757cff11d6c199ca7b987f352f0346e0be4dd23869ec72cb53c77" 1110 | dependencies = [ 1111 | "proc-macro2", 1112 | "proc-macro2-diagnostics", 1113 | "quote", 1114 | "syn", 1115 | ] 1116 | 1117 | [[package]] 1118 | name = "percent-encoding" 1119 | version = "2.3.1" 1120 | source = "registry+https://github.com/rust-lang/crates.io-index" 1121 | checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e" 1122 | 1123 | [[package]] 1124 | name = "pest" 1125 | version = "2.7.7" 1126 | source = "registry+https://github.com/rust-lang/crates.io-index" 1127 | checksum = "219c0dcc30b6a27553f9cc242972b67f75b60eb0db71f0b5462f38b058c41546" 1128 | dependencies = [ 1129 | "memchr", 1130 | "thiserror", 1131 | "ucd-trie", 1132 | ] 1133 | 1134 | [[package]] 1135 | name = "pest_derive" 1136 | version = "2.7.7" 1137 | source = "registry+https://github.com/rust-lang/crates.io-index" 1138 | checksum = "22e1288dbd7786462961e69bfd4df7848c1e37e8b74303dbdab82c3a9cdd2809" 1139 | dependencies = [ 1140 | "pest", 1141 | "pest_generator", 1142 | ] 1143 | 1144 | [[package]] 1145 | name = "pest_generator" 1146 | version = "2.7.7" 1147 | source = "registry+https://github.com/rust-lang/crates.io-index" 1148 | checksum = "1381c29a877c6d34b8c176e734f35d7f7f5b3adaefe940cb4d1bb7af94678e2e" 1149 | dependencies = [ 1150 | "pest", 1151 | "pest_meta", 1152 | "proc-macro2", 1153 | "quote", 1154 | "syn", 1155 | ] 1156 | 1157 | [[package]] 1158 | name = "pest_meta" 1159 | version = "2.7.7" 1160 | source = "registry+https://github.com/rust-lang/crates.io-index" 1161 | checksum = "d0934d6907f148c22a3acbda520c7eed243ad7487a30f51f6ce52b58b7077a8a" 1162 | dependencies = [ 1163 | "once_cell", 1164 | "pest", 1165 | "sha2", 1166 | ] 1167 | 1168 | [[package]] 1169 | name = "phf" 1170 | version = "0.11.2" 1171 | source = "registry+https://github.com/rust-lang/crates.io-index" 1172 | checksum = "ade2d8b8f33c7333b51bcf0428d37e217e9f32192ae4772156f65063b8ce03dc" 1173 | dependencies = [ 1174 | "phf_shared", 1175 | ] 1176 | 1177 | [[package]] 1178 | name = "phf_codegen" 1179 | version = "0.11.2" 1180 | source = "registry+https://github.com/rust-lang/crates.io-index" 1181 | checksum = "e8d39688d359e6b34654d328e262234662d16cc0f60ec8dcbe5e718709342a5a" 1182 | dependencies = [ 1183 | "phf_generator", 1184 | "phf_shared", 1185 | ] 1186 | 1187 | [[package]] 1188 | name = "phf_generator" 1189 | version = "0.11.2" 1190 | source = "registry+https://github.com/rust-lang/crates.io-index" 1191 | checksum = "48e4cc64c2ad9ebe670cb8fd69dd50ae301650392e81c05f9bfcb2d5bdbc24b0" 1192 | dependencies = [ 1193 | "phf_shared", 1194 | "rand", 1195 | ] 1196 | 1197 | [[package]] 1198 | name = "phf_shared" 1199 | version = "0.11.2" 1200 | source = "registry+https://github.com/rust-lang/crates.io-index" 1201 | checksum = "90fcb95eef784c2ac79119d1dd819e162b5da872ce6f3c3abe1e8ca1c082f72b" 1202 | dependencies = [ 1203 | "siphasher", 1204 | ] 1205 | 1206 | [[package]] 1207 | name = "pin-project-lite" 1208 | version = "0.2.13" 1209 | source = "registry+https://github.com/rust-lang/crates.io-index" 1210 | checksum = "8afb450f006bf6385ca15ef45d71d2288452bc3683ce2e2cacc0d18e4be60b58" 1211 | 1212 | [[package]] 1213 | name = "pin-utils" 1214 | version = "0.1.0" 1215 | source = "registry+https://github.com/rust-lang/crates.io-index" 1216 | checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" 1217 | 1218 | [[package]] 1219 | name = "powerfmt" 1220 | version = "0.2.0" 1221 | source = "registry+https://github.com/rust-lang/crates.io-index" 1222 | checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" 1223 | 1224 | [[package]] 1225 | name = "ppv-lite86" 1226 | version = "0.2.17" 1227 | source = "registry+https://github.com/rust-lang/crates.io-index" 1228 | checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" 1229 | 1230 | [[package]] 1231 | name = "proc-macro2" 1232 | version = "1.0.78" 1233 | source = "registry+https://github.com/rust-lang/crates.io-index" 1234 | checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" 1235 | dependencies = [ 1236 | "unicode-ident", 1237 | ] 1238 | 1239 | [[package]] 1240 | name = "proc-macro2-diagnostics" 1241 | version = "0.10.1" 1242 | source = "registry+https://github.com/rust-lang/crates.io-index" 1243 | checksum = "af066a9c399a26e020ada66a034357a868728e72cd426f3adcd35f80d88d88c8" 1244 | dependencies = [ 1245 | "proc-macro2", 1246 | "quote", 1247 | "syn", 1248 | "version_check", 1249 | "yansi", 1250 | ] 1251 | 1252 | [[package]] 1253 | name = "psl" 1254 | version = "2.1.24" 1255 | source = "registry+https://github.com/rust-lang/crates.io-index" 1256 | checksum = "a54ee59b05281c3f036c04aedf36d8ea5f0a50071cc66529503e1c650469fac0" 1257 | dependencies = [ 1258 | "psl-types", 1259 | ] 1260 | 1261 | [[package]] 1262 | name = "psl-types" 1263 | version = "2.0.11" 1264 | source = "registry+https://github.com/rust-lang/crates.io-index" 1265 | checksum = "33cb294fe86a74cbcf50d4445b37da762029549ebeea341421c7c70370f86cac" 1266 | 1267 | [[package]] 1268 | name = "quick-xml" 1269 | version = "0.31.0" 1270 | source = "registry+https://github.com/rust-lang/crates.io-index" 1271 | checksum = "1004a344b30a54e2ee58d66a71b32d2db2feb0a31f9a2d302bf0536f15de2a33" 1272 | dependencies = [ 1273 | "memchr", 1274 | "serde", 1275 | ] 1276 | 1277 | [[package]] 1278 | name = "quote" 1279 | version = "1.0.35" 1280 | source = "registry+https://github.com/rust-lang/crates.io-index" 1281 | checksum = "291ec9ab5efd934aaf503a6466c5d5251535d108ee747472c3977cc5acc868ef" 1282 | dependencies = [ 1283 | "proc-macro2", 1284 | ] 1285 | 1286 | [[package]] 1287 | name = "rand" 1288 | version = "0.8.5" 1289 | source = "registry+https://github.com/rust-lang/crates.io-index" 1290 | checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" 1291 | dependencies = [ 1292 | "libc", 1293 | "rand_chacha", 1294 | "rand_core", 1295 | ] 1296 | 1297 | [[package]] 1298 | name = "rand_chacha" 1299 | version = "0.3.1" 1300 | source = "registry+https://github.com/rust-lang/crates.io-index" 1301 | checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" 1302 | dependencies = [ 1303 | "ppv-lite86", 1304 | "rand_core", 1305 | ] 1306 | 1307 | [[package]] 1308 | name = "rand_core" 1309 | version = "0.6.4" 1310 | source = "registry+https://github.com/rust-lang/crates.io-index" 1311 | checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" 1312 | dependencies = [ 1313 | "getrandom", 1314 | ] 1315 | 1316 | [[package]] 1317 | name = "redox_syscall" 1318 | version = "0.4.1" 1319 | source = "registry+https://github.com/rust-lang/crates.io-index" 1320 | checksum = "4722d768eff46b75989dd134e5c353f0d6296e5aaa3132e776cbdb56be7731aa" 1321 | dependencies = [ 1322 | "bitflags 1.3.2", 1323 | ] 1324 | 1325 | [[package]] 1326 | name = "ref-cast" 1327 | version = "1.0.22" 1328 | source = "registry+https://github.com/rust-lang/crates.io-index" 1329 | checksum = "c4846d4c50d1721b1a3bef8af76924eef20d5e723647333798c1b519b3a9473f" 1330 | dependencies = [ 1331 | "ref-cast-impl", 1332 | ] 1333 | 1334 | [[package]] 1335 | name = "ref-cast-impl" 1336 | version = "1.0.22" 1337 | source = "registry+https://github.com/rust-lang/crates.io-index" 1338 | checksum = "5fddb4f8d99b0a2ebafc65a87a69a7b9875e4b1ae1f00db265d300ef7f28bccc" 1339 | dependencies = [ 1340 | "proc-macro2", 1341 | "quote", 1342 | "syn", 1343 | ] 1344 | 1345 | [[package]] 1346 | name = "regex" 1347 | version = "1.10.3" 1348 | source = "registry+https://github.com/rust-lang/crates.io-index" 1349 | checksum = "b62dbe01f0b06f9d8dc7d49e05a0785f153b00b2c227856282f671e0318c9b15" 1350 | dependencies = [ 1351 | "aho-corasick", 1352 | "memchr", 1353 | "regex-automata 0.4.5", 1354 | "regex-syntax 0.8.2", 1355 | ] 1356 | 1357 | [[package]] 1358 | name = "regex-automata" 1359 | version = "0.1.10" 1360 | source = "registry+https://github.com/rust-lang/crates.io-index" 1361 | checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" 1362 | dependencies = [ 1363 | "regex-syntax 0.6.29", 1364 | ] 1365 | 1366 | [[package]] 1367 | name = "regex-automata" 1368 | version = "0.4.5" 1369 | source = "registry+https://github.com/rust-lang/crates.io-index" 1370 | checksum = "5bb987efffd3c6d0d8f5f89510bb458559eab11e4f869acb20bf845e016259cd" 1371 | dependencies = [ 1372 | "aho-corasick", 1373 | "memchr", 1374 | "regex-syntax 0.8.2", 1375 | ] 1376 | 1377 | [[package]] 1378 | name = "regex-syntax" 1379 | version = "0.6.29" 1380 | source = "registry+https://github.com/rust-lang/crates.io-index" 1381 | checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1" 1382 | 1383 | [[package]] 1384 | name = "regex-syntax" 1385 | version = "0.8.2" 1386 | source = "registry+https://github.com/rust-lang/crates.io-index" 1387 | checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" 1388 | 1389 | [[package]] 1390 | name = "rocket" 1391 | version = "0.5.0" 1392 | source = "registry+https://github.com/rust-lang/crates.io-index" 1393 | checksum = "9e7bb57ccb26670d73b6a47396c83139447b9e7878cab627fdfe9ea8da489150" 1394 | dependencies = [ 1395 | "async-stream", 1396 | "async-trait", 1397 | "atomic 0.5.3", 1398 | "binascii", 1399 | "bytes", 1400 | "either", 1401 | "figment", 1402 | "futures", 1403 | "indexmap", 1404 | "log", 1405 | "memchr", 1406 | "multer", 1407 | "num_cpus", 1408 | "parking_lot", 1409 | "pin-project-lite", 1410 | "rand", 1411 | "ref-cast", 1412 | "rocket_codegen", 1413 | "rocket_http", 1414 | "serde", 1415 | "serde_json", 1416 | "state", 1417 | "tempfile", 1418 | "time", 1419 | "tokio", 1420 | "tokio-stream", 1421 | "tokio-util", 1422 | "ubyte", 1423 | "version_check", 1424 | "yansi", 1425 | ] 1426 | 1427 | [[package]] 1428 | name = "rocket_codegen" 1429 | version = "0.5.0" 1430 | source = "registry+https://github.com/rust-lang/crates.io-index" 1431 | checksum = "a2238066abf75f21be6cd7dc1a09d5414a671f4246e384e49fe3f8a4936bd04c" 1432 | dependencies = [ 1433 | "devise", 1434 | "glob", 1435 | "indexmap", 1436 | "proc-macro2", 1437 | "quote", 1438 | "rocket_http", 1439 | "syn", 1440 | "unicode-xid", 1441 | "version_check", 1442 | ] 1443 | 1444 | [[package]] 1445 | name = "rocket_dyn_templates" 1446 | version = "0.1.0" 1447 | source = "registry+https://github.com/rust-lang/crates.io-index" 1448 | checksum = "04bfc006e547e4f72b760ab861f5943b688aed8a82c4977b5500c98f5d17dbfa" 1449 | dependencies = [ 1450 | "normpath", 1451 | "notify", 1452 | "rocket", 1453 | "tera", 1454 | "walkdir", 1455 | ] 1456 | 1457 | [[package]] 1458 | name = "rocket_http" 1459 | version = "0.5.0" 1460 | source = "registry+https://github.com/rust-lang/crates.io-index" 1461 | checksum = "37a1663694d059fe5f943ea5481363e48050acedd241d46deb2e27f71110389e" 1462 | dependencies = [ 1463 | "cookie", 1464 | "either", 1465 | "futures", 1466 | "http", 1467 | "hyper", 1468 | "indexmap", 1469 | "log", 1470 | "memchr", 1471 | "pear", 1472 | "percent-encoding", 1473 | "pin-project-lite", 1474 | "ref-cast", 1475 | "serde", 1476 | "smallvec", 1477 | "stable-pattern", 1478 | "state", 1479 | "time", 1480 | "tokio", 1481 | "uncased", 1482 | ] 1483 | 1484 | [[package]] 1485 | name = "rustc-demangle" 1486 | version = "0.1.23" 1487 | source = "registry+https://github.com/rust-lang/crates.io-index" 1488 | checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" 1489 | 1490 | [[package]] 1491 | name = "rustc_version" 1492 | version = "0.4.0" 1493 | source = "registry+https://github.com/rust-lang/crates.io-index" 1494 | checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" 1495 | dependencies = [ 1496 | "semver", 1497 | ] 1498 | 1499 | [[package]] 1500 | name = "rustix" 1501 | version = "0.38.31" 1502 | source = "registry+https://github.com/rust-lang/crates.io-index" 1503 | checksum = "6ea3e1a662af26cd7a3ba09c0297a31af215563ecf42817c98df621387f4e949" 1504 | dependencies = [ 1505 | "bitflags 2.4.2", 1506 | "errno", 1507 | "libc", 1508 | "linux-raw-sys", 1509 | "windows-sys 0.52.0", 1510 | ] 1511 | 1512 | [[package]] 1513 | name = "rustversion" 1514 | version = "1.0.14" 1515 | source = "registry+https://github.com/rust-lang/crates.io-index" 1516 | checksum = "7ffc183a10b4478d04cbbbfc96d0873219d962dd5accaff2ffbd4ceb7df837f4" 1517 | 1518 | [[package]] 1519 | name = "ryu" 1520 | version = "1.0.16" 1521 | source = "registry+https://github.com/rust-lang/crates.io-index" 1522 | checksum = "f98d2aa92eebf49b69786be48e4477826b256916e84a57ff2a4f21923b48eb4c" 1523 | 1524 | [[package]] 1525 | name = "same-file" 1526 | version = "1.0.6" 1527 | source = "registry+https://github.com/rust-lang/crates.io-index" 1528 | checksum = "93fc1dc3aaa9bfed95e02e6eadabb4baf7e3078b0bd1b4d7b6b0b68378900502" 1529 | dependencies = [ 1530 | "winapi-util", 1531 | ] 1532 | 1533 | [[package]] 1534 | name = "scoped-tls" 1535 | version = "1.0.1" 1536 | source = "registry+https://github.com/rust-lang/crates.io-index" 1537 | checksum = "e1cf6437eb19a8f4a6cc0f7dca544973b0b78843adbfeb3683d1a94a0024a294" 1538 | 1539 | [[package]] 1540 | name = "scopeguard" 1541 | version = "1.2.0" 1542 | source = "registry+https://github.com/rust-lang/crates.io-index" 1543 | checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" 1544 | 1545 | [[package]] 1546 | name = "semver" 1547 | version = "1.0.21" 1548 | source = "registry+https://github.com/rust-lang/crates.io-index" 1549 | checksum = "b97ed7a9823b74f99c7742f5336af7be5ecd3eeafcb1507d1fa93347b1d589b0" 1550 | dependencies = [ 1551 | "serde", 1552 | ] 1553 | 1554 | [[package]] 1555 | name = "serde" 1556 | version = "1.0.196" 1557 | source = "registry+https://github.com/rust-lang/crates.io-index" 1558 | checksum = "870026e60fa08c69f064aa766c10f10b1d62db9ccd4d0abb206472bee0ce3b32" 1559 | dependencies = [ 1560 | "serde_derive", 1561 | ] 1562 | 1563 | [[package]] 1564 | name = "serde_derive" 1565 | version = "1.0.196" 1566 | source = "registry+https://github.com/rust-lang/crates.io-index" 1567 | checksum = "33c85360c95e7d137454dc81d9a4ed2b8efd8fbe19cee57357b32b9771fccb67" 1568 | dependencies = [ 1569 | "proc-macro2", 1570 | "quote", 1571 | "syn", 1572 | ] 1573 | 1574 | [[package]] 1575 | name = "serde_json" 1576 | version = "1.0.113" 1577 | source = "registry+https://github.com/rust-lang/crates.io-index" 1578 | checksum = "69801b70b1c3dac963ecb03a364ba0ceda9cf60c71cfe475e99864759c8b8a79" 1579 | dependencies = [ 1580 | "itoa", 1581 | "ryu", 1582 | "serde", 1583 | ] 1584 | 1585 | [[package]] 1586 | name = "serde_spanned" 1587 | version = "0.6.5" 1588 | source = "registry+https://github.com/rust-lang/crates.io-index" 1589 | checksum = "eb3622f419d1296904700073ea6cc23ad690adbd66f13ea683df73298736f0c1" 1590 | dependencies = [ 1591 | "serde", 1592 | ] 1593 | 1594 | [[package]] 1595 | name = "sha2" 1596 | version = "0.10.8" 1597 | source = "registry+https://github.com/rust-lang/crates.io-index" 1598 | checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" 1599 | dependencies = [ 1600 | "cfg-if", 1601 | "cpufeatures", 1602 | "digest", 1603 | ] 1604 | 1605 | [[package]] 1606 | name = "sharded-slab" 1607 | version = "0.1.7" 1608 | source = "registry+https://github.com/rust-lang/crates.io-index" 1609 | checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" 1610 | dependencies = [ 1611 | "lazy_static", 1612 | ] 1613 | 1614 | [[package]] 1615 | name = "signal-hook-registry" 1616 | version = "1.4.1" 1617 | source = "registry+https://github.com/rust-lang/crates.io-index" 1618 | checksum = "d8229b473baa5980ac72ef434c4415e70c4b5e71b423043adb4ba059f89c99a1" 1619 | dependencies = [ 1620 | "libc", 1621 | ] 1622 | 1623 | [[package]] 1624 | name = "siphasher" 1625 | version = "0.3.11" 1626 | source = "registry+https://github.com/rust-lang/crates.io-index" 1627 | checksum = "38b58827f4464d87d377d175e90bf58eb00fd8716ff0a62f80356b5e61555d0d" 1628 | 1629 | [[package]] 1630 | name = "slab" 1631 | version = "0.4.9" 1632 | source = "registry+https://github.com/rust-lang/crates.io-index" 1633 | checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67" 1634 | dependencies = [ 1635 | "autocfg", 1636 | ] 1637 | 1638 | [[package]] 1639 | name = "slug" 1640 | version = "0.1.5" 1641 | source = "registry+https://github.com/rust-lang/crates.io-index" 1642 | checksum = "3bd94acec9c8da640005f8e135a39fc0372e74535e6b368b7a04b875f784c8c4" 1643 | dependencies = [ 1644 | "deunicode", 1645 | "wasm-bindgen", 1646 | ] 1647 | 1648 | [[package]] 1649 | name = "smallvec" 1650 | version = "1.13.1" 1651 | source = "registry+https://github.com/rust-lang/crates.io-index" 1652 | checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7" 1653 | 1654 | [[package]] 1655 | name = "socket2" 1656 | version = "0.5.5" 1657 | source = "registry+https://github.com/rust-lang/crates.io-index" 1658 | checksum = "7b5fac59a5cb5dd637972e5fca70daf0523c9067fcdc4842f053dae04a18f8e9" 1659 | dependencies = [ 1660 | "libc", 1661 | "windows-sys 0.48.0", 1662 | ] 1663 | 1664 | [[package]] 1665 | name = "spin" 1666 | version = "0.9.8" 1667 | source = "registry+https://github.com/rust-lang/crates.io-index" 1668 | checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" 1669 | 1670 | [[package]] 1671 | name = "stable-pattern" 1672 | version = "0.1.0" 1673 | source = "registry+https://github.com/rust-lang/crates.io-index" 1674 | checksum = "4564168c00635f88eaed410d5efa8131afa8d8699a612c80c455a0ba05c21045" 1675 | dependencies = [ 1676 | "memchr", 1677 | ] 1678 | 1679 | [[package]] 1680 | name = "state" 1681 | version = "0.6.0" 1682 | source = "registry+https://github.com/rust-lang/crates.io-index" 1683 | checksum = "2b8c4a4445d81357df8b1a650d0d0d6fbbbfe99d064aa5e02f3e4022061476d8" 1684 | dependencies = [ 1685 | "loom", 1686 | ] 1687 | 1688 | [[package]] 1689 | name = "syn" 1690 | version = "2.0.48" 1691 | source = "registry+https://github.com/rust-lang/crates.io-index" 1692 | checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f" 1693 | dependencies = [ 1694 | "proc-macro2", 1695 | "quote", 1696 | "unicode-ident", 1697 | ] 1698 | 1699 | [[package]] 1700 | name = "temp-env" 1701 | version = "0.3.6" 1702 | source = "registry+https://github.com/rust-lang/crates.io-index" 1703 | checksum = "96374855068f47402c3121c6eed88d29cb1de8f3ab27090e273e420bdabcf050" 1704 | dependencies = [ 1705 | "parking_lot", 1706 | ] 1707 | 1708 | [[package]] 1709 | name = "tempfile" 1710 | version = "3.10.0" 1711 | source = "registry+https://github.com/rust-lang/crates.io-index" 1712 | checksum = "a365e8cd18e44762ef95d87f284f4b5cd04107fec2ff3052bd6a3e6069669e67" 1713 | dependencies = [ 1714 | "cfg-if", 1715 | "fastrand", 1716 | "rustix", 1717 | "windows-sys 0.52.0", 1718 | ] 1719 | 1720 | [[package]] 1721 | name = "tera" 1722 | version = "1.19.1" 1723 | source = "registry+https://github.com/rust-lang/crates.io-index" 1724 | checksum = "970dff17c11e884a4a09bc76e3a17ef71e01bb13447a11e85226e254fe6d10b8" 1725 | dependencies = [ 1726 | "chrono", 1727 | "chrono-tz", 1728 | "globwalk", 1729 | "humansize", 1730 | "lazy_static", 1731 | "percent-encoding", 1732 | "pest", 1733 | "pest_derive", 1734 | "rand", 1735 | "regex", 1736 | "serde", 1737 | "serde_json", 1738 | "slug", 1739 | "unic-segment", 1740 | ] 1741 | 1742 | [[package]] 1743 | name = "thiserror" 1744 | version = "1.0.57" 1745 | source = "registry+https://github.com/rust-lang/crates.io-index" 1746 | checksum = "1e45bcbe8ed29775f228095caf2cd67af7a4ccf756ebff23a306bf3e8b47b24b" 1747 | dependencies = [ 1748 | "thiserror-impl", 1749 | ] 1750 | 1751 | [[package]] 1752 | name = "thiserror-impl" 1753 | version = "1.0.57" 1754 | source = "registry+https://github.com/rust-lang/crates.io-index" 1755 | checksum = "a953cb265bef375dae3de6663da4d3804eee9682ea80d8e2542529b73c531c81" 1756 | dependencies = [ 1757 | "proc-macro2", 1758 | "quote", 1759 | "syn", 1760 | ] 1761 | 1762 | [[package]] 1763 | name = "thread_local" 1764 | version = "1.1.7" 1765 | source = "registry+https://github.com/rust-lang/crates.io-index" 1766 | checksum = "3fdd6f064ccff2d6567adcb3873ca630700f00b5ad3f060c25b5dcfd9a4ce152" 1767 | dependencies = [ 1768 | "cfg-if", 1769 | "once_cell", 1770 | ] 1771 | 1772 | [[package]] 1773 | name = "time" 1774 | version = "0.3.34" 1775 | source = "registry+https://github.com/rust-lang/crates.io-index" 1776 | checksum = "c8248b6521bb14bc45b4067159b9b6ad792e2d6d754d6c41fb50e29fefe38749" 1777 | dependencies = [ 1778 | "deranged", 1779 | "itoa", 1780 | "libc", 1781 | "num-conv", 1782 | "num_threads", 1783 | "powerfmt", 1784 | "serde", 1785 | "time-core", 1786 | "time-macros", 1787 | ] 1788 | 1789 | [[package]] 1790 | name = "time-core" 1791 | version = "0.1.2" 1792 | source = "registry+https://github.com/rust-lang/crates.io-index" 1793 | checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" 1794 | 1795 | [[package]] 1796 | name = "time-macros" 1797 | version = "0.2.17" 1798 | source = "registry+https://github.com/rust-lang/crates.io-index" 1799 | checksum = "7ba3a3ef41e6672a2f0f001392bb5dcd3ff0a9992d618ca761a11c3121547774" 1800 | dependencies = [ 1801 | "num-conv", 1802 | "time-core", 1803 | ] 1804 | 1805 | [[package]] 1806 | name = "tokio" 1807 | version = "1.36.0" 1808 | source = "registry+https://github.com/rust-lang/crates.io-index" 1809 | checksum = "61285f6515fa018fb2d1e46eb21223fff441ee8db5d0f1435e8ab4f5cdb80931" 1810 | dependencies = [ 1811 | "backtrace", 1812 | "bytes", 1813 | "libc", 1814 | "mio", 1815 | "num_cpus", 1816 | "pin-project-lite", 1817 | "signal-hook-registry", 1818 | "socket2", 1819 | "tokio-macros", 1820 | "windows-sys 0.48.0", 1821 | ] 1822 | 1823 | [[package]] 1824 | name = "tokio-macros" 1825 | version = "2.2.0" 1826 | source = "registry+https://github.com/rust-lang/crates.io-index" 1827 | checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" 1828 | dependencies = [ 1829 | "proc-macro2", 1830 | "quote", 1831 | "syn", 1832 | ] 1833 | 1834 | [[package]] 1835 | name = "tokio-stream" 1836 | version = "0.1.14" 1837 | source = "registry+https://github.com/rust-lang/crates.io-index" 1838 | checksum = "397c988d37662c7dda6d2208364a706264bf3d6138b11d436cbac0ad38832842" 1839 | dependencies = [ 1840 | "futures-core", 1841 | "pin-project-lite", 1842 | "tokio", 1843 | ] 1844 | 1845 | [[package]] 1846 | name = "tokio-util" 1847 | version = "0.7.10" 1848 | source = "registry+https://github.com/rust-lang/crates.io-index" 1849 | checksum = "5419f34732d9eb6ee4c3578b7989078579b7f039cbbb9ca2c4da015749371e15" 1850 | dependencies = [ 1851 | "bytes", 1852 | "futures-core", 1853 | "futures-sink", 1854 | "pin-project-lite", 1855 | "tokio", 1856 | "tracing", 1857 | ] 1858 | 1859 | [[package]] 1860 | name = "toml" 1861 | version = "0.8.10" 1862 | source = "registry+https://github.com/rust-lang/crates.io-index" 1863 | checksum = "9a9aad4a3066010876e8dcf5a8a06e70a558751117a145c6ce2b82c2e2054290" 1864 | dependencies = [ 1865 | "serde", 1866 | "serde_spanned", 1867 | "toml_datetime", 1868 | "toml_edit", 1869 | ] 1870 | 1871 | [[package]] 1872 | name = "toml_datetime" 1873 | version = "0.6.5" 1874 | source = "registry+https://github.com/rust-lang/crates.io-index" 1875 | checksum = "3550f4e9685620ac18a50ed434eb3aec30db8ba93b0287467bca5826ea25baf1" 1876 | dependencies = [ 1877 | "serde", 1878 | ] 1879 | 1880 | [[package]] 1881 | name = "toml_edit" 1882 | version = "0.22.4" 1883 | source = "registry+https://github.com/rust-lang/crates.io-index" 1884 | checksum = "0c9ffdf896f8daaabf9b66ba8e77ea1ed5ed0f72821b398aba62352e95062951" 1885 | dependencies = [ 1886 | "indexmap", 1887 | "serde", 1888 | "serde_spanned", 1889 | "toml_datetime", 1890 | "winnow", 1891 | ] 1892 | 1893 | [[package]] 1894 | name = "tower-service" 1895 | version = "0.3.2" 1896 | source = "registry+https://github.com/rust-lang/crates.io-index" 1897 | checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" 1898 | 1899 | [[package]] 1900 | name = "tracing" 1901 | version = "0.1.40" 1902 | source = "registry+https://github.com/rust-lang/crates.io-index" 1903 | checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" 1904 | dependencies = [ 1905 | "pin-project-lite", 1906 | "tracing-attributes", 1907 | "tracing-core", 1908 | ] 1909 | 1910 | [[package]] 1911 | name = "tracing-attributes" 1912 | version = "0.1.27" 1913 | source = "registry+https://github.com/rust-lang/crates.io-index" 1914 | checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" 1915 | dependencies = [ 1916 | "proc-macro2", 1917 | "quote", 1918 | "syn", 1919 | ] 1920 | 1921 | [[package]] 1922 | name = "tracing-core" 1923 | version = "0.1.32" 1924 | source = "registry+https://github.com/rust-lang/crates.io-index" 1925 | checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" 1926 | dependencies = [ 1927 | "once_cell", 1928 | "valuable", 1929 | ] 1930 | 1931 | [[package]] 1932 | name = "tracing-log" 1933 | version = "0.2.0" 1934 | source = "registry+https://github.com/rust-lang/crates.io-index" 1935 | checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3" 1936 | dependencies = [ 1937 | "log", 1938 | "once_cell", 1939 | "tracing-core", 1940 | ] 1941 | 1942 | [[package]] 1943 | name = "tracing-subscriber" 1944 | version = "0.3.18" 1945 | source = "registry+https://github.com/rust-lang/crates.io-index" 1946 | checksum = "ad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8b" 1947 | dependencies = [ 1948 | "matchers", 1949 | "nu-ansi-term", 1950 | "once_cell", 1951 | "regex", 1952 | "sharded-slab", 1953 | "smallvec", 1954 | "thread_local", 1955 | "tracing", 1956 | "tracing-core", 1957 | "tracing-log", 1958 | ] 1959 | 1960 | [[package]] 1961 | name = "try-lock" 1962 | version = "0.2.5" 1963 | source = "registry+https://github.com/rust-lang/crates.io-index" 1964 | checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" 1965 | 1966 | [[package]] 1967 | name = "typenum" 1968 | version = "1.17.0" 1969 | source = "registry+https://github.com/rust-lang/crates.io-index" 1970 | checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" 1971 | 1972 | [[package]] 1973 | name = "ubyte" 1974 | version = "0.10.4" 1975 | source = "registry+https://github.com/rust-lang/crates.io-index" 1976 | checksum = "f720def6ce1ee2fc44d40ac9ed6d3a59c361c80a75a7aa8e75bb9baed31cf2ea" 1977 | dependencies = [ 1978 | "serde", 1979 | ] 1980 | 1981 | [[package]] 1982 | name = "ucd-trie" 1983 | version = "0.1.6" 1984 | source = "registry+https://github.com/rust-lang/crates.io-index" 1985 | checksum = "ed646292ffc8188ef8ea4d1e0e0150fb15a5c2e12ad9b8fc191ae7a8a7f3c4b9" 1986 | 1987 | [[package]] 1988 | name = "uncased" 1989 | version = "0.9.10" 1990 | source = "registry+https://github.com/rust-lang/crates.io-index" 1991 | checksum = "e1b88fcfe09e89d3866a5c11019378088af2d24c3fbd4f0543f96b479ec90697" 1992 | dependencies = [ 1993 | "serde", 1994 | "version_check", 1995 | ] 1996 | 1997 | [[package]] 1998 | name = "unic-char-property" 1999 | version = "0.9.0" 2000 | source = "registry+https://github.com/rust-lang/crates.io-index" 2001 | checksum = "a8c57a407d9b6fa02b4795eb81c5b6652060a15a7903ea981f3d723e6c0be221" 2002 | dependencies = [ 2003 | "unic-char-range", 2004 | ] 2005 | 2006 | [[package]] 2007 | name = "unic-char-range" 2008 | version = "0.9.0" 2009 | source = "registry+https://github.com/rust-lang/crates.io-index" 2010 | checksum = "0398022d5f700414f6b899e10b8348231abf9173fa93144cbc1a43b9793c1fbc" 2011 | 2012 | [[package]] 2013 | name = "unic-common" 2014 | version = "0.9.0" 2015 | source = "registry+https://github.com/rust-lang/crates.io-index" 2016 | checksum = "80d7ff825a6a654ee85a63e80f92f054f904f21e7d12da4e22f9834a4aaa35bc" 2017 | 2018 | [[package]] 2019 | name = "unic-segment" 2020 | version = "0.9.0" 2021 | source = "registry+https://github.com/rust-lang/crates.io-index" 2022 | checksum = "e4ed5d26be57f84f176157270c112ef57b86debac9cd21daaabbe56db0f88f23" 2023 | dependencies = [ 2024 | "unic-ucd-segment", 2025 | ] 2026 | 2027 | [[package]] 2028 | name = "unic-ucd-segment" 2029 | version = "0.9.0" 2030 | source = "registry+https://github.com/rust-lang/crates.io-index" 2031 | checksum = "2079c122a62205b421f499da10f3ee0f7697f012f55b675e002483c73ea34700" 2032 | dependencies = [ 2033 | "unic-char-property", 2034 | "unic-char-range", 2035 | "unic-ucd-version", 2036 | ] 2037 | 2038 | [[package]] 2039 | name = "unic-ucd-version" 2040 | version = "0.9.0" 2041 | source = "registry+https://github.com/rust-lang/crates.io-index" 2042 | checksum = "96bd2f2237fe450fcd0a1d2f5f4e91711124f7857ba2e964247776ebeeb7b0c4" 2043 | dependencies = [ 2044 | "unic-common", 2045 | ] 2046 | 2047 | [[package]] 2048 | name = "unicode-ident" 2049 | version = "1.0.12" 2050 | source = "registry+https://github.com/rust-lang/crates.io-index" 2051 | checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" 2052 | 2053 | [[package]] 2054 | name = "unicode-xid" 2055 | version = "0.2.4" 2056 | source = "registry+https://github.com/rust-lang/crates.io-index" 2057 | checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c" 2058 | 2059 | [[package]] 2060 | name = "valuable" 2061 | version = "0.1.0" 2062 | source = "registry+https://github.com/rust-lang/crates.io-index" 2063 | checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" 2064 | 2065 | [[package]] 2066 | name = "vergen" 2067 | version = "8.3.1" 2068 | source = "registry+https://github.com/rust-lang/crates.io-index" 2069 | checksum = "e27d6bdd219887a9eadd19e1c34f32e47fa332301184935c6d9bca26f3cca525" 2070 | dependencies = [ 2071 | "anyhow", 2072 | "cargo_metadata", 2073 | "cfg-if", 2074 | "regex", 2075 | "rustc_version", 2076 | "rustversion", 2077 | "time", 2078 | ] 2079 | 2080 | [[package]] 2081 | name = "version_check" 2082 | version = "0.9.4" 2083 | source = "registry+https://github.com/rust-lang/crates.io-index" 2084 | checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" 2085 | 2086 | [[package]] 2087 | name = "walkdir" 2088 | version = "2.4.0" 2089 | source = "registry+https://github.com/rust-lang/crates.io-index" 2090 | checksum = "d71d857dc86794ca4c280d616f7da00d2dbfd8cd788846559a6813e6aa4b54ee" 2091 | dependencies = [ 2092 | "same-file", 2093 | "winapi-util", 2094 | ] 2095 | 2096 | [[package]] 2097 | name = "want" 2098 | version = "0.3.1" 2099 | source = "registry+https://github.com/rust-lang/crates.io-index" 2100 | checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" 2101 | dependencies = [ 2102 | "try-lock", 2103 | ] 2104 | 2105 | [[package]] 2106 | name = "wasi" 2107 | version = "0.11.0+wasi-snapshot-preview1" 2108 | source = "registry+https://github.com/rust-lang/crates.io-index" 2109 | checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" 2110 | 2111 | [[package]] 2112 | name = "wasm-bindgen" 2113 | version = "0.2.91" 2114 | source = "registry+https://github.com/rust-lang/crates.io-index" 2115 | checksum = "c1e124130aee3fb58c5bdd6b639a0509486b0338acaaae0c84a5124b0f588b7f" 2116 | dependencies = [ 2117 | "cfg-if", 2118 | "wasm-bindgen-macro", 2119 | ] 2120 | 2121 | [[package]] 2122 | name = "wasm-bindgen-backend" 2123 | version = "0.2.91" 2124 | source = "registry+https://github.com/rust-lang/crates.io-index" 2125 | checksum = "c9e7e1900c352b609c8488ad12639a311045f40a35491fb69ba8c12f758af70b" 2126 | dependencies = [ 2127 | "bumpalo", 2128 | "log", 2129 | "once_cell", 2130 | "proc-macro2", 2131 | "quote", 2132 | "syn", 2133 | "wasm-bindgen-shared", 2134 | ] 2135 | 2136 | [[package]] 2137 | name = "wasm-bindgen-macro" 2138 | version = "0.2.91" 2139 | source = "registry+https://github.com/rust-lang/crates.io-index" 2140 | checksum = "b30af9e2d358182b5c7449424f017eba305ed32a7010509ede96cdc4696c46ed" 2141 | dependencies = [ 2142 | "quote", 2143 | "wasm-bindgen-macro-support", 2144 | ] 2145 | 2146 | [[package]] 2147 | name = "wasm-bindgen-macro-support" 2148 | version = "0.2.91" 2149 | source = "registry+https://github.com/rust-lang/crates.io-index" 2150 | checksum = "642f325be6301eb8107a83d12a8ac6c1e1c54345a7ef1a9261962dfefda09e66" 2151 | dependencies = [ 2152 | "proc-macro2", 2153 | "quote", 2154 | "syn", 2155 | "wasm-bindgen-backend", 2156 | "wasm-bindgen-shared", 2157 | ] 2158 | 2159 | [[package]] 2160 | name = "wasm-bindgen-shared" 2161 | version = "0.2.91" 2162 | source = "registry+https://github.com/rust-lang/crates.io-index" 2163 | checksum = "4f186bd2dcf04330886ce82d6f33dd75a7bfcf69ecf5763b89fcde53b6ac9838" 2164 | 2165 | [[package]] 2166 | name = "winapi" 2167 | version = "0.3.9" 2168 | source = "registry+https://github.com/rust-lang/crates.io-index" 2169 | checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" 2170 | dependencies = [ 2171 | "winapi-i686-pc-windows-gnu", 2172 | "winapi-x86_64-pc-windows-gnu", 2173 | ] 2174 | 2175 | [[package]] 2176 | name = "winapi-i686-pc-windows-gnu" 2177 | version = "0.4.0" 2178 | source = "registry+https://github.com/rust-lang/crates.io-index" 2179 | checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" 2180 | 2181 | [[package]] 2182 | name = "winapi-util" 2183 | version = "0.1.6" 2184 | source = "registry+https://github.com/rust-lang/crates.io-index" 2185 | checksum = "f29e6f9198ba0d26b4c9f07dbe6f9ed633e1f3d5b8b414090084349e46a52596" 2186 | dependencies = [ 2187 | "winapi", 2188 | ] 2189 | 2190 | [[package]] 2191 | name = "winapi-x86_64-pc-windows-gnu" 2192 | version = "0.4.0" 2193 | source = "registry+https://github.com/rust-lang/crates.io-index" 2194 | checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" 2195 | 2196 | [[package]] 2197 | name = "windows" 2198 | version = "0.48.0" 2199 | source = "registry+https://github.com/rust-lang/crates.io-index" 2200 | checksum = "e686886bc078bc1b0b600cac0147aadb815089b6e4da64016cbd754b6342700f" 2201 | dependencies = [ 2202 | "windows-targets 0.48.5", 2203 | ] 2204 | 2205 | [[package]] 2206 | name = "windows-core" 2207 | version = "0.52.0" 2208 | source = "registry+https://github.com/rust-lang/crates.io-index" 2209 | checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" 2210 | dependencies = [ 2211 | "windows-targets 0.52.0", 2212 | ] 2213 | 2214 | [[package]] 2215 | name = "windows-sys" 2216 | version = "0.48.0" 2217 | source = "registry+https://github.com/rust-lang/crates.io-index" 2218 | checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" 2219 | dependencies = [ 2220 | "windows-targets 0.48.5", 2221 | ] 2222 | 2223 | [[package]] 2224 | name = "windows-sys" 2225 | version = "0.52.0" 2226 | source = "registry+https://github.com/rust-lang/crates.io-index" 2227 | checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" 2228 | dependencies = [ 2229 | "windows-targets 0.52.0", 2230 | ] 2231 | 2232 | [[package]] 2233 | name = "windows-targets" 2234 | version = "0.48.5" 2235 | source = "registry+https://github.com/rust-lang/crates.io-index" 2236 | checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" 2237 | dependencies = [ 2238 | "windows_aarch64_gnullvm 0.48.5", 2239 | "windows_aarch64_msvc 0.48.5", 2240 | "windows_i686_gnu 0.48.5", 2241 | "windows_i686_msvc 0.48.5", 2242 | "windows_x86_64_gnu 0.48.5", 2243 | "windows_x86_64_gnullvm 0.48.5", 2244 | "windows_x86_64_msvc 0.48.5", 2245 | ] 2246 | 2247 | [[package]] 2248 | name = "windows-targets" 2249 | version = "0.52.0" 2250 | source = "registry+https://github.com/rust-lang/crates.io-index" 2251 | checksum = "8a18201040b24831fbb9e4eb208f8892e1f50a37feb53cc7ff887feb8f50e7cd" 2252 | dependencies = [ 2253 | "windows_aarch64_gnullvm 0.52.0", 2254 | "windows_aarch64_msvc 0.52.0", 2255 | "windows_i686_gnu 0.52.0", 2256 | "windows_i686_msvc 0.52.0", 2257 | "windows_x86_64_gnu 0.52.0", 2258 | "windows_x86_64_gnullvm 0.52.0", 2259 | "windows_x86_64_msvc 0.52.0", 2260 | ] 2261 | 2262 | [[package]] 2263 | name = "windows_aarch64_gnullvm" 2264 | version = "0.48.5" 2265 | source = "registry+https://github.com/rust-lang/crates.io-index" 2266 | checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" 2267 | 2268 | [[package]] 2269 | name = "windows_aarch64_gnullvm" 2270 | version = "0.52.0" 2271 | source = "registry+https://github.com/rust-lang/crates.io-index" 2272 | checksum = "cb7764e35d4db8a7921e09562a0304bf2f93e0a51bfccee0bd0bb0b666b015ea" 2273 | 2274 | [[package]] 2275 | name = "windows_aarch64_msvc" 2276 | version = "0.48.5" 2277 | source = "registry+https://github.com/rust-lang/crates.io-index" 2278 | checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" 2279 | 2280 | [[package]] 2281 | name = "windows_aarch64_msvc" 2282 | version = "0.52.0" 2283 | source = "registry+https://github.com/rust-lang/crates.io-index" 2284 | checksum = "bbaa0368d4f1d2aaefc55b6fcfee13f41544ddf36801e793edbbfd7d7df075ef" 2285 | 2286 | [[package]] 2287 | name = "windows_i686_gnu" 2288 | version = "0.48.5" 2289 | source = "registry+https://github.com/rust-lang/crates.io-index" 2290 | checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" 2291 | 2292 | [[package]] 2293 | name = "windows_i686_gnu" 2294 | version = "0.52.0" 2295 | source = "registry+https://github.com/rust-lang/crates.io-index" 2296 | checksum = "a28637cb1fa3560a16915793afb20081aba2c92ee8af57b4d5f28e4b3e7df313" 2297 | 2298 | [[package]] 2299 | name = "windows_i686_msvc" 2300 | version = "0.48.5" 2301 | source = "registry+https://github.com/rust-lang/crates.io-index" 2302 | checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" 2303 | 2304 | [[package]] 2305 | name = "windows_i686_msvc" 2306 | version = "0.52.0" 2307 | source = "registry+https://github.com/rust-lang/crates.io-index" 2308 | checksum = "ffe5e8e31046ce6230cc7215707b816e339ff4d4d67c65dffa206fd0f7aa7b9a" 2309 | 2310 | [[package]] 2311 | name = "windows_x86_64_gnu" 2312 | version = "0.48.5" 2313 | source = "registry+https://github.com/rust-lang/crates.io-index" 2314 | checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" 2315 | 2316 | [[package]] 2317 | name = "windows_x86_64_gnu" 2318 | version = "0.52.0" 2319 | source = "registry+https://github.com/rust-lang/crates.io-index" 2320 | checksum = "3d6fa32db2bc4a2f5abeacf2b69f7992cd09dca97498da74a151a3132c26befd" 2321 | 2322 | [[package]] 2323 | name = "windows_x86_64_gnullvm" 2324 | version = "0.48.5" 2325 | source = "registry+https://github.com/rust-lang/crates.io-index" 2326 | checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" 2327 | 2328 | [[package]] 2329 | name = "windows_x86_64_gnullvm" 2330 | version = "0.52.0" 2331 | source = "registry+https://github.com/rust-lang/crates.io-index" 2332 | checksum = "1a657e1e9d3f514745a572a6846d3c7aa7dbe1658c056ed9c3344c4109a6949e" 2333 | 2334 | [[package]] 2335 | name = "windows_x86_64_msvc" 2336 | version = "0.48.5" 2337 | source = "registry+https://github.com/rust-lang/crates.io-index" 2338 | checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" 2339 | 2340 | [[package]] 2341 | name = "windows_x86_64_msvc" 2342 | version = "0.52.0" 2343 | source = "registry+https://github.com/rust-lang/crates.io-index" 2344 | checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04" 2345 | 2346 | [[package]] 2347 | name = "winnow" 2348 | version = "0.5.40" 2349 | source = "registry+https://github.com/rust-lang/crates.io-index" 2350 | checksum = "f593a95398737aeed53e489c785df13f3618e41dbcd6718c6addbf1395aa6876" 2351 | dependencies = [ 2352 | "memchr", 2353 | ] 2354 | 2355 | [[package]] 2356 | name = "yansi" 2357 | version = "1.0.0-rc.1" 2358 | source = "registry+https://github.com/rust-lang/crates.io-index" 2359 | checksum = "1367295b8f788d371ce2dbc842c7b709c73ee1364d30351dd300ec2203b12377" 2360 | dependencies = [ 2361 | "is-terminal", 2362 | ] 2363 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "mail-autodiscover-autoconfig" 3 | version = "1.6.1" 4 | authors = ["William Desportes "] 5 | edition = "2021" 6 | rust-version = "1.72" 7 | build = "src/build.rs" 8 | 9 | [badges] 10 | github = { repository = "mail-autodiscover-autoconfig", branch = "main" } 11 | #codecov = { repository = "mail-autodiscover-autoconfig", branch = "main", service = "github" } 12 | is-it-maintained-issue-resolution = { repository = "mail-autodiscover-autoconfig" } 13 | is-it-maintained-open-issues = { repository = "mail-autodiscover-autoconfig" } 14 | maintenance = { status = "passively-maintained" } 15 | 16 | [features] 17 | default = ["apple", "dns"] 18 | apple = [] 19 | dns = [] 20 | 21 | [dependencies] 22 | # ENV 23 | dotenv = "0.15.0" 24 | 25 | # Domain parsing 26 | addr = "0.15.3" 27 | 28 | # Webserver 29 | rocket = { version = "0.5.0", features = ["json"] } 30 | 31 | # Serialization/Deserialization 32 | quick-xml = { version = "0.31.0", default-features = false, features = [ "serialize" ] } 33 | serde_json = "1.0.64" 34 | serde = { version = "1.0.153", default-features = false, features = [ "derive" ] } 35 | chrono = "0.4.34" 36 | 37 | [dependencies.tera] 38 | version = "1" 39 | default-features = false 40 | 41 | [dependencies.rocket_dyn_templates] 42 | version = "0.1.0" 43 | features = ["tera"] 44 | 45 | [dev-dependencies] 46 | temp-env = "0.3.1" 47 | 48 | [build-dependencies] 49 | anyhow = "1.0.63" 50 | vergen = { version = "8.3.1", features = ["build", "cargo", "git", "gitcl", "rustc"] } 51 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Mozilla Public License Version 2.0 2 | ================================== 3 | 4 | 1. Definitions 5 | -------------- 6 | 7 | 1.1. "Contributor" 8 | means each individual or legal entity that creates, contributes to 9 | the creation of, or owns Covered Software. 10 | 11 | 1.2. "Contributor Version" 12 | means the combination of the Contributions of others (if any) used 13 | by a Contributor and that particular Contributor's Contribution. 14 | 15 | 1.3. "Contribution" 16 | means Covered Software of a particular Contributor. 17 | 18 | 1.4. "Covered Software" 19 | means Source Code Form to which the initial Contributor has attached 20 | the notice in Exhibit A, the Executable Form of such Source Code 21 | Form, and Modifications of such Source Code Form, in each case 22 | including portions thereof. 23 | 24 | 1.5. "Incompatible With Secondary Licenses" 25 | means 26 | 27 | (a) that the initial Contributor has attached the notice described 28 | in Exhibit B to the Covered Software; or 29 | 30 | (b) that the Covered Software was made available under the terms of 31 | version 1.1 or earlier of the License, but not also under the 32 | terms of a Secondary License. 33 | 34 | 1.6. "Executable Form" 35 | means any form of the work other than Source Code Form. 36 | 37 | 1.7. "Larger Work" 38 | means a work that combines Covered Software with other material, in 39 | a separate file or files, that is not Covered Software. 40 | 41 | 1.8. "License" 42 | means this document. 43 | 44 | 1.9. "Licensable" 45 | means having the right to grant, to the maximum extent possible, 46 | whether at the time of the initial grant or subsequently, any and 47 | all of the rights conveyed by this License. 48 | 49 | 1.10. "Modifications" 50 | means any of the following: 51 | 52 | (a) any file in Source Code Form that results from an addition to, 53 | deletion from, or modification of the contents of Covered 54 | Software; or 55 | 56 | (b) any new file in Source Code Form that contains any Covered 57 | Software. 58 | 59 | 1.11. "Patent Claims" of a Contributor 60 | means any patent claim(s), including without limitation, method, 61 | process, and apparatus claims, in any patent Licensable by such 62 | Contributor that would be infringed, but for the grant of the 63 | License, by the making, using, selling, offering for sale, having 64 | made, import, or transfer of either its Contributions or its 65 | Contributor Version. 66 | 67 | 1.12. "Secondary License" 68 | means either the GNU General Public License, Version 2.0, the GNU 69 | Lesser General Public License, Version 2.1, the GNU Affero General 70 | Public License, Version 3.0, or any later versions of those 71 | licenses. 72 | 73 | 1.13. "Source Code Form" 74 | means the form of the work preferred for making modifications. 75 | 76 | 1.14. "You" (or "Your") 77 | means an individual or a legal entity exercising rights under this 78 | License. For legal entities, "You" includes any entity that 79 | controls, is controlled by, or is under common control with You. For 80 | purposes of this definition, "control" means (a) the power, direct 81 | or indirect, to cause the direction or management of such entity, 82 | whether by contract or otherwise, or (b) ownership of more than 83 | fifty percent (50%) of the outstanding shares or beneficial 84 | ownership of such entity. 85 | 86 | 2. License Grants and Conditions 87 | -------------------------------- 88 | 89 | 2.1. Grants 90 | 91 | Each Contributor hereby grants You a world-wide, royalty-free, 92 | non-exclusive license: 93 | 94 | (a) under intellectual property rights (other than patent or trademark) 95 | Licensable by such Contributor to use, reproduce, make available, 96 | modify, display, perform, distribute, and otherwise exploit its 97 | Contributions, either on an unmodified basis, with Modifications, or 98 | as part of a Larger Work; and 99 | 100 | (b) under Patent Claims of such Contributor to make, use, sell, offer 101 | for sale, have made, import, and otherwise transfer either its 102 | Contributions or its Contributor Version. 103 | 104 | 2.2. Effective Date 105 | 106 | The licenses granted in Section 2.1 with respect to any Contribution 107 | become effective for each Contribution on the date the Contributor first 108 | distributes such Contribution. 109 | 110 | 2.3. Limitations on Grant Scope 111 | 112 | The licenses granted in this Section 2 are the only rights granted under 113 | this License. No additional rights or licenses will be implied from the 114 | distribution or licensing of Covered Software under this License. 115 | Notwithstanding Section 2.1(b) above, no patent license is granted by a 116 | Contributor: 117 | 118 | (a) for any code that a Contributor has removed from Covered Software; 119 | or 120 | 121 | (b) for infringements caused by: (i) Your and any other third party's 122 | modifications of Covered Software, or (ii) the combination of its 123 | Contributions with other software (except as part of its Contributor 124 | Version); or 125 | 126 | (c) under Patent Claims infringed by Covered Software in the absence of 127 | its Contributions. 128 | 129 | This License does not grant any rights in the trademarks, service marks, 130 | or logos of any Contributor (except as may be necessary to comply with 131 | the notice requirements in Section 3.4). 132 | 133 | 2.4. Subsequent Licenses 134 | 135 | No Contributor makes additional grants as a result of Your choice to 136 | distribute the Covered Software under a subsequent version of this 137 | License (see Section 10.2) or under the terms of a Secondary License (if 138 | permitted under the terms of Section 3.3). 139 | 140 | 2.5. Representation 141 | 142 | Each Contributor represents that the Contributor believes its 143 | Contributions are its original creation(s) or it has sufficient rights 144 | to grant the rights to its Contributions conveyed by this License. 145 | 146 | 2.6. Fair Use 147 | 148 | This License is not intended to limit any rights You have under 149 | applicable copyright doctrines of fair use, fair dealing, or other 150 | equivalents. 151 | 152 | 2.7. Conditions 153 | 154 | Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted 155 | in Section 2.1. 156 | 157 | 3. Responsibilities 158 | ------------------- 159 | 160 | 3.1. Distribution of Source Form 161 | 162 | All distribution of Covered Software in Source Code Form, including any 163 | Modifications that You create or to which You contribute, must be under 164 | the terms of this License. You must inform recipients that the Source 165 | Code Form of the Covered Software is governed by the terms of this 166 | License, and how they can obtain a copy of this License. You may not 167 | attempt to alter or restrict the recipients' rights in the Source Code 168 | Form. 169 | 170 | 3.2. Distribution of Executable Form 171 | 172 | If You distribute Covered Software in Executable Form then: 173 | 174 | (a) such Covered Software must also be made available in Source Code 175 | Form, as described in Section 3.1, and You must inform recipients of 176 | the Executable Form how they can obtain a copy of such Source Code 177 | Form by reasonable means in a timely manner, at a charge no more 178 | than the cost of distribution to the recipient; and 179 | 180 | (b) You may distribute such Executable Form under the terms of this 181 | License, or sublicense it under different terms, provided that the 182 | license for the Executable Form does not attempt to limit or alter 183 | the recipients' rights in the Source Code Form under this License. 184 | 185 | 3.3. Distribution of a Larger Work 186 | 187 | You may create and distribute a Larger Work under terms of Your choice, 188 | provided that You also comply with the requirements of this License for 189 | the Covered Software. If the Larger Work is a combination of Covered 190 | Software with a work governed by one or more Secondary Licenses, and the 191 | Covered Software is not Incompatible With Secondary Licenses, this 192 | License permits You to additionally distribute such Covered Software 193 | under the terms of such Secondary License(s), so that the recipient of 194 | the Larger Work may, at their option, further distribute the Covered 195 | Software under the terms of either this License or such Secondary 196 | License(s). 197 | 198 | 3.4. Notices 199 | 200 | You may not remove or alter the substance of any license notices 201 | (including copyright notices, patent notices, disclaimers of warranty, 202 | or limitations of liability) contained within the Source Code Form of 203 | the Covered Software, except that You may alter any license notices to 204 | the extent required to remedy known factual inaccuracies. 205 | 206 | 3.5. Application of Additional Terms 207 | 208 | You may choose to offer, and to charge a fee for, warranty, support, 209 | indemnity or liability obligations to one or more recipients of Covered 210 | Software. However, You may do so only on Your own behalf, and not on 211 | behalf of any Contributor. You must make it absolutely clear that any 212 | such warranty, support, indemnity, or liability obligation is offered by 213 | You alone, and You hereby agree to indemnify every Contributor for any 214 | liability incurred by such Contributor as a result of warranty, support, 215 | indemnity or liability terms You offer. You may include additional 216 | disclaimers of warranty and limitations of liability specific to any 217 | jurisdiction. 218 | 219 | 4. Inability to Comply Due to Statute or Regulation 220 | --------------------------------------------------- 221 | 222 | If it is impossible for You to comply with any of the terms of this 223 | License with respect to some or all of the Covered Software due to 224 | statute, judicial order, or regulation then You must: (a) comply with 225 | the terms of this License to the maximum extent possible; and (b) 226 | describe the limitations and the code they affect. Such description must 227 | be placed in a text file included with all distributions of the Covered 228 | Software under this License. Except to the extent prohibited by statute 229 | or regulation, such description must be sufficiently detailed for a 230 | recipient of ordinary skill to be able to understand it. 231 | 232 | 5. Termination 233 | -------------- 234 | 235 | 5.1. The rights granted under this License will terminate automatically 236 | if You fail to comply with any of its terms. However, if You become 237 | compliant, then the rights granted under this License from a particular 238 | Contributor are reinstated (a) provisionally, unless and until such 239 | Contributor explicitly and finally terminates Your grants, and (b) on an 240 | ongoing basis, if such Contributor fails to notify You of the 241 | non-compliance by some reasonable means prior to 60 days after You have 242 | come back into compliance. Moreover, Your grants from a particular 243 | Contributor are reinstated on an ongoing basis if such Contributor 244 | notifies You of the non-compliance by some reasonable means, this is the 245 | first time You have received notice of non-compliance with this License 246 | from such Contributor, and You become compliant prior to 30 days after 247 | Your receipt of the notice. 248 | 249 | 5.2. If You initiate litigation against any entity by asserting a patent 250 | infringement claim (excluding declaratory judgment actions, 251 | counter-claims, and cross-claims) alleging that a Contributor Version 252 | directly or indirectly infringes any patent, then the rights granted to 253 | You by any and all Contributors for the Covered Software under Section 254 | 2.1 of this License shall terminate. 255 | 256 | 5.3. In the event of termination under Sections 5.1 or 5.2 above, all 257 | end user license agreements (excluding distributors and resellers) which 258 | have been validly granted by You or Your distributors under this License 259 | prior to termination shall survive termination. 260 | 261 | ************************************************************************ 262 | * * 263 | * 6. Disclaimer of Warranty * 264 | * ------------------------- * 265 | * * 266 | * Covered Software is provided under this License on an "as is" * 267 | * basis, without warranty of any kind, either expressed, implied, or * 268 | * statutory, including, without limitation, warranties that the * 269 | * Covered Software is free of defects, merchantable, fit for a * 270 | * particular purpose or non-infringing. The entire risk as to the * 271 | * quality and performance of the Covered Software is with You. * 272 | * Should any Covered Software prove defective in any respect, You * 273 | * (not any Contributor) assume the cost of any necessary servicing, * 274 | * repair, or correction. This disclaimer of warranty constitutes an * 275 | * essential part of this License. No use of any Covered Software is * 276 | * authorized under this License except under this disclaimer. * 277 | * * 278 | ************************************************************************ 279 | 280 | ************************************************************************ 281 | * * 282 | * 7. Limitation of Liability * 283 | * -------------------------- * 284 | * * 285 | * Under no circumstances and under no legal theory, whether tort * 286 | * (including negligence), contract, or otherwise, shall any * 287 | * Contributor, or anyone who distributes Covered Software as * 288 | * permitted above, be liable to You for any direct, indirect, * 289 | * special, incidental, or consequential damages of any character * 290 | * including, without limitation, damages for lost profits, loss of * 291 | * goodwill, work stoppage, computer failure or malfunction, or any * 292 | * and all other commercial damages or losses, even if such party * 293 | * shall have been informed of the possibility of such damages. This * 294 | * limitation of liability shall not apply to liability for death or * 295 | * personal injury resulting from such party's negligence to the * 296 | * extent applicable law prohibits such limitation. Some * 297 | * jurisdictions do not allow the exclusion or limitation of * 298 | * incidental or consequential damages, so this exclusion and * 299 | * limitation may not apply to You. * 300 | * * 301 | ************************************************************************ 302 | 303 | 8. Litigation 304 | ------------- 305 | 306 | Any litigation relating to this License may be brought only in the 307 | courts of a jurisdiction where the defendant maintains its principal 308 | place of business and such litigation shall be governed by laws of that 309 | jurisdiction, without reference to its conflict-of-law provisions. 310 | Nothing in this Section shall prevent a party's ability to bring 311 | cross-claims or counter-claims. 312 | 313 | 9. Miscellaneous 314 | ---------------- 315 | 316 | This License represents the complete agreement concerning the subject 317 | matter hereof. If any provision of this License is held to be 318 | unenforceable, such provision shall be reformed only to the extent 319 | necessary to make it enforceable. Any law or regulation which provides 320 | that the language of a contract shall be construed against the drafter 321 | shall not be used to construe this License against a Contributor. 322 | 323 | 10. Versions of the License 324 | --------------------------- 325 | 326 | 10.1. New Versions 327 | 328 | Mozilla Foundation is the license steward. Except as provided in Section 329 | 10.3, no one other than the license steward has the right to modify or 330 | publish new versions of this License. Each version will be given a 331 | distinguishing version number. 332 | 333 | 10.2. Effect of New Versions 334 | 335 | You may distribute the Covered Software under the terms of the version 336 | of the License under which You originally received the Covered Software, 337 | or under the terms of any subsequent version published by the license 338 | steward. 339 | 340 | 10.3. Modified Versions 341 | 342 | If you create software not governed by this License, and you want to 343 | create a new license for such software, you may create and use a 344 | modified version of this License if you rename the license and remove 345 | any references to the name of the license steward (except to note that 346 | such modified license differs from this License). 347 | 348 | 10.4. Distributing Source Code Form that is Incompatible With Secondary 349 | Licenses 350 | 351 | If You choose to distribute Source Code Form that is Incompatible With 352 | Secondary Licenses under the terms of this version of the License, the 353 | notice described in Exhibit B of this License must be attached. 354 | 355 | Exhibit A - Source Code Form License Notice 356 | ------------------------------------------- 357 | 358 | This Source Code Form is subject to the terms of the Mozilla Public 359 | License, v. 2.0. If a copy of the MPL was not distributed with this 360 | file, You can obtain one at http://mozilla.org/MPL/2.0/. 361 | 362 | If it is not possible or desirable to put the notice in a particular 363 | file, then You may include the notice in a location (such as a LICENSE 364 | file in a relevant directory) where a recipient would be likely to look 365 | for such a notice. 366 | 367 | You may add additional accurate notices of copyright ownership. 368 | 369 | Exhibit B - "Incompatible With Secondary Licenses" Notice 370 | --------------------------------------------------------- 371 | 372 | This Source Code Form is "Incompatible With Secondary Licenses", as 373 | defined by the Mozilla Public License, v. 2.0. 374 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | IMAGE_TAG ?= wdes/mail-autodiscover-autoconfig 2 | # All: linux/386,linux/amd64,linux/arm/v5,linux/arm/v7,linux/arm64/v8,linux/mips64le,linux/ppc64le,linux/s390x 3 | # Supported by rust (Debian variant, alpine has 2 less): linux/386,linux/amd64,linux/arm/v7,linux/arm64/v8 4 | # Supported by alpine: linux/386,linux/amd64,linux/arm/v6,linux/arm/v7,linux/arm64/v8,linux/ppc64le,linux/s390x 5 | PLATFORM ?= linux/amd64 6 | 7 | ACTION ?= load 8 | PROGRESS_MODE ?= plain 9 | EXTRA_ARGS ?= 10 | 11 | .PHONY: build build-release test test-coverage validate format docker-build 12 | 13 | build: 14 | @cargo build 15 | 16 | build-release: 17 | @cargo build --release 18 | 19 | test: 20 | @cargo test 21 | 22 | test-coverage: 23 | @cargo tarpaulin 24 | 25 | validate: 26 | @xmllint --noout --schema xml/xsd/mobilesync/AutodiscoverRequest.xsd xml/mobilesync/AutodiscoverRequest.xml 27 | @xmllint --noout --schema xml/xsd/mobilesync/AutodiscoverResponse.xsd templates/xml/autodiscover-mobilesync.xml.tera 28 | 29 | @xmllint --noout --schema xml/xsd/autodiscover/AutodiscoverRequest.xsd xml/autodiscover/AutodiscoverRequest.xml 30 | @xmllint --noout --schema xml/xsd/autodiscover/AutodiscoverResponse.xsd xml/autodiscover/AutodiscoverExchangeResponse.xml 31 | @xmllint --noout --schema xml/xsd/autodiscover/AutodiscoverResponse.xsd xml/autodiscover/AutodiscoverResponse.xml 32 | @xmllint --noout --schema xml/xsd/autodiscover/AutodiscoverResponse.xsd templates/xml/autodiscover.xml.tera 33 | @xmllint --noout --schema xml/xsd/autodiscover/AutodiscoverExchangeResponseRedirect.xsd xml/autodiscover/AutodiscoverResponseRedirect.xml 34 | @xmllint --noout --schema xml/xsd/autodiscover/AutodiscoverResponseError.xsd xml/autodiscover/AutodiscoverResponseError.xml 35 | 36 | format: 37 | @cargo fmt -- --emit files 38 | 39 | docker-build: 40 | # https://github.com/docker/buildx#building 41 | docker buildx build \ 42 | --tag $(IMAGE_TAG) \ 43 | --progress $(PROGRESS_MODE) \ 44 | --platform $(PLATFORM) \ 45 | --build-arg VCS_REF="$(shell git rev-parse HEAD)" \ 46 | --build-arg BUILD_DATE="$(shell date -u +"%Y-%m-%dT%H:%M:%SZ")" \ 47 | --build-arg RELEASE_VERSION="$(shell grep -P -m 1 '^version = ".*"$$' Cargo.toml | cut -d '"' -f 2)" \ 48 | --$(ACTION) \ 49 | $(EXTRA_ARGS) \ 50 | --file docker/Dockerfile \ 51 | ./ 52 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Wdes Mail AutoDiscover-AutoConfig 2 | 3 | [![dependency status](https://deps.rs/repo/github/wdes/mail-autodiscover-autoconfig/status.svg)](https://deps.rs/repo/github/wdes/mail-autodiscover-autoconfig) 4 | [![Build and test rust code](https://github.com/wdes/mail-autodiscover-autoconfig/actions/workflows/rust.yml/badge.svg)](https://github.com/wdes/mail-autodiscover-autoconfig/actions/workflows/rust.yml) 5 | ![maintenance-status](https://img.shields.io/badge/maintenance-passively--maintained-yellowgreen.svg) 6 | 7 | ## Support 8 | 9 | - Thunderbird 10 | - Microsoft Outlook 11 | - Apple MacOS 12 | - Apple iOS 13 | 14 | ## Inspiration 15 | 16 | - [mailcow's autodiscover-json.php](https://github.com/mailcow/mailcow-dockerized/blob/master/data/web/autodiscover-json.php) 17 | - [Monogramm's autodiscover-email-settings Node project](https://github.com/Monogramm/autodiscover-email-settings) 18 | - [Wicloz's EmailAutoConfig templates](https://github.com/Wicloz/EmailAutoConfig/tree/8e02dbd6dca7edfd748802028ba711289a7fe1a5/templates) 19 | - [Mailu's logic for AcceptableResponseSchema](https://github.com/Mailu/Mailu/blob/c15e4e6015592735fa6f730af72b8332e93ae672/core/admin/mailu/internal/views/autoconfig.py#L55-L91) 20 | - [hmlkao's php-autodiscover for Apps to test](https://github.com/hmlkao/php-autodiscover#readme) 21 | - [StephanvanSchaik's automail project written in Rust](https://github.com/StephanvanSchaik/automail) 22 | 23 | ## Tested email clients 24 | 25 | | Email client | Tested version | 26 | | ------------ | -------------- | 27 | | [Apple MacOS Monterey](https://www.apple.com/fr/macos/monterey/) on Apple Mail | MacOS: 12.2, Mail: 15.0 (3693.60.0.1.1) | 28 | | [Thunderbird](https://www.thunderbird.net/) | 91.10.0 | 29 | | [Evolution on Ubuntu](https://wiki.gnome.org/Apps/Evolution/) | [3.40.0](https://gitlab.gnome.org/GNOME/evolution/-/tree/3.40.0/) | 30 | | [KMail on Ubuntu](https://userbase.kde.org/KMail) | 5.19.3 (21.12.3) | 31 | | [Microsoft Office Pro Plus 2013](https://wikipedia.org/wiki/Microsoft_Office_2013) | 15.0.5399.1000 64 bits | 32 | | [Microsoft Office Pro Plus 2021](https://wikipedia.org/wiki/Microsoft_Office_2013)
*[_You need to disable Office 365 setup and adjust the config manually_](https://github.com/smartlyway/email-autoconfig-php/issues/2) | 14326.204454 64 bits | 33 | 34 | ### Mobile email clients 35 | 36 | | Email client | Tested version | 37 | | ------------ | -------------- | 38 | | [Apple iOS 15.6.1](https://support.apple.com/en-us/HT213412) | iOS: 15.6.1 | 39 | | [FairEmail](https://github.com/M66B/FairEmail) | 1.1917 | 40 | | [K-9 Mail since 6.709](https://github.com/thundernest/k-9#readme) | [6.709](https://github.com/thundernest/k-9/releases/tag/6.709) | 41 | | [Android Nine](https://www.9folders.com/en/index.html) | [4.9.4b](https://play.google.com/store/apps/details?id=com.ninefolders.hd3) | 42 | | [Spark Mail on Android](https://sparkmailapp.com/) | 2.11.8 | 43 | | [MailTime on Android](https://mailtime.com/) | 2.5.4.0614 | 44 | | [Maily on Android](https://github.com/Enough-Software/enough_mail_app#readme) | [1.0.0](https://play.google.com/store/apps/details?id=de.enough.enough_mail_app) | 45 | | [ProfiMail on Android](https://www.lonelycatgames.com/apps/profimail) | 4.31.08 | 46 | 47 | ## Usage 48 | 49 | Pull the [image](https://hub.docker.com/r/wdes/mail-autodiscover-autoconfig): `docker pull wdes/mail-autodiscover-autoconfig` 50 | 51 | Save this `docker-compose.yml` file and adjust it for your needs. 52 | 53 | ```yml 54 | version: "3" 55 | 56 | services: 57 | mail-autodiscover-autoconfig: 58 | image: wdes/mail-autodiscover-autoconfig:latest 59 | mem_limit: 120M 60 | mem_reservation: 50M 61 | restart: on-failure:40 62 | ports: 63 | - "8088:80" 64 | environment: 65 | ROCKET_PROFILE: production 66 | ROCKET_ADDRESS: "0.0.0.0" 67 | ROCKET_PORT: "80" 68 | # https://www.uuidgenerator.net/ 69 | # Re-generate the two UUIDs below 70 | APPLE_MAIL_UUID: ff83a13b-c4e6-41c5-bf54-0a244bb3bf5d 71 | APPLE_PROFILE_UUID: b8e39daa-64a3-4928-bb86-cb4b551fdd57 72 | # CUSTOM_DOMAINS: foo.tld 73 | # (optional: CUSTOM_DOMAINS) List of domains that will use {imap,pop,smtp}.domain.tld instead of the hosts below 74 | IMAP_HOSTNAME: imap.mails.provider.tld 75 | POP_HOSTNAME: pop.mails.provider.tld 76 | SMTP_HOSTNAME: smtp.mails.provider.tld 77 | ``` 78 | 79 | ### Install on Apple 80 | 81 | - Browse `https://autoconfig../apple` or directly `https://autoconfig../email.mobileconfig?email=@.` 82 | - Fill and submit the form, the profile downloads itself 83 | - Click on it, it says to go to system settings to enable it 84 | - Go to system settings, then "Profiles" or "Downloaded Profiles" 85 | - Click install on the profile, enter your password 86 | - You can go back to your Mail app, the email configured 87 | 88 | NB: Is Apple signing implemented: No. Will it be: maybe, if someone/I figures it out ^^ 89 | 90 | ### Technical compilation aspects 91 | 92 | You can disable some of the default features. For now the default features are: 93 | 94 | - `apple` (This feature contains the web UI route and the mobile config route) 95 | - `dns` (This feature adds a DNS txt route to obtain your ideal DNS config) 96 | 97 | ## TODO 98 | 99 | - [ ] [Merge the Apple code with StephanvanSchaik's automail](https://github.com/StephanvanSchaik/automail), [ref: StephanvanSchaik/automail#1](https://github.com/StephanvanSchaik/automail/issues/1). 100 | - [ ] Test `// Used by Microsoft Office 2009 (to be confirmed)` and adjust the code comments. 101 | -------------------------------------------------------------------------------- /docker/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM alpine:3.20 as build-env 2 | 3 | WORKDIR /workspace 4 | COPY . ./ 5 | RUN apk add --no-cache --update musl-dev openssl-dev rust cargo 6 | RUN cargo test --release 7 | # https://users.rust-lang.org/t/sigsegv-with-program-linked-against-openssl-in-an-alpine-container/52172 8 | RUN RUSTFLAGS="-C target-feature=-crt-static" cargo build --release 9 | 10 | FROM alpine:3.20 as runtime 11 | 12 | ARG VCS_REF 13 | ARG BUILD_DATE 14 | ARG RELEASE_VERSION 15 | 16 | # Metadata 17 | LABEL org.label-schema.vendor="Wdes" \ 18 | org.label-schema.url="https://github.com/wdes/mail-autodiscover-autoconfig#readme" \ 19 | org.label-schema.name="mail-autodiscover-autoconfig" \ 20 | org.label-schema.description="A docker image to deploy to have a dynamic autodiscover XML and autoconfig XML host. Supports Outlook, Thunderbird, Apple, some Android apps, and more.." \ 21 | org.label-schema.version=${RELEASE_VERSION} \ 22 | org.label-schema.vcs-url="https://github.com/wdes/mail-autodiscover-autoconfig.git" \ 23 | org.label-schema.vcs-ref=${VCS_REF} \ 24 | org.label-schema.build-date=${BUILD_DATE} \ 25 | org.label-schema.docker.schema-version="1.0" \ 26 | \ 27 | com.docker.extension.publisher-url="https://github.com/wdes" \ 28 | \ 29 | org.opencontainers.image.title="Docker autodiscover, autoconfig web server" \ 30 | org.opencontainers.image.description="A docker image to deploy to have a dynamic autodiscover XML and autoconfig XML host. Supports Outlook, Thunderbird, Apple, some Android apps, and more.." \ 31 | org.opencontainers.image.authors="williamdes@wdes.fr" \ 32 | org.opencontainers.image.url="https://github.com/wdes/mail-autodiscover-autoconfig#readme" \ 33 | org.opencontainers.image.documentation="https://github.com/wdes/mail-autodiscover-autoconfig#readme" \ 34 | org.opencontainers.image.source="https://github.com/wdes/mail-autodiscover-autoconfig" \ 35 | org.opencontainers.image.vendor="Wdes" \ 36 | org.opencontainers.image.licenses="MPL-2.0" \ 37 | org.opencontainers.image.created=${BUILD_DATE} \ 38 | org.opencontainers.image.version=${RELEASE_VERSION} \ 39 | org.opencontainers.image.revision=${VCS_REF} \ 40 | org.opencontainers.image.ref.name="latest" 41 | 42 | # https://github.com/mischov/meeseeks/issues/98#issuecomment-636615680 43 | RUN apk add --no-cache --update openssl libgcc 44 | 45 | ENV ROCKET_TEMPLATE_DIR="/usr/lib/mail-autodiscover-autoconfig/templates" 46 | COPY --from=build-env /workspace/templates /usr/lib/mail-autodiscover-autoconfig/templates 47 | COPY --from=build-env /workspace/target/release/mail-autodiscover-autoconfig /usr/bin 48 | 49 | ENTRYPOINT [ "mail-autodiscover-autoconfig" ] 50 | -------------------------------------------------------------------------------- /src/build.rs: -------------------------------------------------------------------------------- 1 | use anyhow::Result; 2 | use vergen::EmitBuilder; 3 | 4 | pub fn main() -> Result<()> { 5 | // NOTE: See the EmitBuilder documentation for configuration options. 6 | EmitBuilder::builder() 7 | .all_build() 8 | .all_cargo() 9 | .all_git() 10 | .all_rustc() 11 | .emit()?; 12 | Ok(()) 13 | } 14 | -------------------------------------------------------------------------------- /src/host_header.rs: -------------------------------------------------------------------------------- 1 | // Source: https://github.com/SergioBenitez/Rocket/issues/823#issuecomment-1157761369 2 | use addr::parse_domain_name; 3 | use rocket::http::Status; 4 | use rocket::request::FromRequest; 5 | use rocket::request::Outcome; 6 | use rocket::Request; 7 | 8 | pub struct HostHeader<'a> { 9 | pub host: &'a str, 10 | pub base_domain: String, 11 | } 12 | 13 | fn get_base_domain<'a>(header: &'a str) -> String { 14 | let parsed = &parse_domain_name(header); 15 | 16 | match parsed { 17 | Ok(h) => match h.root() { 18 | Some(d) => d.to_string(), 19 | None => header.to_string(), 20 | }, 21 | _ => header.to_string(), 22 | } 23 | } 24 | 25 | #[rocket::async_trait] 26 | impl<'r> FromRequest<'r> for HostHeader<'r> { 27 | type Error = String; 28 | 29 | async fn from_request(req: &'r Request<'_>) -> Outcome { 30 | let header_name: &str = match req.headers().contains("X-Forwarded-Host") { 31 | true => "X-Forwarded-Host", 32 | false => "Host", 33 | }; 34 | 35 | match req.headers().get_one(header_name) { 36 | Some(h) => Outcome::Success(HostHeader { 37 | host: h, 38 | base_domain: get_base_domain(h), 39 | }), 40 | None => Outcome::Error(( 41 | Status::UnprocessableEntity, 42 | "Missing a Host or X-Forwarded-Host header".to_string(), 43 | )), 44 | } 45 | } 46 | } 47 | 48 | #[cfg(test)] 49 | mod tests { 50 | use super::*; 51 | 52 | #[test] 53 | fn test_get_base_domain() { 54 | assert_eq!("d", get_base_domain("d")); 55 | assert_eq!("d.tld", get_base_domain("d.tld")); 56 | assert_eq!("d.tld", get_base_domain("foo.d.tld")); 57 | assert_eq!("wdes.fr", get_base_domain("autoconfig.wdes.fr")); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /src/main.rs: -------------------------------------------------------------------------------- 1 | #[macro_use] 2 | extern crate rocket; 3 | extern crate dotenv; 4 | extern crate rocket_dyn_templates; 5 | extern crate serde; 6 | extern crate serde_json; 7 | extern crate tera; 8 | 9 | use crate::dotenv::dotenv; 10 | use rocket_dyn_templates::Template; 11 | use std::env; 12 | 13 | pub mod host_header; 14 | pub mod resources; 15 | pub mod routes; 16 | pub mod util; 17 | 18 | #[launch] 19 | fn rocket() -> _ { 20 | println!( 21 | "Wdes Mail AutoDiscover-AutoConfig (https://github.com/wdes/mail-autodiscover-autoconfig)." 22 | ); 23 | 24 | println!( 25 | "Version: {} built on Rust: {} at: {} using commit: {} on branch: {}", 26 | env!("CARGO_PKG_VERSION"), 27 | env!("VERGEN_RUSTC_SEMVER"), 28 | env!("VERGEN_BUILD_TIMESTAMP"), 29 | env!("VERGEN_GIT_SHA"), 30 | env!("VERGEN_GIT_BRANCH"), 31 | ); 32 | 33 | dotenv().ok(); 34 | 35 | let custom_domains: String = util::get_custom_domains_list(); 36 | println!("Custom domains: {}", custom_domains); 37 | 38 | let figment = rocket::Config::figment().merge(("ident", "Wdes Mail AutoDiscover-AutoConfig")); 39 | 40 | let mut rocket = rocket::custom(figment).attach(Template::fairing()).mount( 41 | "/", 42 | routes![ 43 | routes::tech::index, 44 | routes::tech::robots, 45 | routes::tech::version, 46 | routes::tech::ping, 47 | routes::autoconfig::v11_mail_config_v11, 48 | routes::autoconfig::mail_config_v11, 49 | routes::autoconfig::well_known_mail_config_v11, 50 | routes::autoconfig::mail_autodiscover_microsoft, 51 | routes::autoconfig::mail_autodiscover_microsoft_case, 52 | routes::autoconfig::mail_autodiscover_microsoft_camel_case, 53 | routes::autoconfig::post_mail_autodiscover_microsoft, 54 | routes::autoconfig::post_mail_autodiscover_microsoft_case, 55 | routes::autoconfig::post_mail_autodiscover_microsoft_camel_case, 56 | routes::autoconfig::post_mail_autodiscover_microsoft_json, 57 | routes::autoconfig::post_mail_autodiscover_microsoft_json_legacy, 58 | ], 59 | ); 60 | if cfg!(feature = "apple") { 61 | rocket = rocket.mount( 62 | "/", 63 | routes![ 64 | routes::autoconfig::mail_autodiscover_apple_mobileconfig, 65 | routes::tech::apple, 66 | ], 67 | ); 68 | } 69 | if cfg!(feature = "dns") { 70 | rocket = rocket.mount("/", routes![routes::dns::dns_txt_zone,]); 71 | } 72 | rocket 73 | } 74 | -------------------------------------------------------------------------------- /src/resources.rs: -------------------------------------------------------------------------------- 1 | #[allow(non_snake_case)] 2 | pub mod AppleResponse; 3 | #[allow(non_snake_case)] 4 | pub mod AutoDiscoverJson; 5 | #[allow(non_snake_case)] 6 | pub mod AutoDiscoverXml; 7 | #[allow(non_snake_case)] 8 | pub mod DnsTxtResponse; 9 | #[allow(non_snake_case)] 10 | pub mod Version; 11 | -------------------------------------------------------------------------------- /src/resources/AppleResponse.rs: -------------------------------------------------------------------------------- 1 | use rocket::request::Request; 2 | use rocket::response::{self, Responder, Response}; 3 | use rocket_dyn_templates::Template; 4 | 5 | pub struct AppleResponse { 6 | pub template: Template, 7 | pub domain: String, 8 | } 9 | 10 | impl<'r, 'o: 'r> Responder<'r, 'o> for AppleResponse { 11 | fn respond_to(self, req: &'r Request<'_>) -> response::Result<'o> { 12 | Response::build_from(self.template.respond_to(req)?) 13 | .raw_header( 14 | "Content-Type", 15 | "application/x-apple-aspen-config; charset=utf-8", 16 | ) 17 | .raw_header( 18 | "Content-Disposition", 19 | "attachment; filename=\"".to_owned() + &self.domain + ".mobileconfig\"", 20 | ) 21 | .ok() 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/resources/AutoDiscoverJson.rs: -------------------------------------------------------------------------------- 1 | use rocket::http::{ContentType, Status}; 2 | use rocket::request::Request; 3 | use rocket::response::{self, Responder, Response}; 4 | use rocket::serde::json::Json; 5 | use serde::{Deserialize, Serialize}; 6 | 7 | #[derive(Serialize, Deserialize)] 8 | pub struct AutoDiscoverJson { 9 | pub Protocol: String, 10 | pub Url: String, 11 | } 12 | 13 | #[derive(Serialize, Deserialize)] 14 | pub struct AutoDiscoverJsonError { 15 | pub ErrorCode: String, 16 | pub ErrorMessage: String, 17 | } 18 | 19 | impl<'r, 'o: 'r> Responder<'r, 'o> for AutoDiscoverJsonError { 20 | fn respond_to(self, req: &'r Request<'_>) -> response::Result<'o> { 21 | Response::build_from( 22 | Json(AutoDiscoverJsonError { 23 | ErrorCode: self.ErrorCode, 24 | ErrorMessage: self.ErrorMessage, 25 | }) 26 | .respond_to(req)?, 27 | ) 28 | .header(ContentType::JSON) 29 | .status(Status::BadRequest) 30 | .ok() 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/resources/AutoDiscoverXml.rs: -------------------------------------------------------------------------------- 1 | use quick_xml::de::from_str; 2 | use quick_xml::DeError; 3 | use rocket::data::ByteUnit; 4 | use rocket::data::{self, Capped, Data, FromData}; 5 | use rocket::http::{ContentType, Status}; 6 | use rocket::request::Request; 7 | use rocket::response::{self, Responder, Response}; 8 | use rocket_dyn_templates::Template; 9 | use serde::Deserialize; 10 | use std::io; 11 | 12 | #[derive(Debug)] 13 | pub enum XmlError { 14 | Io(io::Error), 15 | Parse(String, DeError), 16 | } 17 | 18 | #[derive(Deserialize)] 19 | pub struct AutoDiscoverXmlPayloadRequest { 20 | pub EMailAddress: Option, 21 | pub LegacyDN: Option, 22 | pub AcceptableResponseSchema: String, 23 | } 24 | 25 | #[derive(Deserialize)] 26 | pub struct AutoDiscoverXmlPayload { 27 | pub Request: AutoDiscoverXmlPayloadRequest, 28 | } 29 | 30 | pub struct AutoDiscoverXmlError { 31 | pub template: Template, 32 | } 33 | 34 | impl<'r, 'o: 'r> Responder<'r, 'o> for AutoDiscoverXmlError { 35 | fn respond_to(self, req: &'r Request<'_>) -> response::Result<'o> { 36 | Response::build_from(self.template.respond_to(req)?) 37 | .header(ContentType::XML) 38 | .status(Status::Ok) // Yes, I did curl microsoft and it sends 200 as a response code 39 | .ok() 40 | } 41 | } 42 | 43 | #[rocket::async_trait] 44 | impl<'r> FromData<'r> for AutoDiscoverXmlPayload { 45 | type Error = XmlError; 46 | 47 | async fn from_data(req: &'r Request<'_>, data: Data<'r>) -> data::Outcome<'r, Self> { 48 | use rocket::outcome::Outcome::{Error, Success}; 49 | let size_limit = req.limits().get("xml").unwrap_or(ByteUnit::Kilobyte(4096)); 50 | 51 | let contents: Result, std::io::Error> = 52 | data.open(size_limit).into_string().await; 53 | match contents { 54 | Ok(dd) => { 55 | let payload: Result = from_str(&dd); 56 | match payload { 57 | Ok(d) => Success(d), 58 | Err(e) => Error(( 59 | Status::UnprocessableEntity, 60 | XmlError::Parse(dd.to_string(), e), 61 | )), 62 | } 63 | } 64 | Err(e) => Error((Status::UnprocessableEntity, XmlError::Io(e))), 65 | } 66 | } 67 | } 68 | 69 | pub struct AutoDiscoverXml { 70 | pub template: Template, 71 | pub domain: String, 72 | } 73 | 74 | impl<'r, 'o: 'r> Responder<'r, 'o> for AutoDiscoverXml { 75 | fn respond_to(self, req: &'r Request<'_>) -> response::Result<'o> { 76 | let header_accept: Option<&str> = req.headers().get_one("Accept"); 77 | let mime_type: &str = match header_accept { 78 | Some("text/xml") => "text/xml", 79 | _ => "application/xml", 80 | }; 81 | Response::build_from(self.template.respond_to(req)?) 82 | .raw_header("Content-Type", mime_type) 83 | .ok() 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /src/resources/DnsTxtResponse.rs: -------------------------------------------------------------------------------- 1 | use rocket::request::Request; 2 | use rocket::response::{self, Responder, Response}; 3 | use rocket_dyn_templates::Template; 4 | 5 | pub struct DnsTxtResponse { 6 | pub template: Template, 7 | pub domain: String, 8 | } 9 | 10 | impl<'r, 'o: 'r> Responder<'r, 'o> for DnsTxtResponse { 11 | fn respond_to(self, req: &'r Request<'_>) -> response::Result<'o> { 12 | Response::build_from(self.template.respond_to(req)?) 13 | .raw_header("Content-Type", "text/plain; charset=utf-8") 14 | .raw_header( 15 | "Content-Disposition", 16 | "attachment; filename=\"".to_owned() + &self.domain + "-dns-zone.txt\"", 17 | ) 18 | .ok() 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/resources/Version.rs: -------------------------------------------------------------------------------- 1 | use serde::{Deserialize, Serialize}; 2 | 3 | #[derive(Serialize, Deserialize)] 4 | #[serde(rename_all = "camelCase")] 5 | pub struct Version<'a> { 6 | pub code: &'a str, 7 | pub description: String, 8 | } 9 | -------------------------------------------------------------------------------- /src/routes.rs: -------------------------------------------------------------------------------- 1 | pub mod autoconfig; 2 | pub mod dns; 3 | pub mod tech; 4 | -------------------------------------------------------------------------------- /src/routes/autoconfig.rs: -------------------------------------------------------------------------------- 1 | use crate::host_header::HostHeader; 2 | use crate::resources::AppleResponse::AppleResponse; 3 | use crate::resources::AutoDiscoverJson::{AutoDiscoverJson, AutoDiscoverJsonError}; 4 | use crate::resources::AutoDiscoverXml::{ 5 | AutoDiscoverXml, AutoDiscoverXmlError, AutoDiscoverXmlPayload, 6 | }; 7 | use crate::util::{get_config_for_domain, Config}; 8 | use chrono::Local; 9 | use rocket::serde::json::Json; 10 | use rocket_dyn_templates::{context, Template}; 11 | use std::env; 12 | 13 | fn handle_mail_config_v11(host: HostHeader) -> AutoDiscoverXml { 14 | let config: Config = get_config_for_domain(&host.base_domain); 15 | AutoDiscoverXml { 16 | domain: config.domain.to_string(), 17 | template: Template::render( 18 | "xml/config-v1.1", 19 | context! { 20 | domain: config.domain, 21 | display_name: config.display_name, 22 | imap_hostname: config.imap_hostname, 23 | pop_hostname: config.pop_hostname, 24 | smtp_hostname: config.smtp_hostname, 25 | }, 26 | ), 27 | } 28 | } 29 | 30 | // Used by Maily (tested version: 1.0.0) (de.enough.enough_mail_app: https://github.com/Enough-Software/enough_mail/blob/v2.1.1/lib/src/private/util/discover_helper.dart#L34-L58) 31 | // Used by KMail (tested version: 5.19.3 (21.12.3)) (https://github.com/KDE/kmail-account-wizard/blob/v21.12.3/src/ispdb/ispdb.cpp#L64-L90) (https://invent.kde.org/pim/kmail-account-wizard/-/blob/v21.12.3/src/ispdb/ispdb.cpp#L64-90) 32 | // Used by Thunderbird (tested version: Thunderbird 91.10.0) 33 | // Used by FairEmail (tested version: 1.1917) (https://github.com/M66B/FairEmail/blob/1.1917/app/src/main/java/eu/faircode/email/EmailProvider.java#L558) 34 | // Used by Evolution on Ubuntu (tested version: 3.40.0-1) (/mail/config-v1.1.xml?emailaddress=EVOLUTIONUSER%40wdes.fr&emailmd5=46865a3ba18ca94e2c98f15b8cf14125) (https://gitlab.gnome.org/GNOME/evolution/-/blob/3.40.1/src/mail/e-mail-autoconfig.c#L514) 35 | // Used by Spark Mail on Android (tested version: 2.11.8) 36 | // Used by MailTime on Android (tested version: 2.5.4.0614) 37 | // Used by ProfiMail on Android (tested version: 4.31.08) (https://www.lonelycatgames.com/apps/profimail) 38 | // Used by K-9 Mail on Android (tested version: 6.709, since: 6.709) 39 | #[get("/mail/config-v1.1.xml?")] 40 | #[allow(unused_variables)] 41 | pub fn mail_config_v11(host: HostHeader, emailaddress: Option<&str>) -> AutoDiscoverXml { 42 | handle_mail_config_v11(host) 43 | } 44 | 45 | // Used by Android Nine (tested version: 4.9.4b) (com.ninefolders.hd3) 46 | #[get("/v1.1/mail/config-v1.1.xml?")] 47 | #[allow(unused_variables)] 48 | pub fn v11_mail_config_v11(host: HostHeader, emailaddress: Option<&str>) -> AutoDiscoverXml { 49 | handle_mail_config_v11(host) 50 | } 51 | 52 | #[get("/.well-known/autoconfig/mail/config-v1.1.xml?")] 53 | #[allow(unused_variables)] 54 | pub fn well_known_mail_config_v11(host: HostHeader, emailaddress: Option<&str>) -> AutoDiscoverXml { 55 | handle_mail_config_v11(host) 56 | } 57 | 58 | // Used by Android Nine (tested version: 4.9.4b) (com.ninefolders.hd3) 59 | // Used by Microsoft Outlook for Android (tested version: 4.2220.1) 60 | // Used by Microsoft Office Pro Plus 2021 (tested version: 14326.20454 64 bits) 61 | 62 | // Example: /autodiscover/autodiscover.json?Email=test%40wdes.fr&Protocol=ActiveSync&RedirectCount=1 63 | // Example: /autodiscover/autodiscover.json?Email=test%40wdes.fr&Protocol=Autodiscoverv1&RedirectCount=1 64 | #[get("/autodiscover/autodiscover.json?&&")] 65 | #[allow(unused_variables)] 66 | #[allow(non_snake_case)] 67 | pub fn post_mail_autodiscover_microsoft_json( 68 | host: HostHeader, 69 | Email: Option<&str>, 70 | Protocol: Option<&str>, 71 | RedirectCount: Option<&str>, 72 | ) -> Result, AutoDiscoverJsonError> { 73 | match Protocol { 74 | Some("AutodiscoverV1") => Ok(Json(AutoDiscoverJson { 75 | Protocol: "AutodiscoverV1".to_string(), 76 | Url: "https://".to_owned() + &host.host + "/Autodiscover/Autodiscover.xml", 77 | })), 78 | Some("Autodiscoverv1") => Ok(Json(AutoDiscoverJson { 79 | Protocol: "Autodiscoverv1".to_string(), 80 | Url: "https://".to_owned() + &host.host + "/Autodiscover/Autodiscover.xml", 81 | })), 82 | /* 83 | Some("ActiveSync") => Some(AutoDiscoverJson { 84 | Protocol: "ActiveSync".to_string(), 85 | Url: "https://".to_owned() + &host.host + "/Microsoft-Server-ActiveSync", 86 | }),*/ 87 | _ => Err(AutoDiscoverJsonError { 88 | ErrorCode: "InvalidProtocol".to_string(), 89 | ErrorMessage: 90 | "The given protocol value is invalid. Supported values are \"AutodiscoverV1\" or \"Autodiscoverv1\"." 91 | .to_string(), 92 | }), 93 | } 94 | } 95 | 96 | // Used by Microsoft Office 2009 (to be confirmed) 97 | // Example: /autodiscover/autodiscover.json/v1.0/infos%40domain.tld?Protocol=ActiveSync&RedirectCount=1 98 | #[get("/autodiscover/autodiscover.json/v1.0/infos?&&")] 99 | #[allow(unused_variables)] 100 | #[allow(non_snake_case)] 101 | pub fn post_mail_autodiscover_microsoft_json_legacy( 102 | host: HostHeader, 103 | Email: Option<&str>, 104 | Protocol: Option<&str>, 105 | RedirectCount: Option<&str>, 106 | ) -> Result, AutoDiscoverJsonError> { 107 | match Protocol { 108 | Some("AutodiscoverV1") => Ok(Json(AutoDiscoverJson { 109 | Protocol: "AutodiscoverV1".to_string(), 110 | Url: "https://".to_owned() + &host.host + "/Autodiscover/Autodiscover.xml", 111 | })), 112 | Some("Autodiscoverv1") => Ok(Json(AutoDiscoverJson { 113 | Protocol: "Autodiscoverv1".to_string(), 114 | Url: "https://".to_owned() + &host.host + "/Autodiscover/Autodiscover.xml", 115 | })), 116 | /* 117 | Some("ActiveSync") => Some(AutoDiscoverJson { 118 | Protocol: "ActiveSync".to_string(), 119 | Url: "https://".to_owned() + &host.host + "/Microsoft-Server-ActiveSync", 120 | }),*/ 121 | _ => Err(AutoDiscoverJsonError { 122 | ErrorCode: "InvalidProtocol".to_string(), 123 | ErrorMessage: 124 | "The given protocol value is invalid. Supported values are \"AutodiscoverV1\" or \"Autodiscoverv1\"." 125 | .to_string(), 126 | }), 127 | } 128 | } 129 | 130 | fn autodiscover_microsoft( 131 | host: HostHeader, 132 | payload: Option, 133 | ) -> Result { 134 | let config: Config = get_config_for_domain(&host.base_domain); 135 | // TODO: http://schemas.microsoft.com/exchange/autodiscover/mobilesync/responseschema/2006 136 | match payload { 137 | Some(p) => match p.Request.AcceptableResponseSchema.as_str() { 138 | "http://schemas.microsoft.com/exchange/autodiscover/outlook/responseschema/2006a" => { 139 | Ok(AutoDiscoverXml { 140 | domain: config.domain.to_string(), 141 | template: Template::render( 142 | "xml/autodiscover", 143 | context! { 144 | domain: config.domain, 145 | display_name: config.display_name, 146 | imap_hostname: config.imap_hostname, 147 | pop_hostname: config.pop_hostname, 148 | smtp_hostname: config.smtp_hostname, 149 | }, 150 | ), 151 | }) 152 | } 153 | _ => { 154 | let date = Local::now(); 155 | Err(AutoDiscoverXmlError { 156 | template: Template::render( 157 | "xml/autodiscover-error", 158 | context! { 159 | time: date.format("%H:%M:%S").to_string(), 160 | id: date.format("%s").to_string(), 161 | }, 162 | ), 163 | }) 164 | } 165 | }, 166 | None => Ok(AutoDiscoverXml { 167 | domain: config.domain.to_string(), 168 | template: Template::render( 169 | "xml/autodiscover", 170 | context! { 171 | domain: config.domain, 172 | display_name: config.display_name, 173 | imap_hostname: config.imap_hostname, 174 | pop_hostname: config.pop_hostname, 175 | smtp_hostname: config.smtp_hostname, 176 | }, 177 | ), 178 | }), 179 | } 180 | } 181 | 182 | // Used by Android MyMail (tested version: 14.26.0.37052) (com.my.mail) 183 | // Used by Android Spike Email (tested version: 3.5.7.0) (com.pingapp.app) 184 | // Used by Microsoft Outlook for Android (tested version: 4.2220.1) 185 | // Used by Microsoft Office Pro Plus 2013 (tested version: 15.0.5399.1000 64 bits) 186 | // Used by Microsoft Office Pro Plus 2021 (tested version: 14326.20454 64 bits) 187 | #[get("/autodiscover/autodiscover.xml")] 188 | pub fn mail_autodiscover_microsoft( 189 | host: HostHeader, 190 | ) -> Result { 191 | autodiscover_microsoft(host, None) 192 | } 193 | 194 | #[get("/Autodiscover/Autodiscover.xml")] 195 | pub fn mail_autodiscover_microsoft_case( 196 | host: HostHeader, 197 | ) -> Result { 198 | autodiscover_microsoft(host, None) 199 | } 200 | 201 | #[get("/AutoDiscover/AutoDiscover.xml")] 202 | pub fn mail_autodiscover_microsoft_camel_case( 203 | host: HostHeader, 204 | ) -> Result { 205 | autodiscover_microsoft(host, None) 206 | } 207 | 208 | // Used by Thunderbird (tested version: 91.10.0) 209 | // Used by Microsoft Outlook for Android (tested version: 4.2220.1) 210 | // Used by Microsoft Office Pro Plus 2013 (tested version: 15.0.5399.1000 64 bits) 211 | // Used by Microsoft Office Pro Plus 2021 (tested version: 14326.20454 64 bits) 212 | // Used by Microsoft Office 2009 (to be confirmed) 213 | #[post("/autodiscover/autodiscover.xml", data = "")] 214 | pub fn post_mail_autodiscover_microsoft( 215 | host: HostHeader, 216 | payload: AutoDiscoverXmlPayload, 217 | ) -> Result { 218 | autodiscover_microsoft(host, Some(payload)) 219 | } 220 | 221 | #[post("/Autodiscover/Autodiscover.xml", data = "")] 222 | pub fn post_mail_autodiscover_microsoft_case( 223 | host: HostHeader, 224 | payload: AutoDiscoverXmlPayload, 225 | ) -> Result { 226 | autodiscover_microsoft(host, Some(payload)) 227 | } 228 | 229 | #[post("/AutoDiscover/AutoDiscover.xml", data = "")] 230 | pub fn post_mail_autodiscover_microsoft_camel_case( 231 | host: HostHeader, 232 | payload: AutoDiscoverXmlPayload, 233 | ) -> Result { 234 | autodiscover_microsoft(host, Some(payload)) 235 | } 236 | 237 | // iOS / Apple Mail (/email.mobileconfig?email=username@domain.com or /email.mobileconfig?email=username) 238 | #[get("/email.mobileconfig?")] 239 | pub fn mail_autodiscover_apple_mobileconfig(host: HostHeader, email: &str) -> AppleResponse { 240 | let config: Config = get_config_for_domain(&host.base_domain); 241 | let mail_uuid: String = env::var("APPLE_MAIL_UUID").expect("APPLE_MAIL_UUID must be set"); 242 | let profile_uuid: String = 243 | env::var("APPLE_PROFILE_UUID").expect("APPLE_PROFILE_UUID must be set"); 244 | 245 | // See :https://developer.apple.com/business/documentation/Configuration-Profile-Reference.pdf 246 | AppleResponse { 247 | domain: config.domain.to_string(), 248 | template: Template::render( 249 | "xml/email_mobileconfig", 250 | context! { 251 | domain: config.domain, 252 | display_name: config.display_name, 253 | imap_hostname: config.imap_hostname, 254 | pop_hostname: config.pop_hostname, 255 | smtp_hostname: config.smtp_hostname, 256 | email_address: email, 257 | username: email, 258 | mail_uuid: mail_uuid, 259 | profile_uuid: profile_uuid, 260 | }, 261 | ), 262 | } 263 | } 264 | 265 | #[cfg(test)] 266 | mod tests { 267 | use super::*; 268 | 269 | #[test] 270 | fn test_get_config_for_domain() { 271 | temp_env::with_vars( 272 | vec![ 273 | ("CUSTOM_DOMAINS", Some("foo.tld")), 274 | ("IMAP_HOSTNAME", Some("imap.foo.tld")), 275 | ("POP_HOSTNAME", Some("pop.example.tld")), 276 | ("SMTP_HOSTNAME", Some("smtp.domain.tld")), 277 | ], 278 | || { 279 | assert_eq!( 280 | Config { 281 | domain: "foo.tld", 282 | display_name: "foo.tld Mail".to_string(), 283 | imap_hostname: "imap.foo.tld".to_string(), 284 | pop_hostname: "pop.foo.tld".to_string(), 285 | smtp_hostname: "smtp.foo.tld".to_string(), 286 | }, 287 | get_config_for_domain("foo.tld") 288 | ); 289 | }, 290 | ); 291 | temp_env::with_vars( 292 | vec![ 293 | ("CUSTOM_DOMAINS", Some("foo.bar")), 294 | ("IMAP_HOSTNAME", Some("imap.custom.tld")), 295 | ("POP_HOSTNAME", Some("pop.example.tld")), 296 | ("SMTP_HOSTNAME", Some("smtp.domain.tld")), 297 | ], 298 | || { 299 | assert_eq!( 300 | Config { 301 | domain: "foo.tld", 302 | display_name: "foo.tld Mail".to_string(), 303 | imap_hostname: "imap.custom.tld".to_string(), 304 | pop_hostname: "pop.example.tld".to_string(), 305 | smtp_hostname: "smtp.domain.tld".to_string(), 306 | }, 307 | get_config_for_domain("foo.tld") 308 | ); 309 | }, 310 | ); 311 | temp_env::with_vars( 312 | vec![ 313 | ("IMAP_HOSTNAME", Some("imap.custom.tld")), 314 | ("POP_HOSTNAME", Some("pop.example.tld")), 315 | ("SMTP_HOSTNAME", Some("smtp.domain.tld")), 316 | ], 317 | || { 318 | assert_eq!( 319 | Config { 320 | domain: "foo.tld", 321 | display_name: "foo.tld Mail".to_string(), 322 | imap_hostname: "imap.custom.tld".to_string(), 323 | pop_hostname: "pop.example.tld".to_string(), 324 | smtp_hostname: "smtp.domain.tld".to_string(), 325 | }, 326 | get_config_for_domain("foo.tld") 327 | ); 328 | }, 329 | ); 330 | } 331 | } 332 | -------------------------------------------------------------------------------- /src/routes/dns.rs: -------------------------------------------------------------------------------- 1 | use crate::host_header::HostHeader; 2 | use crate::resources::DnsTxtResponse::DnsTxtResponse; 3 | use crate::util::{get_config_for_domain, Config}; 4 | use rocket_dyn_templates::{context, Template}; 5 | 6 | #[get("/dns-zone")] 7 | pub fn dns_txt_zone(host: HostHeader) -> DnsTxtResponse { 8 | let config: Config = get_config_for_domain(&host.base_domain); 9 | 10 | // See :https://developer.apple.com/business/documentation/Configuration-Profile-Reference.pdf 11 | DnsTxtResponse { 12 | domain: config.domain.to_string(), 13 | template: Template::render( 14 | "dns/zone", 15 | context! { 16 | imap_hostname: config.imap_hostname, 17 | pop_hostname: config.pop_hostname, 18 | smtp_hostname: config.smtp_hostname, 19 | }, 20 | ), 21 | } 22 | } 23 | 24 | #[cfg(test)] 25 | mod tests { 26 | use super::*; 27 | } 28 | -------------------------------------------------------------------------------- /src/routes/tech.rs: -------------------------------------------------------------------------------- 1 | use crate::host_header::HostHeader; 2 | use crate::resources::Version::Version; 3 | use rocket::serde::json::Json; 4 | use rocket_dyn_templates::{context, Template}; 5 | 6 | #[get("/")] 7 | pub fn index(host: HostHeader) -> Template { 8 | Template::render( 9 | "index", 10 | context! { 11 | name: host.base_domain 12 | }, 13 | ) 14 | } 15 | 16 | #[get("/apple")] 17 | pub fn apple(host: HostHeader) -> Template { 18 | Template::render( 19 | "apple", 20 | context! { 21 | name: host.base_domain 22 | }, 23 | ) 24 | } 25 | 26 | #[get("/robots.txt")] 27 | pub fn robots() -> &'static str { 28 | "User-agent: *\nDisallow: /\n" 29 | } 30 | 31 | #[get("/version")] 32 | pub fn version() -> Json> { 33 | Json(Version { 34 | code: env!("CARGO_PKG_VERSION"), 35 | description: "Wdes Mail AutoDiscover-AutoConfig (https://github.com/wdes/mail-autodiscover-autoconfig)".to_string(), 36 | }) 37 | } 38 | 39 | #[get("/ping")] 40 | pub fn ping() -> &'static str { 41 | "pong" 42 | } 43 | -------------------------------------------------------------------------------- /src/util.rs: -------------------------------------------------------------------------------- 1 | use std::env; 2 | 3 | #[derive(Eq, PartialEq, Debug)] 4 | pub struct Config<'a> { 5 | pub domain: &'a str, 6 | pub display_name: String, 7 | pub imap_hostname: String, 8 | pub pop_hostname: String, 9 | pub smtp_hostname: String, 10 | } 11 | 12 | pub fn get_custom_domains_list() -> String { 13 | match env::var("CUSTOM_DOMAINS") { 14 | Ok(custom_domains) => custom_domains, 15 | _ => "".to_string(), 16 | } 17 | } 18 | 19 | pub fn get_config_for_domain(domain: &str) -> Config { 20 | let is_custom_host: bool = get_custom_domains_list() 21 | .split(',') 22 | .collect::>() 23 | .contains(&domain); 24 | 25 | if is_custom_host { 26 | return Config { 27 | domain: domain, 28 | display_name: domain.to_owned() + " Mail", 29 | imap_hostname: "imap.".to_owned() + &domain.to_owned(), 30 | pop_hostname: "pop.".to_owned() + &domain.to_owned(), 31 | smtp_hostname: "smtp.".to_owned() + &domain.to_owned(), 32 | }; 33 | } 34 | 35 | let imap_hostname: String = env::var("IMAP_HOSTNAME").expect("IMAP_HOSTNAME must be set"); 36 | let pop_hostname: String = env::var("POP_HOSTNAME").expect("IMAP_HOSTNAME must be set"); 37 | let smtp_hostname: String = env::var("SMTP_HOSTNAME").expect("IMAP_HOSTNAME must be set"); 38 | 39 | Config { 40 | domain: domain, 41 | display_name: domain.to_owned() + " Mail", 42 | imap_hostname: imap_hostname, 43 | pop_hostname: pop_hostname, 44 | smtp_hostname: smtp_hostname, 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /templates/apple.html.tera: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | {{ name }} email AutoDiscover-AutoConfig | Apple 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 |
21 |
22 | 23 |
24 |

Setup for Apple

25 |
26 |
27 |
28 |
29 | 30 | 31 |
32 | 33 |
34 |
35 |
36 |
37 | 38 | 41 |
42 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /templates/dns/zone.txt.tera: -------------------------------------------------------------------------------- 1 | ; This are the records according to RFC6186 2 | _imap._tcp.{{ domain }}. SRV 0 1 143 {{ imap_hostname }}. 3 | _imaps._tcp.{{ domain }}. SRV 0 1 993 {{ imap_hostname }}. 4 | _pop3._tcp.{{ domain }}. SRV 0 1 110 {{ pop_hostname }}. 5 | _pop3s._tcp.{{ domain }}. SRV 0 1 995 {{ pop_hostname }}. 6 | _submission._tcp.{{ domain }}. SRV 0 1 587 {{ smtp_hostname }}. 7 | _submission._tcp.{{ domain }}. SRV 0 2 25 {{ smtp_hostname }}. 8 | ; This is a record according to RFC8314 9 | _submissions._tcp.{{ domain }}. SRV 0 1 465 {{ smtp_hostname }}. 10 | ; This is a Microsoft Exchange record 11 | ; See: https://docs.microsoft.com/en-us/exchange/client-developer/exchange-web-services/autodiscover-for-exchange#querying-dns-for-an-srv-record 12 | _autodiscover._tcp.{{ domain }}. SRV 0 1 443 autodiscover.{{ domain }}. 13 | ; This is Thunderbird specific autodiscovery records 14 | ; See: https://wiki.mozilla.org/Thunderbird:Autoconfiguration:DNSBasedLookup 15 | {{ domain }}. IN TXT "mailconf=https://autodiscover.{{ domain }}/mail/config-v1.1.xml" 16 | -------------------------------------------------------------------------------- /templates/index.html.tera: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | {{ name }} email AutoDiscover-AutoConfig 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 |
21 |
22 | 23 |
24 |

{{ name }} email AutoDiscover-AutoConfig

25 |
26 | 27 | 31 |
32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /templates/xml/autodiscover-error.xml.tera: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 601 6 | Provider is not available 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /templates/xml/autodiscover-mobilesync.xml.tera: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | en:en 5 | 6 | {{ display_name }} 7 | {{ email_address }} 8 | 9 | 10 | 11 | 12 | MobileSync 13 | https://example.org/TODOmobilesyncURL 14 | TODO: Mobile sync name 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /templates/xml/autodiscover.xml.tera: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | email 6 | settings 7 | 8 | 9 | IMAP 10 | {{ imap_hostname }} 11 | 993 12 | on 13 | {{ domain }} 14 | off 15 | on 16 | on 17 | 18 | 19 | 20 | POP3 21 | {{ pop_hostname }} 22 | 995 23 | on 24 | {{ domain }} 25 | off 26 | on 27 | on 28 | 29 | 30 | 31 | SMTP 32 | {{ smtp_hostname }} 33 | 465 34 | on 35 | {{ domain }} 36 | off 37 | on 38 | on 39 | 40 | 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /templates/xml/config-v1.1.xml.tera: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | {{ domain }} 6 | {{ display_name }} 7 | %EMAILLOCALPART% 8 | 9 | 10 | {{ imap_hostname }} 11 | 993 12 | SSL 13 | password-cleartext 14 | %EMAILADDRESS% 15 | 16 | 17 | {{ imap_hostname }} 18 | 143 19 | STARTTLS 20 | password-cleartext 21 | %EMAILADDRESS% 22 | 23 | 24 | 25 | {{ pop_hostname }} 26 | 995 27 | SSL 28 | password-cleartext 29 | %EMAILADDRESS% 30 | false 31 | true 32 | 0 33 | 34 | 35 | {{ pop_hostname }} 36 | 110 37 | STARTTLS 38 | password-cleartext 39 | %EMAILADDRESS% 40 | false 41 | true 42 | 0 43 | 44 | 45 | 46 | {{ smtp_hostname }} 47 | 465 48 | SSL 49 | password-cleartext 50 | %EMAILADDRESS% 51 | 52 | 53 | {{ smtp_hostname }} 54 | 587 55 | STARTTLS 56 | password-cleartext 57 | %EMAILADDRESS% 58 | 59 | 60 | 61 | 62 | -------------------------------------------------------------------------------- /templates/xml/email_mobileconfig.tera: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PayloadContent 6 | 7 | 8 | EmailAccountDescription 9 | {{ display_name }} 10 | EmailAccountName 11 | {{ display_name }} 12 | EmailAccountType 13 | EmailTypeIMAP 14 | EmailAddress 15 | {{ email_address }} 16 | IncomingMailServerAuthentication 17 | EmailAuthPassword 18 | IncomingMailServerHostName 19 | {{ imap_hostname }} 20 | IncomingMailServerPortNumber 21 | 993 22 | IncomingMailServerUseSSL 23 | 24 | IncomingMailServerUsername 25 | {{ username }} 26 | OutgoingMailServerAuthentication 27 | EmailAuthPassword 28 | OutgoingMailServerHostName 29 | {{ smtp_hostname }} 30 | OutgoingMailServerPortNumber 31 | 465 32 | OutgoingMailServerUseSSL 33 | 34 | OutgoingMailServerUsername 35 | {{ username }} 36 | OutgoingPasswordSameAsIncomingPassword 37 | 38 | PayloadDescription 39 | Email account configuration for {{ email_address }} 40 | PayloadDisplayName 41 | {{ display_name }} 42 | PayloadIdentifier 43 | {{ domain }}.autoconfig.{{ profile_uuid }} 44 | PayloadType 45 | com.apple.mail.managed 46 | PayloadUUID 47 | {{ profile_uuid }} 48 | PayloadVersion 49 | 1 50 | SMIMEEnablePerMessageSwitch 51 | 52 | SMIMEEnabled 53 | 54 | SMIMESigningEnabled 55 | 56 | disableMailRecentsSyncing 57 | 58 | 59 | 60 | PayloadDescription 61 | Email account configuration for {{ email_address }} 62 | PayloadDisplayName 63 | {{ display_name }} 64 | PayloadIdentifier 65 | {{ domain }}.autoconfig.{{ mail_uuid }} 66 | PayloadOrganization 67 | {{ domain }} 68 | PayloadRemovalDisallowed 69 | 70 | PayloadType 71 | Configuration 72 | PayloadUUID 73 | {{ mail_uuid }} 74 | PayloadVersion 75 | 1 76 | 77 | 78 | -------------------------------------------------------------------------------- /xml/autodiscover/AutodiscoverExchangeResponse.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Donald Duck 5 | /o=ExchangeLabs/ou=Exchange Administrative Group (FYDIBOHF23SPDLT)/cn=Recipients/cn=9f0941f88f5546569c87b8ed3a90bec9-duck 6 | duck@duckburg.onmicrosoft.com 7 | 00de18b9-994a-4124-960a-bd8968414491 8 | 9 | 10 | email 11 | settings 12 | True 13 | 14 | EXCH 15 | 12f2c1c5-cf63-4584-a64b-e2e369b32285@duckburg.onmicrosoft.com 16 | /o=ExchangeLabs/ou=Exchange Administrative Group (FYDIBOHF23SPDLT)/cn=Configuration/cn=Servers/cn=12f2c1c5-cf63-4584-a64b-e2e369b32285@duckburg.onmicrosoft.com 17 | 73C18193 18 | /o=ExchangeLabs/ou=Exchange Administrative Group (FYDIBOHF23SPDLT)/cn=Configuration/cn=Servers/cn=12f2c1c5-cf63-4584-a64b-e2e369b32285@duckburg.onmicrosoft.com/cn=Microsoft Private MDB 19 | outlook.office365.com 20 | Anonymous 21 | https://outlook.office365.com/EWS/Exchange.asmx 22 | https://outlook.office365.com/EWS/Exchange.asmx 23 | https://outlook.office365.com/EWS/Exchange.asmx 24 | https://outlook.office365.com/EWS/Exchange.asmx 25 | https://outlook.office365.com/owa/ 26 | ?path=/options/callanswering 27 | ?path=/options/connectedaccounts 28 | options/ecp/PersonalSettings/DeliveryReport.aspx?rfr=olk&exsvurl=1&IsOWA=<IsOWA>&MsgID=<MsgID>&Mbx=<Mbx>&realm=duckburg.onmicrosoft.com 29 | ?path=/options/retentionpolicies 30 | ?path=/options/textmessaging 31 | ?path=/options/calendarpublishing/id/<FldID> 32 | https://outlook.office365.com/EWS/Exchange.asmx 33 | https://outlook.office365.com/EWS/UM2007Legacy.asmx 34 | https://outlook.office365.com/OAB/646f1f11-3801-40d4-bed8-7122e3812ed4/ 35 | off 36 | 37 | 38 | EXPR 39 | outlook.office365.com 40 | On 41 | Basic 42 | https://outlook.another.office365.com/EWS/Exchange.asmx 43 | https://outlook.office365.com/EWS/Exchange.asmx 44 | https://outlook.office365.com/EWS/Exchange.asmx 45 | https://outlook.office365.com/EWS/Exchange.asmx 46 | https://outlook.office365.com/owa/ 47 | ?path=/options/callanswering 48 | ?path=/options/connectedaccounts 49 | options/ecp/PersonalSettings/DeliveryReport.aspx?rfr=olk&exsvurl=1&IsOWA=<IsOWA>&MsgID=<MsgID>&Mbx=<Mbx>&realm=duckburg.onmicrosoft.com 50 | ?path=/options/retentionpolicies 51 | ?path=/options/textmessaging 52 | ?path=/options/calendarpublishing/id/<FldID> 53 | https://outlook.office365.com/EWS/Exchange.asmx 54 | https://outlook.office365.com/EWS/UM2007Legacy.asmx 55 | https://outlook.office365.com/OAB/646f1f11-3801-40d4-bed8-7122e3812ed4/ 56 | on 57 | msstd:outlook.com 58 | https://outlook.office365.com/EWS/Exchange.asmx 59 | VI1PR09 60 | 61 | 62 | WEB 63 | 64 | https://outlook.office365.com/owa/ 65 | 66 | EXCH 67 | https://outlook.office365.com/EWS/Exchange.asmx 68 | 69 | 70 | 71 | https://outlook.office365.com/owa/duckburg.onmicrosoft.com/ 72 | 73 | EXPR 74 | https://outlook.office365.com/EWS/Exchange.asmx 75 | 76 | 77 | 78 | 79 | 80 | 81 | -------------------------------------------------------------------------------- /xml/autodiscover/AutodiscoverRequest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | test@example.org 5 | http://schemas.microsoft.com/exchange/autodiscover/outlook/responseschema/2006a 6 | 7 | 8 | -------------------------------------------------------------------------------- /xml/autodiscover/AutodiscoverResponse.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | 8 | 11 | 12 | Test email account 13 | 14 | 15 | 18 | 19 | 25 | email 26 | 27 | 34 | settings 35 | 36 | 39 | 40 | 49 | IMAP 50 | 51 | 56 | mail.szepe.net 57 | 58 | 59 | 62 | 993 63 | 64 | 67 | on 68 | 69 | 72 | @@DOMAIN@@ 73 | 74 | 78 | off 79 | 80 | 84 | on 85 | 86 | 90 | on 91 | 92 | 93 | 94 | 95 | SMTP 96 | mail.szepe.net 97 | 465 98 | on 99 | @@DOMAIN@@ 100 | off 101 | on 102 | on 103 | 104 | 105 | 106 | 107 | 108 | -------------------------------------------------------------------------------- /xml/autodiscover/AutodiscoverResponseError.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 601 6 | The AcceptableResponseSchema is not supported 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /xml/autodiscover/AutodiscoverResponseRedirect.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | email 6 | redirectUrl 7 | https://example.org/Autodiscover/Autodiscover.xml 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /xml/mobilesync/AutodiscoverRequest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | test@example.org 5 | http://schemas.microsoft.com/exchange/autodiscover/mobilesync/responseschema/2006 6 | 7 | 8 | -------------------------------------------------------------------------------- /xml/xsd/autodiscover/AutodiscoverExchangeResponse.xsd: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | -------------------------------------------------------------------------------- /xml/xsd/autodiscover/AutodiscoverExchangeResponseRedirect.xsd: -------------------------------------------------------------------------------- 1 | 2 | 10 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /xml/xsd/autodiscover/AutodiscoverRequest.xsd: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /xml/xsd/autodiscover/AutodiscoverResponse.xsd: -------------------------------------------------------------------------------- 1 | 2 | 10 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /xml/xsd/autodiscover/AutodiscoverResponseError.xsd: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /xml/xsd/autodiscover/AutodiscoverResponseRedirect.xsd: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /xml/xsd/mobilesync/AutodiscoverMobileSyncResponse.xsd: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | -------------------------------------------------------------------------------- /xml/xsd/mobilesync/AutodiscoverRequest.xsd: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /xml/xsd/mobilesync/AutodiscoverResponse.xsd: -------------------------------------------------------------------------------- 1 | 2 | 10 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | --------------------------------------------------------------------------------