├── .deepsource.toml
├── .editorconfig
├── .github
├── FUNDING.yml
├── ISSUE_TEMPLATE
│ ├── bug_report.md
│ └── feature_request.md
├── dependabot.yml
└── workflows
│ ├── build.yml
│ ├── dependabot.yml
│ ├── main.yml
│ ├── pull_request.yml
│ ├── release.yml
│ ├── stale.yml
│ └── test.yml
├── .gitignore
├── Cargo.lock
├── Cargo.toml
├── LICENSE
├── Makefile
├── README.md
├── SECURITY.md
├── axolotl-web
├── .depcheckrc.yaml
├── .editorconfig
├── .gitignore
├── .nvmrc
├── LICENSE
├── README.md
├── eslint.config.js
├── gettext.config.cjs
├── index.html
├── jsconfig.json
├── package.json
├── public
│ ├── axolotl.ico
│ ├── axolotl.png
│ └── favicon.ico
├── src
│ ├── App.vue
│ ├── assets
│ │ ├── dark.scss
│ │ ├── fonts
│ │ │ ├── ubuntu-r-webfont.woff
│ │ │ └── ubuntu-r-webfont.woff2
│ │ ├── images
│ │ │ ├── check-circle-outline.svg
│ │ │ ├── check-circle-outline_dark.svg
│ │ │ ├── double-check-filled.svg
│ │ │ ├── double-check-filled_dark.svg
│ │ │ ├── double-check.svg
│ │ │ ├── double-check_dark.svg
│ │ │ ├── loading.svg
│ │ │ ├── play.svg
│ │ │ ├── sending.svg
│ │ │ ├── sending_dark.svg
│ │ │ └── warning.svg
│ │ ├── light.scss
│ │ ├── logo.png
│ │ └── style.scss
│ ├── components
│ │ ├── AddContactModal.vue
│ │ ├── AddDeviceModal.vue
│ │ ├── AddGroupMembersModal.vue
│ │ ├── AttachmentBar.vue
│ │ ├── ConfirmationModal.vue
│ │ ├── EditContactModal.vue
│ │ ├── ErrorModal.vue
│ │ ├── IdentityModal.vue
│ │ ├── ImportUnavailableModal.vue
│ │ ├── ImportVcfModal.vue
│ │ ├── LegacyHeader.vue
│ │ ├── Message.vue
│ │ └── VerificationPinInput.vue
│ ├── config.js
│ ├── helpers
│ │ └── uuidCheck.js
│ ├── layouts
│ │ ├── Default.vue
│ │ └── Legacy.vue
│ ├── main.js
│ ├── pages
│ │ ├── About.vue
│ │ ├── ChatList.vue
│ │ ├── Contacts.vue
│ │ ├── Debug.vue
│ │ ├── DeviceLinking.vue
│ │ ├── DeviceList.vue
│ │ ├── EditContact.vue
│ │ ├── EditGroup.vue
│ │ ├── MessageList.vue
│ │ ├── NewGroup.vue
│ │ ├── OnBoarding.vue
│ │ ├── Password.vue
│ │ ├── Profile.vue
│ │ ├── Register.vue
│ │ ├── SetPassword.vue
│ │ ├── SetUsername.vue
│ │ ├── Settings.vue
│ │ └── Verification.vue
│ ├── router
│ │ └── router.js
│ └── store
│ │ └── store.js
├── tests
│ └── unit
│ │ └── components
│ │ └── Message.spec.js
├── translations
│ └── translations.json
├── vite.config.js
├── vitest.config.js
└── yarn.lock
├── build.rs
├── click
├── axolotl-helper
├── axolotl-push-helper.json
├── axolotl-push.apparmor
├── axolotl.apparmor
├── axolotl.content-hub
├── axolotl.desktop
├── axolotl.png
├── axolotl.url-dispatcher
└── notification.sh
├── clickable.yaml
├── data
├── axolotl.desktop
├── axolotl.metainfo.xml
└── icons
│ ├── icon.icns
│ ├── icon.ico
│ └── icon.png
├── docs
├── CHANGELOG.md
├── DEBUG.md
├── INSTALL.md
├── NOTES.md
├── TRANSLATE.md
└── architecture.png
├── examples
└── dump
│ ├── Cargo.toml
│ └── dump_db.rs
├── flatpak
├── README.md
├── cargo-sources.json
├── node-sources.json
└── org.nanuc.Axolotl.yml
├── guis
└── qml
│ └── ut
│ └── MainUt.qml
├── manifest.json
├── po
├── LINGUAS
├── POTFILES
├── ar.po
├── be.po
├── bg.po
├── cs.po
├── da.po
├── de.po
├── el.po
├── es.po
├── fa.po
├── fi.po
├── fr.po
├── hr.po
├── hu.po
├── in.po
├── it.po
├── iw.po
├── ja.po
├── kn-rIN.po
├── ko.po
├── mk.po
├── nb.po
├── nl.po
├── no.po
├── pl.po
├── pt-BR.po
├── pt.po
├── ro.po
├── ru.po
├── sk.po
├── sl.po
├── sr.po
├── sv.po
├── ta.po
├── textsecure.nanuc.pot
├── tr.po
├── vi.po
└── zh-rCN.po
├── screenshot.png
├── snap
├── gui
│ ├── axolotl.desktop
│ └── axolotl.png
└── snapcraft.yaml
├── src
├── error.rs
├── handlers.rs
├── handlers
│ └── registration.rs
├── lib.rs
├── main.rs
├── manager_thread.rs
├── messages.rs
└── requests.rs
├── tauri.conf.json
└── vetur.config.js
/.deepsource.toml:
--------------------------------------------------------------------------------
1 | version = 1
2 |
3 | [[analyzers]]
4 | name = "rust"
5 |
6 | [analyzers.meta]
7 | msrv = "stable"
8 |
9 | [[analyzers]]
10 | name = "javascript"
11 |
12 | [analyzers.meta]
13 | plugins = ["vue"]
14 | environment = [
15 | "mocha",
16 | "vitest"
17 | ]
18 |
19 | [[transformers]]
20 | name = "prettier"
21 |
22 | [[transformers]]
23 | name = "rustfmt"
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | # Editor configuration, see https://editorconfig.org
2 |
3 | root = true
4 |
5 | [*]
6 | indent_style = space
7 | indent_size = 2
8 | end_of_line = lf
9 | trim_trailing_whitespace = true
10 | insert_final_newline = true
11 | max_line_length = 100
12 |
--------------------------------------------------------------------------------
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | # These are supported funding model platforms
2 | patreon: nanuc
3 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/bug_report.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Bug report
3 | about: Create a report to help us improve
4 | title: "[BUG]"
5 | labels: ''
6 | assignees: ''
7 |
8 | ---
9 |
10 | ### Description
11 |
12 | [Description of the issue]
13 |
14 | ### Steps to Reproduce
15 |
16 | 1. [First Step]
17 | 2. [Second Step]
18 | 3. [and so on...]
19 |
20 | **Expected behavior:** [What you expect to happen]
21 |
22 | **Actual behavior:** [What actually happens]
23 |
24 | #### Versions
25 |
26 | Please provide the Version as written in `Settings->About Axolotl`
27 |
28 | #### Device
29 | What device or OS are you using?
30 |
31 | #### Link to Debug Log
32 | Please provide a link to debug from ~/.cache/upstart/application-click-axolotl.nanuc_axolotl*.log
33 | Be careful it contains sensible data
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/feature_request.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Feature request
3 | about: Suggest an idea for this project
4 | title: ''
5 | labels: ''
6 | assignees: ''
7 |
8 | ---
9 |
10 | **Is your feature request related to a problem? Please describe.**
11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
12 |
13 | **Describe the solution you'd like**
14 | A clear and concise description of what you want to happen.
15 |
16 | **Describe alternatives you've considered**
17 | A clear and concise description of any alternative solutions or features you've considered.
18 |
19 | **Additional context**
20 | Add any other context or screenshots about the feature request here.
21 |
--------------------------------------------------------------------------------
/.github/dependabot.yml:
--------------------------------------------------------------------------------
1 | # Please see the documentation for all configuration options:
2 | # https://help.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
3 |
4 | version: 2
5 | updates:
6 | - package-ecosystem: "npm"
7 | directory: "/axolotl-web"
8 | schedule:
9 | interval: "daily"
10 | - package-ecosystem: "github-actions"
11 | directory: "/"
12 | schedule:
13 | interval: "daily"
14 | - package-ecosystem: "cargo"
15 | directory: "/"
16 | schedule:
17 | interval: "daily"
18 |
--------------------------------------------------------------------------------
/.github/workflows/dependabot.yml:
--------------------------------------------------------------------------------
1 | name: Dependabot post-run
2 |
3 | on: pull_request
4 |
5 | concurrency:
6 | group: ${{ github.workflow }}-${{ github.ref }}
7 | cancel-in-progress: true
8 |
9 | jobs:
10 | flatpak-sources-update:
11 | name: Update Flatpak sources
12 | # Avoid infinit loops of this workflow pushing and triggering another workflow
13 | # We do want to run the other workflows to build and test but do not want to run this one again.
14 | # https://github.com/stefanzweifel/git-auto-commit-action?tab=readme-ov-file#prevent-infinite-loop-when-using-a-personal-access-token
15 | if: github.actor == 'dependabot[bot]'
16 | runs-on: ubuntu-latest
17 | steps:
18 | - uses: actions/checkout@v4
19 | with:
20 | # Using an SSH deploy key to allow running workflows triggered by push event
21 | # https://github.com/stefanzweifel/git-auto-commit-action?tab=readme-ov-file#commits-made-by-this-action-do-not-trigger-new-workflow-runs
22 | # NOTE for actions triggered by dependabot, only the dependabot secrets are available
23 | # https://docs.github.com/en/code-security/dependabot/working-with-dependabot/automating-dependabot-with-github-actions#responding-to-events
24 | ssh-key: "${{ secrets.DEPENDABOT_SSH_KEY }}"
25 | # Fetch whole history as we want to commit and push
26 | fetch-depth: 0
27 |
28 | - name: Download flatpak-builder-tools
29 | run: |
30 | curl -L https://github.com/flatpak/flatpak-builder-tools/archive/refs/heads/master.tar.gz | tar xz
31 | mv flatpak-builder-tools-master flatpak-builder-tools
32 |
33 | - name: Install flatpak-builder-tools dependencies
34 | run: |
35 | sudo apt install -y pipx python3 python3-aiohttp python3-toml python3-yaml
36 |
37 | - name: Update NodeJS sources
38 | working-directory: flatpak-builder-tools/node
39 | run: |
40 | pipx install .
41 | flatpak-node-generator yarn ${{ github.workspace }}/axolotl-web/yarn.lock -o ${{ github.workspace }}/flatpak/node-sources.json
42 |
43 | - name: Update Cargo sources
44 | working-directory: flatpak-builder-tools/cargo
45 | run: python3 flatpak-cargo-generator.py ${{ github.workspace }}/Cargo.lock -o ${{ github.workspace }}/flatpak/cargo-sources.json
46 |
47 | - uses: stefanzweifel/git-auto-commit-action@v5
48 | with:
49 | # Ignore other changes like the cloned flatpak-builder-tools repo
50 | file_pattern: "flatpak/*-sources.json"
51 | # Do not block dependabot from updating this PR: https://github.com/dependabot/dependabot-core/issues/1758
52 | commit_message: "[dependabot skip] Update Flatpak sources"
53 | commit_author: "github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>"
54 | # Do not overwrite in case our version is outdated
55 | push_options: "--force-with-lease"
56 |
57 | auto-approve:
58 | if: github.actor == 'dependabot[bot]'
59 | runs-on: ubuntu-latest
60 | permissions:
61 | pull-requests: write
62 | steps:
63 | - name: Auto approve Dependabot PRs
64 | run: gh pr review --approve "$PR_URL"
65 | env:
66 | PR_URL: ${{github.event.pull_request.html_url}}
67 | GH_TOKEN: ${{secrets.GITHUB_TOKEN}}
68 |
69 | auto-merge:
70 | if: github.actor == 'dependabot[bot]'
71 | runs-on: ubuntu-latest
72 | permissions:
73 | contents: write
74 | pull-requests: write
75 | steps:
76 | # NOTE Auto-merge is blocked until branch protection rules are fulfilled
77 | - name: Enable auto-merge for Dependabot PRs
78 | run: gh pr merge --auto --merge "$PR_URL"
79 | env:
80 | PR_URL: ${{github.event.pull_request.html_url}}
81 | GH_TOKEN: ${{secrets.GITHUB_TOKEN}}
82 |
--------------------------------------------------------------------------------
/.github/workflows/main.yml:
--------------------------------------------------------------------------------
1 | name: Axolotl main pipeline
2 |
3 | on:
4 | push:
5 | branches:
6 | - main
7 |
8 | jobs:
9 | build:
10 | uses: ./.github/workflows/build.yml
11 |
--------------------------------------------------------------------------------
/.github/workflows/pull_request.yml:
--------------------------------------------------------------------------------
1 | name: Axolotl pull request pipeline
2 |
3 | on:
4 | pull_request:
5 |
6 | concurrency:
7 | group: ${{ github.workflow }}-${{ github.ref }}
8 | cancel-in-progress: true
9 |
10 | permissions:
11 | checks: write
12 |
13 | jobs:
14 | build:
15 | uses: ./.github/workflows/build.yml
16 | test:
17 | uses: ./.github/workflows/test.yml
18 |
19 | # Check if all important jobs passed
20 | # This can be used as required status for branch protection rules.
21 | pr-ok:
22 | runs-on: ubuntu-latest
23 | needs:
24 | - build
25 | - test
26 | if: always()
27 | steps:
28 | - name: All tests ok
29 | if: ${{ !(contains(needs.*.result, 'failure')) }}
30 | run: exit 0
31 | - name: Some tests failed
32 | if: ${{ contains(needs.*.result, 'failure') }}
33 | run: exit 1
34 |
--------------------------------------------------------------------------------
/.github/workflows/release.yml:
--------------------------------------------------------------------------------
1 | name: Axolotl release pipeline
2 |
3 | on:
4 | push:
5 | tags:
6 | - 'v*'
7 |
8 | jobs:
9 | build:
10 | uses: ./.github/workflows/build.yml
11 |
12 | release:
13 | name: Create release
14 | needs: build
15 | runs-on: ubuntu-latest
16 |
17 | steps:
18 | - name: Download build artifacts
19 | uses: actions/download-artifact@v4
20 | with:
21 | path: build-artifacts
22 | - name: Get git tag version
23 | id: get_version
24 | uses: battila7/get-version-action@v2
25 | - name: Create draft GitHub release page
26 | id: create_release
27 | uses: marvinpinto/action-automatic-releases@v1.2.1
28 | with:
29 | repo_token: ${{ secrets.GITHUB_TOKEN }}
30 | title: ${{ steps.get_version.outputs.version }}
31 | draft: true
32 | prerelease: false
33 | files: |
34 | **/*.click
35 | **/*.deb
36 | **/*.AppImage
37 |
--------------------------------------------------------------------------------
/.github/workflows/stale.yml:
--------------------------------------------------------------------------------
1 | name: Close stale issues and PRs
2 | on:
3 | schedule:
4 | - cron: '30 1 * * *'
5 |
6 | jobs:
7 | stale:
8 | runs-on: ubuntu-latest
9 | steps:
10 | - uses: actions/stale@v9
11 | with:
12 | # Number of days of inactivity before a stale Issue or Pull Request is closed.
13 | # Set to -1 to disable. If disabled, issues still need to be closed manually, but will remain marked as stale.
14 | days-before-close: 14
15 | # Number of days of inactivity before an Issue or Pull Request becomes stale
16 | days-before-stale: 30
17 | # We don't want any Issues to be marked as stale for now.
18 | days-before-issue-stale: -1
19 | exempt-issue-labels: dependencies,no stalebot
20 | exempt-pr-labels: dependencies,no stalebot
21 | operations-per-run: 500
22 | stale-issue-label: stale
23 | stale-pr-label: stale
24 | stale-pr-message: >
25 | This pull request has been automatically marked as stale because it has not had
26 | activity in the last 30 days. It will be closed in 2 weeks if no further activity occurs. Please
27 | feel free to give a status update now, ping for review, or re-open when it's ready.
28 | Thank you for your contributions!
29 | close-pr-message: >
30 | This pull request has been automatically closed because it has not had
31 | activity in the last 2 weeks. Please feel free to give a status update now, ping for review, or re-open when it's ready.
32 | Thank you for your contributions!
33 |
34 |
--------------------------------------------------------------------------------
/.github/workflows/test.yml:
--------------------------------------------------------------------------------
1 | name: Axolotl test pipeline
2 |
3 | on:
4 | workflow_call:
5 | workflow_dispatch:
6 |
7 | env:
8 | NODE_VERSION: "20.x"
9 |
10 | jobs:
11 | test-axolotl-web:
12 | name: Test axolotl-web
13 | runs-on: ubuntu-latest
14 | steps:
15 | - name: Setup Node
16 | uses: actions/setup-node@v4
17 | with:
18 | node-version: ${{ env.NODE_VERSION }}
19 |
20 | - name: Check out code
21 | uses: actions/checkout@v4
22 |
23 | - name: Download dependencies
24 | run: make download-dependencies-axolotl-web
25 |
26 | - name: Test
27 | run: make check-axolotl-web
28 |
29 | rustfmt:
30 | name: rustfmt
31 | runs-on: ubuntu-latest
32 | steps:
33 | - name: Checkout repository
34 | uses: actions/checkout@v4
35 |
36 | - name: Rust setup
37 | uses: actions-rust-lang/setup-rust-toolchain@v1
38 | with:
39 | toolchain: stable
40 | components: rustfmt
41 | rustflags: ''
42 |
43 | - name: Check code format
44 | uses: actions-rust-lang/rustfmt@v1
45 |
46 | clippy:
47 | name: clippy
48 | runs-on: ubuntu-latest
49 | permissions:
50 | checks: write
51 | steps:
52 | - name: Checkout repository
53 | uses: actions/checkout@v4
54 |
55 | - name: install protoc
56 | run: sudo apt-get install protobuf-compiler
57 |
58 | - name: Rust setup
59 | uses: actions-rust-lang/setup-rust-toolchain@v1
60 | with:
61 | toolchain: stable
62 | components: clippy
63 | rustflags: ''
64 |
65 | - name: Run clippy lints
66 | uses: auguwu/clippy-action@1.4.0
67 | with:
68 | token: ${{secrets.GITHUB_TOKEN}}
69 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | axolotl.nanuc_*click
2 | axolotl
3 | builddir/
4 | build/
5 | target/
6 | .clickable/*
7 | *po~
8 | *~~
9 | *.snap
10 | *.AppImage
11 | *.vcf
12 | main
13 |
14 | output
15 | *.syso
16 | dist
17 | .flatpak-builder
18 | .flatpak
19 | .idea/*
20 | .idea
21 | axolotl.code-workspace
22 | libzkgroup.so
23 | libzkgroup*.so
24 | *.log
25 | *.sql*
26 | *.gz
27 | rustc-ice*.txt
28 | .devcontainer/
29 | .vscode/
30 |
--------------------------------------------------------------------------------
/Cargo.toml:
--------------------------------------------------------------------------------
1 | [package]
2 | name = "axolotl"
3 | version = "2.0.3"
4 | edition = "2021"
5 | description = """\
6 | This is a cross-platform Signal client."""
7 | license = "GPL-3"
8 | rust-version = "1.75"
9 |
10 | [build-dependencies]
11 | tauri-build = { version = "2.0.3", features = [], optional = true }
12 |
13 | [dependencies]
14 | tauri = { version = "2.1.1", features = [], optional = true }
15 | presage = { git = "https://github.com/nanu-c/presage", rev = "350921c533224265a0ff026dfddc67419ca45b7a" }
16 | presage-store-sled = { git = "https://github.com/nanu-c/presage", rev = "350921c533224265a0ff026dfddc67419ca45b7a" }
17 | #presage = {path = "../presage/presage"}
18 | #presage-store-sled = { path = "../presage/presage-store-sled" }
19 | zeroize = { version = "1.8.1", default-features = false }
20 | tokio = { version = "1", features = ["macros", "rt-multi-thread"] }
21 | tokio-stream = "0.1"
22 | hex = "0.4"
23 | warp = "0.3"
24 | futures = { version = "0.3", default-features = false }
25 | serde = { version = "1.0", features = ["derive"] }
26 | serde_json = "1.0"
27 | log = "0.4.27"
28 | env_logger = "0.11.6"
29 | url = "2.5.4"
30 | sled = "0.34.7"
31 | clap = { version = "4.5.39", features = ["derive"] }
32 | dirs = "6.0.0"
33 | notify-rust = { version = "4.11.3", optional = true }
34 | data-url = "0.3.1"
35 |
36 | dbus = { version = "0.9", optional = true }
37 |
38 | [patch.crates-io]
39 | "curve25519-dalek" = { git = 'https://github.com/signalapp/curve25519-dalek', tag = 'signal-curve25519-4.0.0' }
40 |
41 |
42 | [features]
43 | # by default Tauri runs in production mode
44 | # when `tauri dev` runs it is executed with `cargo run --no-default-features` if `devPath` is an URL
45 | # this feature is used for production builds where `devPath` points to the filesystem
46 | # DO NOT remove this
47 | default = ["dep:notify-rust"]
48 | custom-protocol = ["tauri/custom-protocol"]
49 | tauri = ["dep:tauri", "dep:notify-rust", "custom-protocol"]
50 | ut = ["dep:dbus"]
51 | # Use this feature to debug registration issues on test servers
52 | staging-servers = []
53 |
54 |
55 | [[example]]
56 | name = "dump_db"
57 | path = "examples/dump/dump_db.rs"
58 |
--------------------------------------------------------------------------------
/Makefile:
--------------------------------------------------------------------------------
1 | # This is the Makefile for axolotl.
2 | # For more info about the syntax, see https://makefiletutorial.com/
3 |
4 | .PHONY: build build-axolotl-web build-axolotl install install-axolotl uninstall uninstall-axolotl clean clean-axolotl-web clean-axolotl check check-axolotl-web check-axolotl build-translation download-dependencies download-dependencies-axolotl-web download-dependencies-axolotl update-version download-dependencies-flatpak install-flatpak build-snap install-snap
5 |
6 | AXOLOTL_GIT_VERSION := $(shell git tag | tail --lines=1)
7 | AXOLOTL_VERSION := $(subst v,,$(AXOLOTL_GIT_VERSION))
8 | ARCH := $(shell uname --machine)
9 | CURRENT_DIR := $(shell pwd)
10 |
11 | APP_ID := axolotl
12 | define APPDATA_TEXT=
13 | \\t\t
10 |
11 |
12 |
13 |
Translate me!
` instead of `Translate me!
` 83 | - `Translate me!
` instead of `Translate me!
` 84 | - `Translate me!
Please...
` instead of `Translate me!
Please...