{"id":50695345,"url":"https://github.com/tuanle96/zca-desktop","last_synced_at":"2026-06-09T06:06:01.500Z","repository":{"id":362806940,"uuid":"1256042001","full_name":"tuanle96/zca-desktop","owner":"tuanle96","description":"Unofficial personal-use Zalo desktop client built with Tauri, Rust, SvelteKit, and an optional encrypted cloud sync backend.","archived":false,"fork":false,"pushed_at":"2026-06-06T01:11:15.000Z","size":4715,"stargazers_count":22,"open_issues_count":0,"forks_count":2,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-06T03:08:34.050Z","etag":null,"topics":["desktop-app","rust","tauri","zalo"],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/tuanle96.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":"AGENTS.md","dco":null,"cla":"CLA.md"}},"created_at":"2026-06-01T12:07:22.000Z","updated_at":"2026-06-06T01:11:09.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/tuanle96/zca-desktop","commit_stats":null,"previous_names":["tuanle96/zca-desktop"],"tags_count":9,"template":false,"template_full_name":null,"purl":"pkg:github/tuanle96/zca-desktop","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tuanle96%2Fzca-desktop","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tuanle96%2Fzca-desktop/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tuanle96%2Fzca-desktop/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tuanle96%2Fzca-desktop/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/tuanle96","download_url":"https://codeload.github.com/tuanle96/zca-desktop/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tuanle96%2Fzca-desktop/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34093797,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-09T02:00:06.510Z","response_time":63,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["desktop-app","rust","tauri","zalo"],"created_at":"2026-06-09T06:06:00.616Z","updated_at":"2026-06-09T06:06:01.486Z","avatar_url":"https://github.com/tuanle96.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# zca-desktop\n\nUnofficial cross-platform **Zalo desktop client** built with **Tauri v2, Rust,\nSvelteKit, and Svelte 5**. The desktop core hosts concurrent\n[`zca-rust`](https://github.com/tuanle96/zca-rust) sessions, while an optional\nRust cloud backend can host QR-linked Zalo sessions, encrypted sync state, and\nmedia storage for personal self-hosted use.\n\n![zca-desktop desktop app screenshot](docs/readme-assets/zca-desktop-demo.png)\n\n\u003e **Unofficial. Not affiliated with Zalo or VNG.** This is a personal-use,\n\u003e noncommercial project. Using an unofficial client can get your Zalo account\n\u003e rate-limited, suspended, or permanently banned, and may violate Zalo's Terms\n\u003e of Service. Read [DISCLAIMER.md](./DISCLAIMER.md) before using it with any\n\u003e account you care about.\n\n## Current status\n\nThe project is early but functional. Local desktop chat, multi-account session\nmanagement, QR login, encrypted credential storage, SQLite history restore, and\nthe self-hosted cloud backend are implemented and tested. Some media delivery\nand packaging work is still in progress; see [Roadmap](#roadmap).\n\n## Install\n\n### Homebrew Cask\n\n```bash\nbrew tap tuanle96/tap\nbrew install --cask zca-desktop\n```\n\nThe published macOS DMG is universal `x86_64 arm64`, Developer ID signed,\nnotarized by Apple, and stapled for Gatekeeper.\n\nThe app also supports in-app updates from the Settings -\u003e Giới thiệu panel. The\nupdater checks the latest GitHub Release `latest.json`, verifies the Tauri\nupdater signature, downloads the signed updater payload, installs it, and\nrelaunches the app.\n\n## Implemented\n\n### Desktop local mode\n\n| Area | Status | Notes |\n| --- | --- | --- |\n| Tauri desktop shell | Implemented | Tauri v2 app with SvelteKit/Svelte 5 UI and Tailwind v4 styling. |\n| Zalo login | Implemented | QR login flow streams non-secret QR progress to the UI; credential material stays in Rust. |\n| Dev credential loader | Implemented | Optional local `.zalo-cred.json` loader for development; the webview never receives the token values. |\n| Multi-account sessions | Implemented | `SessionManager` owns one authenticated API + realtime listener per account with graceful replacement/removal. |\n| Realtime messages | Implemented | Listener emits `zalo://message` events and tags messages with `account_id` for per-account routing. |\n| Account switcher | Implemented | Left rail lists logged-in accounts, status, unread totals, and switches active account state. |\n| Multi-device self-listen | Implemented | Messages sent from another official Zalo device render as outgoing messages in zca-desktop. |\n| Text messaging | Implemented | Send text messages and quoted replies to user/group threads through the active account session. |\n| Rich messages | Implemented | Stickers, sticker search/recent packs, reactions, quotes, link previews, recalled/deleted state, and persistence. |\n| Contacts and groups | Implemented | Friend/contact list and group metadata are loaded through the core and used to backfill thread identity. |\n| Local persistence | Implemented | SQLite stores accounts, threads, messages, rich metadata, attachments metadata, and recent stickers. |\n| Credential storage | Implemented | Zalo credentials are encrypted before persistence; the master key is stored in the OS keychain. |\n| Session restore | Implemented | Saved accounts are restored on startup; expired credentials are marked reauth-needed. |\n| Settings panel | Implemented | Account info, logout/forget account, theme selection, local data stats, and about panel. |\n\n### Self-hosted cloud mode\n\n| Area | Status | Notes |\n| --- | --- | --- |\n| Backend foundation | Implemented | Rust `axum` server, Postgres via `sqlx`, S3-compatible object storage, migrations, and API contracts. |\n| Email magic-link auth | Implemented | Device registration, recovery-key wrapping, token hashing, revoke support, rate limits, and audit events. |\n| Hosted Zalo sessions | Implemented | Backend QR/login/listen/send worker per hosted account with encrypted credential restore. |\n| Desktop cloud commands | Implemented | Tauri command bridge for cloud auth, account management, realtime, contacts, conversations, and messages. |\n| Realtime SSE | Implemented | Per-user realtime stream with reconnect/offline UI handling and ownership isolation. |\n| Cloud contacts | Implemented | Hosted contacts endpoint and desktop contact pane in cloud mode. |\n| Cloud message store | Implemented | Encrypted message fields and file metadata across registered devices. |\n| Media mirroring | Implemented | Bounded HTTP(S) media fetch, encrypted object-store writes, and desktop download hydration. |\n| Cloud rich messages | Implemented | Quote, link, sticker, file/media preview, reactions, and deleted state hydrate in desktop cloud mode. |\n| Cloud upload flow | Implemented with caveat | Encrypted upload, ownership validation, and desktop flow are wired; image/file delivery semantics still need final live hardening. |\n\n### Safety and project hygiene\n\n| Area | Status | Notes |\n| --- | --- | --- |\n| Secret handling | Implemented | Zalo `imei`, cookies, user-agent, device tokens, and server secrets are treated as bearer credentials. |\n| Redaction | Implemented | Raw API logging redacts common token/cookie fields by default; `ZCA_LOG_RAW=1` is local-debug only. |\n| Public docs | Implemented | Architecture, credential handling, privacy, deployment, and threat-model docs are included. |\n| Harness gates | Implemented | Root harness scripts, Codex instructions, GitHub workflows, task evidence, and readiness checks are wired. |\n| License posture | Implemented | PolyForm Noncommercial 1.0.0; commercial use is not permitted without a separate license. |\n\n## Not implemented yet\n\n- **Local desktop attachment sending**: image/file upload and rendering in local\n  mode is still a roadmap item.\n- **Hosted attachment delivery hardening**: cloud upload/storage exists, but\n  recipient delivery for some media paths still needs final live proof and fixes.\n- **Signed app distribution**: the macOS universal DMG is published, signed, and\n  notarized; Windows and Linux installers are still roadmap items.\n- **Deep device-coexistence proof**: the app is designed to coexist with other\n  Zalo devices and self-listen is enabled, but broader multi-device validation is\n  still planned.\n- **Production operations**: the cloud backend has a deployment checklist, but no\n  hosted public service is provided by this repository.\n\n## Roadmap\n\n### Near term\n\n- Finish local desktop attachment upload/rendering.\n- Finalize hosted image/file delivery semantics and live proof for cloud\n  attachment sends.\n- Improve cloud account reauth UX when hosted credentials expire or Zalo rejects\n  a restored session.\n- Add more focused tests around rich-message hydration, media previews, and\n  device revocation flows.\n\n### Mid term\n\n- Package signed desktop builds for Windows and Linux using Tauri bundling.\n- Expand release automation for publishing the updater `latest.json` asset on\n  every signed macOS release.\n- Expand multi-device coexistence testing across phone, web, and desktop Zalo\n  sessions.\n- Improve cloud deployment templates for production-grade Postgres, object\n  storage, SMTP, HTTPS, backups, and log rotation.\n\n### Later / exploratory\n\n- Optional self-hosted relay/sync model for same-account state across multiple\n  zca-desktop installs.\n- More complete data export/delete tooling for self-hosted cloud operators.\n- A stricter public API compatibility workflow around `crates/zca-types` and the\n  generated TypeScript contracts.\n\n## Stack\n\n- **Desktop core**: Rust + Tauri v2, layered as\n  `types -\u003e config -\u003e store -\u003e zalo -\u003e session -\u003e command`.\n- **Zalo adapter**: [`zca-rust`](https://github.com/tuanle96/zca-rust), pinned to\n  a known revision for reproducible builds.\n- **Desktop UI**: SvelteKit/Svelte 5 SPA, Tailwind v4, shadcn-svelte style\n  primitives.\n- **Cloud backend**: Rust `axum`, `sqlx`, Postgres, S3-compatible object storage,\n  server-sent events.\n- **Shared contracts**: Rust DTOs in `crates/zca-types`, generated TypeScript in\n  `packages/types`.\n- **Package manager**: `bun`.\n\n## Quick start\n\nPrerequisites:\n\n- [Rust](https://rustup.rs)\n- [bun](https://bun.sh)\n- [Tauri v2 system dependencies](https://v2.tauri.app/start/prerequisites/)\n- Docker, if you want the local cloud backend stack\n\n```bash\n# 1. Install workspace dependencies\nbun install\n\n# 2. Optional: start the local cloud backend for development\n#    Postgres + MinIO + MailHog + zca cloud server at http://127.0.0.1:37880\ndocker compose -f apps/server/docker-compose.dev.yml up -d --build\n\n# 3. Run the desktop app\nbun --cwd apps/desktop run tauri dev\n```\n\nThe production default sign-in endpoint is `https://zca.tuanle.dev`. Override\n`PUBLIC_ZCA_CLOUD_BASE_URL=http://127.0.0.1:37880` when you want the app to use\nthe local backend from step 2 for magic-link/device auth. See\n[apps/server/README.md](./apps/server/README.md) for backend-specific setup,\nenvironment variables, and deployment notes.\n\n## Development commands\n\n```bash\n# Desktop frontend\nbun --cwd apps/desktop run check\nbun --cwd apps/desktop run build\n\n# Mobile frontend\nbun --cwd apps/mobile run check\nbun --cwd apps/mobile run build\n\n# Rust client workspace\ncargo clippy --all-targets -- -D warnings\ncargo test --all\n\n# Cloud backend workspace\ncargo clippy --manifest-path apps/server/Cargo.toml --all-targets -- -D warnings\ncargo test --manifest-path apps/server/Cargo.toml\n\n# Shared Rust -\u003e TypeScript contract generation\ncargo test --manifest-path crates/zca-types/Cargo.toml --features ts\ngit diff --exit-code -- packages/types/src/generated\n```\n\n## Operational docs\n\n- [Architecture](./docs/ARCHITECTURE.md)\n- [Credential handling](./docs/CREDENTIALS.md)\n- [Privacy and data handling](./docs/PRIVACY.md)\n- [Deployment checklist](./docs/DEPLOYMENT.md)\n- [Threat model](./docs/THREAT_MODEL.md)\n- [Server README](./apps/server/README.md)\n\n## Contributing\n\nContributions are welcome, especially bug fixes, tests, docs, and narrowly\nscoped hardening work. Please read [CONTRIBUTING.md](./CONTRIBUTING.md) first.\n\nIn short:\n\n- Every contributor must agree to the [Contributor License Agreement](./CLA.md)\n  and sign off their commits (`git commit -s`).\n- Be respectful; see the [Code of Conduct](./CODE_OF_CONDUCT.md).\n- Do not add spam-like, mass-messaging, scraping, or bulk automation features.\n- Never commit Zalo credentials, cookies, tunnel credentials, server secrets, or\n  raw unredacted debug captures.\n\nFound a security or credential-handling issue? Report it privately through the\nprocess in [SECURITY.md](./SECURITY.md). Do not open a public issue containing\ncredentials, cookies, private messages, or infrastructure secrets.\n\n## License\n\nzca-desktop is licensed under the\n**[PolyForm Noncommercial License 1.0.0](./LICENSE)**.\n\n- Free for personal, hobby, educational, research, and other noncommercial use.\n- Commercial use is not permitted under this license.\n\nIf you need a commercial license, contact the maintainer. See [LICENSE](./LICENSE),\n[DISCLAIMER.md](./DISCLAIMER.md), and the\n[PolyForm FAQ](https://polyformproject.org/licenses/) for details.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftuanle96%2Fzca-desktop","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftuanle96%2Fzca-desktop","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftuanle96%2Fzca-desktop/lists"}