| 1 |
[package] |
| 2 |
name = "synckit-client" |
| 3 |
version = "0.6.0" |
| 4 |
edition = "2024" |
| 5 |
description = "SyncKit client SDK with end-to-end encryption" |
| 6 |
license-file = "LICENSE" |
| 7 |
|
| 8 |
[features] |
| 9 |
default = ["keychain", "store"] |
| 10 |
keychain = ["dep:keyring"] |
| 11 |
# The higher-level SyncStore engine (owns a rusqlite connection to the app's DB). |
| 12 |
# Default-on so app consumers get it for free; a consumer that only needs the |
| 13 |
# transport/crypto SDK (e.g. mnw-cli, which sets `default-features = false`) skips |
| 14 |
# it and avoids compiling bundled SQLite. |
| 15 |
store = ["dep:rusqlite", "dep:synckit-config"] |
| 16 |
# Exposes test-only constructors (`set_master_key_raw`, `with_http_client`) that |
| 17 |
# bypass key derivation. Enabled automatically for this crate's own test builds |
| 18 |
# via the self dev-dependency below; never part of `default`, so a real consumer |
| 19 |
# cannot reach a raw-key injection point. |
| 20 |
testing = [] |
| 21 |
|
| 22 |
[dependencies] |
| 23 |
# Encryption |
| 24 |
chacha20poly1305 = "0.11" |
| 25 |
argon2 = "0.5" |
| 26 |
rand = "0.10" |
| 27 |
base64 = "0.22" |
| 28 |
zeroize = "1" |
| 29 |
# X25519 ECDH — the only asymmetric primitive in the crate, used solely by the |
| 30 |
# group-key layer (`identity.rs`) to seal a Group Content Key to a member's public |
| 31 |
# key. Pure-Rust (curve25519-dalek), no aws-lc/ring. Deliberately just the curve op: |
| 32 |
# the GCK itself is sealed with the XChaCha20-Poly1305 above, not a sealed-box crate. |
| 33 |
# `static_secrets` enables the reusable `StaticSecret` (a member's long-lived key). |
| 34 |
x25519-dalek = { version = "2", default-features = false, features = ["static_secrets", "zeroize"] } |
| 35 |
|
| 36 |
# PKCE (OAuth2) challenge hashing |
| 37 |
sha2 = "0.11" |
| 38 |
hex = "0.4" |
| 39 |
|
| 40 |
# HTTP |
| 41 |
# rustls-no-provider: rustls TLS with the OS-native trust store (rustls-platform-verifier), |
| 42 |
# no bundled crypto provider — the consuming app installs one process default (ring). |
| 43 |
reqwest = { version = "0.13", default-features = false, features = ["json", "rustls-no-provider", "stream", "form", "charset", "http2", "system-proxy"] } |
| 44 |
bytes = "1" |
| 45 |
tokio = { version = "1", features = ["rt-multi-thread", "macros", "time", "fs", "io-util"] } |
| 46 |
tokio-stream = "0.1" |
| 47 |
|
| 48 |
# Serialization |
| 49 |
serde = { version = "1", features = ["derive"] } |
| 50 |
serde_json = "1" |
| 51 |
chrono = { version = "0.4", features = ["serde"] } |
| 52 |
uuid = { version = "1", features = ["v4", "serde"] } |
| 53 |
|
| 54 |
# OS keychain (optional) |
| 55 |
keyring = { version = "4", optional = true } |
| 56 |
|
| 57 |
# URL encoding |
| 58 |
urlencoding = "2" |
| 59 |
|
| 60 |
# Unicode |
| 61 |
unicode-normalization = "0.1" |
| 62 |
|
| 63 |
# Synchronization |
| 64 |
parking_lot = "0.12" |
| 65 |
|
| 66 |
# Error handling & logging |
| 67 |
thiserror = "2" |
| 68 |
tracing = "0.1" |
| 69 |
|
| 70 |
# SyncStore engine (feature = "store"). Owns the app's SQLite connection. Bundled |
| 71 |
# so no system libsqlite is needed; `functions` to register the `hash_row_id` UDF. |
| 72 |
rusqlite = { version = "0.39", features = ["bundled", "functions"], optional = true } |
| 73 |
# The local config store (posture types + KV store). The config sync adapter |
| 74 |
# (src/store/config.rs) turns a ConfigSpec into a SyncTable. Path dep: sibling in |
| 75 |
# the MNW tree, versioned together. |
| 76 |
synckit-config = { path = "../synckit-config", optional = true } |
| 77 |
|
| 78 |
[dev-dependencies] |
| 79 |
wiremock = "0.6" |
| 80 |
# reqwest is built `rustls-no-provider`, so real consumers install a rustls crypto |
| 81 |
# provider at startup (audiofiles installs ring). The test suite has no such app, so |
| 82 |
# it installs ring itself before building any client. Dev-only: never in a consumer build. |
| 83 |
rustls = { version = "0.23", default-features = false, features = ["ring"] } |
| 84 |
# Self dev-dependency: turns on the `testing` feature for this crate's own |
| 85 |
# unit/integration test builds without leaking it into a consumer's default set. |
| 86 |
# `default-features = false` so it only ADDS `testing` to whatever the test run |
| 87 |
# already selected — under a plain `cargo test` the package still builds with its |
| 88 |
# own defaults (keychain + store), but `cargo test --no-default-features` can turn |
| 89 |
# keychain OFF (making `keystore::store_key` the no-op stub) to run the keychain- |
| 90 |
# free rotation orchestration test below. |
| 91 |
synckit-client = { path = ".", default-features = false, features = ["testing"] } |
| 92 |
|
| 93 |
[lints.rust] |
| 94 |
unused = "warn" |
| 95 |
unreachable_pub = "warn" |
| 96 |
|
| 97 |
[lints.clippy] |
| 98 |
pedantic = { level = "warn", priority = -1 } |
| 99 |
# Allow-list tuned from a measured breakdown across server/multithreaded/pter |
| 100 |
# (2026-07-22). These are the high-churn / low-signal pedantic lints; everything |
| 101 |
# else in `pedantic` stays a warning. Keep this block identical across repos. |
| 102 |
module_name_repetitions = "allow" |
| 103 |
# Doc lints. No docs-completeness push is underway. |
| 104 |
missing_errors_doc = "allow" |
| 105 |
missing_panics_doc = "allow" |
| 106 |
doc_markdown = "allow" |
| 107 |
# Numeric casts. Endemic and mostly intentional in size and byte math. |
| 108 |
cast_possible_truncation = "allow" |
| 109 |
cast_sign_loss = "allow" |
| 110 |
cast_precision_loss = "allow" |
| 111 |
cast_possible_wrap = "allow" |
| 112 |
cast_lossless = "allow" |
| 113 |
# Subjective structure and style nags. High churn, low signal. |
| 114 |
must_use_candidate = "allow" |
| 115 |
too_many_lines = "allow" |
| 116 |
struct_excessive_bools = "allow" |
| 117 |
similar_names = "allow" |
| 118 |
items_after_statements = "allow" |
| 119 |
single_match_else = "allow" |
| 120 |
# Frequent false-positives in TUI and router-heavy code. |
| 121 |
match_same_arms = "allow" |
| 122 |
unnecessary_wraps = "allow" |
| 123 |
type_complexity = "allow" |
| 124 |
|