From 0b8eb49996faf04fc128b9f963ec167b3bd91430 Mon Sep 17 00:00:00 2001 From: emadab <63538622+Emadab@users.noreply.github.com> Date: Thu, 2 Jul 2026 12:01:36 +0330 Subject: [PATCH 1/4] chore: prepare repo for open source MIT release Replace Tantivy (AGPL-3.0) with SQLite FTS5 in synapse-search to clear the license conflict, simplify to plain MIT, add LICENSE/SECURITY.md/ CODE_OF_CONDUCT.md/issue+PR templates, fix repo URL to Emadab/Synapse, and add an Anki trademark disclaimer to the README. --- .github/ISSUE_TEMPLATE/bug_report.md | 25 ++ .github/ISSUE_TEMPLATE/feature_request.md | 14 + .github/PULL_REQUEST_TEMPLATE.md | 9 + CODE_OF_CONDUCT.md | 67 +++ CONTRIBUTING.md | 4 +- Cargo.lock | 510 +--------------------- Cargo.toml | 6 +- LICENSE | 21 + README.md | 17 +- SECURITY.md | 20 + apps/desktop/package.json | 6 + crates/synapse-search/Cargo.toml | 4 +- crates/synapse-search/src/lib.rs | 179 ++++---- 13 files changed, 301 insertions(+), 581 deletions(-) create mode 100644 .github/ISSUE_TEMPLATE/bug_report.md create mode 100644 .github/ISSUE_TEMPLATE/feature_request.md create mode 100644 .github/PULL_REQUEST_TEMPLATE.md create mode 100644 CODE_OF_CONDUCT.md create mode 100644 LICENSE create mode 100644 SECURITY.md diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 0000000..9629a5b --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,25 @@ +--- +name: Bug report +about: Report a problem with Synapse +title: "" +labels: bug +--- + +## Steps to reproduce + +1. ... +2. ... + +## Expected behaviour + +## Actual behaviour + +## Environment + +- OS + version: +- Synapse version: +- Involves an Anki-imported collection (`.apkg`/`.colpkg`)? yes/no + +## Logs + +Attach the log from `Help → Open Log Folder` if relevant. diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md new file mode 100644 index 0000000..e60e942 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -0,0 +1,14 @@ +--- +name: Feature request +about: Suggest an idea for Synapse +title: "" +labels: enhancement +--- + +## Problem + +What are you trying to do that Synapse doesn't support today? + +## Proposed solution + +## Alternatives considered diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 0000000..b2f9754 --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,9 @@ +## What / why + +## Checklist + +- [ ] `pnpm lint` and `cargo clippy -- -D warnings` pass +- [ ] `cargo fmt --check` and `pnpm fmt:check` pass +- [ ] `cargo test --workspace` and `pnpm test` pass +- [ ] New IPC commands have a Rust test and a TypeScript wrapper +- [ ] Ran `pnpm bindings` if Rust `#[derive(TS)]` structs changed diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md new file mode 100644 index 0000000..c9a5faf --- /dev/null +++ b/CODE_OF_CONDUCT.md @@ -0,0 +1,67 @@ +# Contributor Covenant Code of Conduct + +## Our Pledge + +We as members, contributors, and leaders pledge to make participation in our +community a harassment-free experience for everyone, regardless of age, body +size, visible or invisible disability, ethnicity, sex characteristics, gender +identity and expression, level of experience, education, socio-economic +status, nationality, personal appearance, race, religion, or sexual identity +and orientation. + +We pledge to act and interact in ways that contribute to an open, welcoming, +diverse, inclusive, and healthy community. + +## Our Standards + +Examples of behavior that contributes to a positive environment include: + +- Demonstrating empathy and kindness toward other people +- Being respectful of differing opinions, viewpoints, and experiences +- Giving and gracefully accepting constructive feedback +- Accepting responsibility and apologizing to those affected by our mistakes, + and learning from the experience +- Focusing on what is best not just for us as individuals, but for the + overall community + +Examples of unacceptable behavior include: + +- The use of sexualized language or imagery, and sexual attention or advances + of any kind +- Trolling, insulting or derogatory comments, and personal or political + attacks +- Public or private harassment +- Publishing others' private information, such as a physical or email + address, without their explicit permission +- Other conduct which could reasonably be considered inappropriate in a + professional setting + +## Enforcement Responsibilities + +Project maintainers are responsible for clarifying and enforcing our +standards of acceptable behavior and will take appropriate and fair +corrective action in response to any behavior that they deem inappropriate, +threatening, offensive, or harmful. + +## Scope + +This Code of Conduct applies within all community spaces, and also applies +when an individual is officially representing the community in public +spaces. + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be +reported by opening a +[GitHub Security Advisory](https://github.com/Emadab/Synapse/security/advisories/new) +or a confidential issue on the project's issue tracker. All complaints will +be reviewed and investigated promptly and fairly. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], +version 2.1, available at +[https://www.contributor-covenant.org/version/2/1/code_of_conduct.html][v2.1]. + +[homepage]: https://www.contributor-covenant.org +[v2.1]: https://www.contributor-covenant.org/version/2/1/code_of_conduct.html diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 7533d89..cec970d 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -12,7 +12,7 @@ ## Setup ```sh -git clone https://github.com/synapse-srs/synapse +git clone https://github.com/Emadab/Synapse cd synapse pnpm install ``` @@ -89,7 +89,7 @@ docs: ADR-003 plugin sandbox decision ## Reporting issues -Open an issue at https://github.com/synapse-srs/synapse/issues with: +Open an issue at https://github.com/Emadab/Synapse/issues with: - OS + version - Steps to reproduce diff --git a/Cargo.lock b/Cargo.lock index 4bb21bc..a3400cf 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -55,12 +55,6 @@ dependencies = [ "alloc-no-stdlib", ] -[[package]] -name = "allocator-api2" -version = "0.2.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" - [[package]] name = "android_system_properties" version = "0.1.5" @@ -85,15 +79,6 @@ dependencies = [ "derive_arbitrary", ] -[[package]] -name = "arc-swap" -version = "1.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a3a1fd6f75306b68087b831f025c712524bcb19aad54e557b1129cfa0a2b207" -dependencies = [ - "rustversion", -] - [[package]] name = "async-broadcast" version = "0.7.2" @@ -145,7 +130,7 @@ dependencies = [ "futures-lite", "parking", "polling", - "rustix 1.1.4", + "rustix", "slab", "windows-sys 0.61.2", ] @@ -176,7 +161,7 @@ dependencies = [ "cfg-if", "event-listener", "futures-lite", - "rustix 1.1.4", + "rustix", ] [[package]] @@ -202,7 +187,7 @@ dependencies = [ "cfg-if", "futures-core", "futures-io", - "rustix 1.1.4", + "rustix", "signal-hook-registry", "slab", "windows-sys 0.61.2", @@ -302,15 +287,6 @@ dependencies = [ "serde_core", ] -[[package]] -name = "bitpacking" -version = "0.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96a7139abd3d9cebf8cd6f920a389cf3dc9576172e32f4563f188cae3c3eb019" -dependencies = [ - "crunchy", -] - [[package]] name = "block-buffer" version = "0.10.4" @@ -497,12 +473,6 @@ dependencies = [ "shlex", ] -[[package]] -name = "census" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f4c707c6a209cbe82d10abd08e1ea8995e9ea937d2550646e02798948992be0" - [[package]] name = "cesu8" version = "1.1.0" @@ -675,37 +645,12 @@ dependencies = [ "crossbeam-utils", ] -[[package]] -name = "crossbeam-deque" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9dd111b7b7f7d55b72c0a6ae361660ee5853c9af73f70c3c2ef6858b950e2e51" -dependencies = [ - "crossbeam-epoch", - "crossbeam-utils", -] - -[[package]] -name = "crossbeam-epoch" -version = "0.9.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b82ac4a3c2ca9c3460964f020e1402edd5753411d7737aa39c3714ad1b5420e" -dependencies = [ - "crossbeam-utils", -] - [[package]] name = "crossbeam-utils" version = "0.8.21" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" -[[package]] -name = "crunchy" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "460fbee9c2c2f33933d720630a6a0bac33ba7053db5344fac858d4b8952d77d5" - [[package]] name = "crypto-common" version = "0.1.7" @@ -956,19 +901,13 @@ checksum = "521e380c0c8afb8d9a1e83a1822ee03556fc3e3e7dbc1fd30be14e37f9cb3f89" dependencies = [ "bit-set", "cssparser", - "foldhash 0.2.0", + "foldhash", "html5ever", "precomputed-hash", "selectors", "tendril", ] -[[package]] -name = "downcast-rs" -version = "1.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75b325c5dbd37f80359721ad39aca5a29fb04c89279657cffdda8736d0c0b9d2" - [[package]] name = "dpi" version = "0.1.2" @@ -1020,12 +959,6 @@ version = "1.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d0881ea181b1df73ff77ffaaf9c7544ecc11e82fba9b5f27b262a3c73a332555" -[[package]] -name = "either" -version = "1.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91622ff5e7162018101f2fea40d6ebf4a78bbe5a49736a2020649edf9693679e" - [[package]] name = "embed-resource" version = "3.0.9" @@ -1133,12 +1066,6 @@ version = "0.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7360491ce676a36bf9bb3c56c1aa791658183a54d2744120f27285738d90465a" -[[package]] -name = "fastdivide" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9afc2bd4d5a73106dd53d10d73d3401c2f32730ba2c0b93ddb888a8983680471" - [[package]] name = "fastrand" version = "2.4.1" @@ -1186,12 +1113,6 @@ version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" -[[package]] -name = "foldhash" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" - [[package]] name = "foldhash" version = "0.2.0" @@ -1234,16 +1155,6 @@ dependencies = [ "percent-encoding", ] -[[package]] -name = "fs4" -version = "0.8.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7e180ac76c23b45e767bd7ae9579bc0bb458618c4bc71835926e098e61d15f8" -dependencies = [ - "rustix 0.38.44", - "windows-sys 0.52.0", -] - [[package]] name = "futures-channel" version = "0.3.32" @@ -1636,17 +1547,6 @@ dependencies = [ "ahash", ] -[[package]] -name = "hashbrown" -version = "0.15.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1" -dependencies = [ - "allocator-api2", - "equivalent", - "foldhash 0.1.5", -] - [[package]] name = "hashbrown" version = "0.17.1" @@ -1705,12 +1605,6 @@ dependencies = [ "markup5ever", ] -[[package]] -name = "htmlescape" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e9025058dae765dee5070ec375f591e2ba14638c63feff74f13805a72e523163" - [[package]] name = "http" version = "1.4.2" @@ -1977,18 +1871,6 @@ dependencies = [ "generic-array", ] -[[package]] -name = "instant" -version = "0.1.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0242819d153cba4b4b05a5a8f2a7e9bbf97b6055b2a002b395c96b5ff3c0222" -dependencies = [ - "cfg-if", - "js-sys", - "wasm-bindgen", - "web-sys", -] - [[package]] name = "ipnet" version = "2.12.0" @@ -2014,15 +1896,6 @@ dependencies = [ "once_cell", ] -[[package]] -name = "itertools" -version = "0.12.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" -dependencies = [ - "either", -] - [[package]] name = "itoa" version = "1.0.18" @@ -2156,12 +2029,6 @@ version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" -[[package]] -name = "levenshtein_automata" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c2cdeb66e45e9f36bfad5bbdb4d2384e70936afbee843c6f6543f0c551ebb25" - [[package]] name = "libappindicator" version = "0.9.0" @@ -2211,12 +2078,6 @@ dependencies = [ "winapi", ] -[[package]] -name = "libm" -version = "0.2.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6d2cec3eae94f9f509c767b45932f1ada8350c4bdb85af2fcab4a3c14807981" - [[package]] name = "libredox" version = "0.1.17" @@ -2237,12 +2098,6 @@ dependencies = [ "vcpkg", ] -[[package]] -name = "linux-raw-sys" -version = "0.4.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab" - [[package]] name = "linux-raw-sys" version = "0.12.1" @@ -2270,21 +2125,6 @@ version = "0.4.32" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "953f07c43838f8e6f9758cab68bf5bed85465e7587ebe0b823f1bcd81978ad3a" -[[package]] -name = "lru" -version = "0.12.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "234cf4f4a04dc1f57e24b96cc0cd600cf2af460d4161ac5ecdd0af8e1f3b2a38" -dependencies = [ - "hashbrown 0.15.5", -] - -[[package]] -name = "lz4_flex" -version = "0.11.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "373f5eceeeab7925e0c1098212f2fbc4d416adec9d35051a6ab251e824c1854a" - [[package]] name = "lzma-rs" version = "0.3.0" @@ -2326,31 +2166,12 @@ dependencies = [ "regex-automata", ] -[[package]] -name = "measure_time" -version = "0.8.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbefd235b0aadd181626f281e1d684e116972988c14c264e42069d5e8a5775cc" -dependencies = [ - "instant", - "log", -] - [[package]] name = "memchr" version = "2.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "88904434abc2901f197fe8cc55f0445e7ded921dba5911dad2e2b39b48e663c4" -[[package]] -name = "memmap2" -version = "0.9.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "714098028fe011992e1c3962653c96b2d578c4b4bce9036e15ff220319b1e0e3" -dependencies = [ - "libc", -] - [[package]] name = "memoffset" version = "0.9.1" @@ -2366,12 +2187,6 @@ version = "0.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" -[[package]] -name = "minimal-lexical" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" - [[package]] name = "miniz_oxide" version = "0.8.9" @@ -2414,12 +2229,6 @@ dependencies = [ "windows-sys 0.61.2", ] -[[package]] -name = "murmurhash32" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2195bf6aa996a481483b29d62a7663eed3fe39600c460e323f8ff41e90bdd89b" - [[package]] name = "ndk" version = "0.9.0" @@ -2450,16 +2259,6 @@ version = "1.0.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "650eef8c711430f1a879fdd01d4745a7deea475becfb90269c06775983bbf086" -[[package]] -name = "nom" -version = "7.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" -dependencies = [ - "memchr", - "minimal-lexical", -] - [[package]] name = "nu-ansi-term" version = "0.50.3" @@ -2482,17 +2281,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" dependencies = [ "autocfg", - "libm", -] - -[[package]] -name = "num_cpus" -version = "1.17.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91df4bbde75afed763b708b7eee1e8e7651e02d97f6d5dd763e89367e957b23b" -dependencies = [ - "hermit-abi", - "libc", ] [[package]] @@ -2719,12 +2507,6 @@ version = "1.21.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" -[[package]] -name = "oneshot" -version = "0.1.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "269bca4c2591a28585d6bf10d9ed0332b7d76900a1b02bec41bdc3a2cdcda107" - [[package]] name = "open" version = "5.3.5" @@ -2753,15 +2535,6 @@ dependencies = [ "pin-project-lite", ] -[[package]] -name = "ownedbytes" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3a059efb063b8f425b948e042e6b9bd85edfe60e913630ed727b23e2dfcc558" -dependencies = [ - "stable_deref_trait", -] - [[package]] name = "pango" version = "0.18.3" @@ -2963,7 +2736,7 @@ dependencies = [ "concurrent-queue", "hermit-abi", "pin-project-lite", - "rustix 1.1.4", + "rustix", "windows-sys 0.61.2", ] @@ -2982,15 +2755,6 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" -[[package]] -name = "ppv-lite86" -version = "0.2.21" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9" -dependencies = [ - "zerocopy", -] - [[package]] name = "precomputed-hash" version = "0.1.1" @@ -3089,72 +2853,12 @@ version = "6.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f8dcc9c7d52a811697d2151c701e0d08956f92b0e24136cf4cf27b57a6a0d9bf" -[[package]] -name = "rand" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ca0ecfa931c29007047d1bc58e623ab12e5590e8c7cc53200d5202b69266d8a" -dependencies = [ - "libc", - "rand_chacha", - "rand_core", -] - -[[package]] -name = "rand_chacha" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" -dependencies = [ - "ppv-lite86", - "rand_core", -] - -[[package]] -name = "rand_core" -version = "0.6.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" -dependencies = [ - "getrandom 0.2.17", -] - -[[package]] -name = "rand_distr" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32cb0b9bc82b0a0876c2dd994a7e7a2683d3e7390ca40e6886785ef0c7e3ee31" -dependencies = [ - "num-traits", - "rand", -] - [[package]] name = "raw-window-handle" version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "20675572f6f24e9e76ef639bc5552774ed45f1c30e2951e1e99c59888861c539" -[[package]] -name = "rayon" -version = "1.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb39b166781f92d482534ef4b4b1b2568f42613b53e5b6c160e24cfbfa30926d" -dependencies = [ - "either", - "rayon-core", -] - -[[package]] -name = "rayon-core" -version = "1.13.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22e18b0f0062d30d4230b2e85ff77fdfe4326feb054b9783a3460d8435c8ab91" -dependencies = [ - "crossbeam-deque", - "crossbeam-utils", -] - [[package]] name = "redox_syscall" version = "0.5.18" @@ -3296,22 +3000,6 @@ dependencies = [ "smallvec", ] -[[package]] -name = "rust-stemmers" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e46a2036019fdb888131db7a4c847a1063a7493f971ed94ea82c67eada63ca54" -dependencies = [ - "serde", - "serde_derive", -] - -[[package]] -name = "rustc-hash" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" - [[package]] name = "rustc-hash" version = "2.1.2" @@ -3327,19 +3015,6 @@ dependencies = [ "semver", ] -[[package]] -name = "rustix" -version = "0.38.44" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154" -dependencies = [ - "bitflags 2.13.0", - "errno", - "libc", - "linux-raw-sys 0.4.15", - "windows-sys 0.59.0", -] - [[package]] name = "rustix" version = "1.1.4" @@ -3349,7 +3024,7 @@ dependencies = [ "bitflags 2.13.0", "errno", "libc", - "linux-raw-sys 0.12.1", + "linux-raw-sys", "windows-sys 0.61.2", ] @@ -3439,7 +3114,7 @@ dependencies = [ "phf", "phf_codegen", "precomputed-hash", - "rustc-hash 2.1.2", + "rustc-hash", "servo_arc", "smallvec", ] @@ -3671,15 +3346,6 @@ version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8ee5873ec9cce0195efcb7a4e9507a04cd49aec9c83d0389df45b1ef7ba2e649" -[[package]] -name = "sketches-ddsketch" -version = "0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85636c14b73d81f541e525f585c0a2109e6744e1565b5c1668e31c70c10ed65c" -dependencies = [ - "serde", -] - [[package]] name = "slab" version = "0.4.12" @@ -3897,8 +3563,8 @@ dependencies = [ name = "synapse-search" version = "0.1.0" dependencies = [ + "rusqlite", "synapse-core", - "tantivy", ] [[package]] @@ -3934,147 +3600,6 @@ dependencies = [ "version-compare", ] -[[package]] -name = "tantivy" -version = "0.22.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96599ea6fccd844fc833fed21d2eecac2e6a7c1afd9e044057391d78b1feb141" -dependencies = [ - "aho-corasick", - "arc-swap", - "base64 0.22.1", - "bitpacking", - "byteorder", - "census", - "crc32fast", - "crossbeam-channel", - "downcast-rs", - "fastdivide", - "fnv", - "fs4", - "htmlescape", - "itertools", - "levenshtein_automata", - "log", - "lru", - "lz4_flex", - "measure_time", - "memmap2", - "num_cpus", - "once_cell", - "oneshot", - "rayon", - "regex", - "rust-stemmers", - "rustc-hash 1.1.0", - "serde", - "serde_json", - "sketches-ddsketch", - "smallvec", - "tantivy-bitpacker", - "tantivy-columnar", - "tantivy-common", - "tantivy-fst", - "tantivy-query-grammar", - "tantivy-stacker", - "tantivy-tokenizer-api", - "tempfile", - "thiserror 1.0.69", - "time", - "uuid", - "winapi", -] - -[[package]] -name = "tantivy-bitpacker" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "284899c2325d6832203ac6ff5891b297fc5239c3dc754c5bc1977855b23c10df" -dependencies = [ - "bitpacking", -] - -[[package]] -name = "tantivy-columnar" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12722224ffbe346c7fec3275c699e508fd0d4710e629e933d5736ec524a1f44e" -dependencies = [ - "downcast-rs", - "fastdivide", - "itertools", - "serde", - "tantivy-bitpacker", - "tantivy-common", - "tantivy-sstable", - "tantivy-stacker", -] - -[[package]] -name = "tantivy-common" -version = "0.7.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8019e3cabcfd20a1380b491e13ff42f57bb38bf97c3d5fa5c07e50816e0621f4" -dependencies = [ - "async-trait", - "byteorder", - "ownedbytes", - "serde", - "time", -] - -[[package]] -name = "tantivy-fst" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d60769b80ad7953d8a7b2c70cdfe722bbcdcac6bccc8ac934c40c034d866fc18" -dependencies = [ - "byteorder", - "regex-syntax", - "utf8-ranges", -] - -[[package]] -name = "tantivy-query-grammar" -version = "0.22.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "847434d4af57b32e309f4ab1b4f1707a6c566656264caa427ff4285c4d9d0b82" -dependencies = [ - "nom", -] - -[[package]] -name = "tantivy-sstable" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c69578242e8e9fc989119f522ba5b49a38ac20f576fc778035b96cc94f41f98e" -dependencies = [ - "tantivy-bitpacker", - "tantivy-common", - "tantivy-fst", - "zstd", -] - -[[package]] -name = "tantivy-stacker" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c56d6ff5591fc332739b3ce7035b57995a3ce29a93ffd6012660e0949c956ea8" -dependencies = [ - "murmurhash32", - "rand_distr", - "tantivy-common", -] - -[[package]] -name = "tantivy-tokenizer-api" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a0dcade25819a89cfe6f17d932c9cedff11989936bf6dd4f336d50392053b04" -dependencies = [ - "serde", -] - [[package]] name = "tao" version = "0.35.3" @@ -4434,7 +3959,7 @@ dependencies = [ "fastrand", "getrandom 0.4.3", "once_cell", - "rustix 1.1.4", + "rustix", "windows-sys 0.61.2", ] @@ -4972,12 +4497,6 @@ version = "0.7.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" -[[package]] -name = "utf8-ranges" -version = "1.0.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7fcfc827f90e53a02eaef5e535ee14266c1d569214c6aa70133a624d8a3164ba" - [[package]] name = "utf8_iter" version = "1.0.4" @@ -5438,15 +4957,6 @@ dependencies = [ "windows-targets 0.42.2", ] -[[package]] -name = "windows-sys" -version = "0.52.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" -dependencies = [ - "windows-targets 0.52.6", -] - [[package]] name = "windows-sys" version = "0.59.0" @@ -5843,7 +5353,7 @@ dependencies = [ "hex", "libc", "ordered-stream", - "rustix 1.1.4", + "rustix", "serde", "serde_repr", "tracing", diff --git a/Cargo.toml b/Cargo.toml index 58218d1..917bb0f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,13 +15,13 @@ members = [ [workspace.package] version = "0.1.0" edition = "2021" -license = "MIT OR Apache-2.0" +license = "MIT" authors = ["Synapse contributors"] -repository = "https://github.com/synapse-srs/synapse" +repository = "https://github.com/Emadab/Synapse" rust-version = "1.80" # Shared dependency versions. Crates opt in with `.workspace = true`. -# Heavy/feature-specific deps (rusqlite, tantivy, zip, fsrs, …) are added to the +# Heavy/feature-specific deps (rusqlite, zip, fsrs, …) are added to the # individual crate that owns that concern, in the milestone that introduces it. [workspace.dependencies] serde = { version = "1", features = ["derive"] } diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..e5ad1fe --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2026 Synapse contributors + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md index 1f75ec5..6462ed0 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,9 @@ # Synapse +[![CI](https://github.com/Emadab/Synapse/actions/workflows/ci.yml/badge.svg)](https://github.com/Emadab/Synapse/actions/workflows/ci.yml) +[![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE) +[![Release](https://img.shields.io/github/v/release/Emadab/Synapse)](https://github.com/Emadab/Synapse/releases/latest) + > A beautiful, modern spaced-repetition desktop app — fully compatible with Anki. Synapse wraps Anki's proven scheduling data model in a Linear/Obsidian-grade @@ -10,6 +14,12 @@ experience, while guaranteeing you can move decks in and out of Anki losslessly. - **Offline-first**, native-feeling, keyboard-first - **Tauri + React/TypeScript** over a **UI-agnostic Rust core** +## Install + +Download the latest release for your platform (Windows, macOS, Linux) from the +[Releases page](https://github.com/Emadab/Synapse/releases). Builds are +produced and signed by the [release workflow](.github/workflows/release.yml). + ## Architecture See [`docs/ARCHITECTURE.md`](docs/ARCHITECTURE.md). In short: a platform-agnostic @@ -54,4 +64,9 @@ pnpm build # type-check + production frontend build ## License -MIT OR Apache-2.0 +[MIT](LICENSE) + +--- + +Synapse is an independent project and is not affiliated with, endorsed by, or +sponsored by Ankitects Pty Ltd. "Anki" is a trademark of Ankitects Pty Ltd. diff --git a/SECURITY.md b/SECURITY.md new file mode 100644 index 0000000..89eb23a --- /dev/null +++ b/SECURITY.md @@ -0,0 +1,20 @@ +# Security Policy + +## Supported Versions + +Synapse is pre-1.0. Only the latest release is supported with security fixes. + +| Version | Supported | +| ------- | --------- | +| 0.1.x | ✅ | + +## Reporting a Vulnerability + +Please report security vulnerabilities privately via +[GitHub Security Advisories](https://github.com/Emadab/Synapse/security/advisories/new) +rather than opening a public issue. + +Include as much detail as you can: affected version, reproduction steps, and +impact. This is a small open source project maintained on a best-effort +basis — there's no formal SLA, but reports will be triaged and acknowledged +as soon as possible. diff --git a/apps/desktop/package.json b/apps/desktop/package.json index 213fad5..a783d7b 100644 --- a/apps/desktop/package.json +++ b/apps/desktop/package.json @@ -3,6 +3,12 @@ "private": true, "version": "0.1.0", "type": "module", + "license": "MIT", + "author": "Synapse contributors", + "repository": { + "type": "git", + "url": "https://github.com/Emadab/Synapse.git" + }, "scripts": { "dev": "vite", "build": "tsc --noEmit && vite build", diff --git a/crates/synapse-search/Cargo.toml b/crates/synapse-search/Cargo.toml index 28ea48b..31950eb 100644 --- a/crates/synapse-search/Cargo.toml +++ b/crates/synapse-search/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "synapse-search" -description = "Full-text & faceted search over notes via Tantivy, with an Anki-style query parser." +description = "Full-text & faceted search over notes via SQLite FTS5, with an Anki-style query parser." version.workspace = true edition.workspace = true license.workspace = true @@ -9,4 +9,4 @@ repository.workspace = true [dependencies] synapse-core.workspace = true -tantivy = "0.22" +rusqlite = { version = "0.32", features = ["bundled"] } diff --git a/crates/synapse-search/src/lib.rs b/crates/synapse-search/src/lib.rs index 1e41daf..a290713 100644 --- a/crates/synapse-search/src/lib.rs +++ b/crates/synapse-search/src/lib.rs @@ -1,84 +1,67 @@ //! # synapse-search //! -//! Tantivy-backed full-text + faceted search over notes. The query language is -//! Anki-flavoured: bare words match note text (AND by default), and `tag:`, -//! `deck:` and `note:` filter by facet (e.g. `tag:verb deck:Spanish hola`). -//! The index lives in RAM and is rebuilt from `NoteIndexRow`s; the application -//! keeps it in sync by rebuilding on the relevant `DomainEvent`s. SQLite stays -//! the transactional source of truth. +//! SQLite FTS5-backed full-text + faceted search over notes. The query +//! language is Anki-flavoured: bare words match note text (AND by default), +//! and `tag:`, `deck:` and `note:` filter by facet (e.g. +//! `tag:verb deck:Spanish hola`). The index lives in an in-memory SQLite +//! database and is rebuilt from `NoteIndexRow`s; the application keeps it in +//! sync by rebuilding on the relevant `DomainEvent`s. The on-disk SQLite +//! database (via synapse-db) stays the transactional source of truth. //! -//! `is:` selectors (due/new/suspended) depend on live scheduling state and are -//! intersected at the storage layer — not in the index — so they are not -//! handled here yet. +//! `is:` selectors (due/new/suspended) depend on live scheduling state and +//! are intersected at the storage layer — not in the index — so any +//! `prefix:value` token that isn't `tag:`/`deck:`/`note:` degrades to a plain +//! text match rather than being treated as a facet. +use std::cell::RefCell; + +use rusqlite::Connection; use synapse_core::error::{CoreError, CoreResult}; use synapse_core::model::NoteIndexRow; -use tantivy::collector::TopDocs; -use tantivy::query::QueryParser; -use tantivy::schema::{Field, Schema, Value, STORED, TEXT}; -use tantivy::{doc, Index, IndexReader, TantivyDocument}; -fn err(e: tantivy::TantivyError) -> CoreError { +fn err(e: rusqlite::Error) -> CoreError { CoreError::Other(Box::new(e)) } /// In-memory note search index. pub struct NoteIndex { - index: Index, - reader: IndexReader, - parser: QueryParser, - note_id: Field, - text: Field, - tag: Field, - deck: Field, - notetype: Field, + conn: RefCell, } impl NoteIndex { pub fn new() -> CoreResult { - let mut builder = Schema::builder(); - let note_id = builder.add_i64_field("note_id", STORED); - let text = builder.add_text_field("text", TEXT); - let tag = builder.add_text_field("tag", TEXT); - let deck = builder.add_text_field("deck", TEXT); - let notetype = builder.add_text_field("note", TEXT); - let schema = builder.build(); - - let index = Index::create_in_ram(schema); - let reader = index.reader().map_err(err)?; - let mut parser = QueryParser::for_index(&index, vec![text]); - // Space-separated terms are ANDed, matching Anki. - parser.set_conjunction_by_default(); + let conn = Connection::open_in_memory().map_err(err)?; + conn.execute_batch("CREATE VIRTUAL TABLE notes USING fts5(text, tag, deck, note);") + .map_err(err)?; Ok(Self { - index, - reader, - parser, - note_id, - text, - tag, - deck, - notetype, + conn: RefCell::new(conn), }) } /// Replace the entire index contents with `rows`. pub fn rebuild(&self, rows: &[NoteIndexRow]) -> CoreResult<()> { - let mut writer = self.index.writer(15_000_000).map_err(err)?; - writer.delete_all_documents().map_err(err)?; - for row in rows { - writer - .add_document(doc!( - self.note_id => row.note_id, - self.text => row.text.clone(), - self.tag => row.tags.clone(), - self.deck => row.deck.clone(), - self.notetype => row.notetype.clone(), - )) + let mut conn = self.conn.borrow_mut(); + let tx = conn.transaction().map_err(err)?; + tx.execute("DELETE FROM notes;", []).map_err(err)?; + { + let mut stmt = tx + .prepare( + "INSERT INTO notes(rowid, text, tag, deck, note) VALUES (?1, ?2, ?3, ?4, ?5);", + ) .map_err(err)?; + for row in rows { + stmt.execute(rusqlite::params![ + row.note_id, + row.text, + row.tags, + row.deck, + row.notetype, + ]) + .map_err(err)?; + } } - writer.commit().map_err(err)?; - self.reader.reload().map_err(err)?; + tx.commit().map_err(err)?; Ok(()) } @@ -86,33 +69,75 @@ impl NoteIndex { /// query syntax degrades to a plain text search; an unparseable query /// yields no results rather than an error. pub fn search(&self, query: &str, limit: usize) -> CoreResult> { - let parsed = self - .parser - .parse_query(query) - .or_else(|_| self.parser.parse_query(&sanitize(query))); - let Ok(parsed) = parsed else { + let Some(match_expr) = build_match_expr(query) else { return Ok(vec![]); }; - let searcher = self.reader.searcher(); - let hits = searcher - .search(&parsed, &TopDocs::with_limit(limit)) - .map_err(err)?; + let conn = self.conn.borrow(); + let mut stmt = match conn + .prepare("SELECT rowid FROM notes WHERE notes MATCH ?1 ORDER BY rank LIMIT ?2;") + { + Ok(stmt) => stmt, + Err(_) => return Ok(vec![]), + }; + + let rows = stmt.query_map(rusqlite::params![match_expr, limit as i64], |r| { + r.get::<_, i64>(0) + }); + let rows = match rows { + Ok(rows) => rows, + Err(_) => return Ok(vec![]), + }; - let mut ids = Vec::with_capacity(hits.len()); - for (_score, address) in hits { - let doc: TantivyDocument = searcher.doc(address).map_err(err)?; - if let Some(id) = doc.get_first(self.note_id).and_then(|v| v.as_i64()) { - ids.push(id); + let mut ids = Vec::new(); + for row in rows { + match row { + Ok(id) => ids.push(id), + Err(_) => return Ok(vec![]), } } Ok(ids) } } -/// Strip query operators so a malformed query can still match as plain text. -fn sanitize(query: &str) -> String { - query.replace([':', '"', '(', ')', '+', '-', '*'], " ") +/// Quote `value` as an FTS5 string literal, escaping embedded `"` by +/// doubling it. This is the injection-safety boundary: no raw user substring +/// is ever concatenated unquoted into the MATCH expression, so `AND`/`OR`/ +/// `NOT`/`*`/parens inside user input can't hijack the query. +fn quote(value: &str) -> String { + format!("\"{}\"", value.replace('"', "\"\"")) +} + +/// Translate an Anki-flavoured query string into an FTS5 MATCH expression. +/// Returns `None` if the query has no usable terms. +fn build_match_expr(query: &str) -> Option { + let mut clauses = Vec::new(); + + for token in query.split_whitespace() { + if let Some((prefix, value)) = token.split_once(':') { + if value.is_empty() { + continue; + } + match prefix { + "tag" | "deck" | "note" => { + clauses.push(format!("{prefix}:{}", quote(value))); + } + _ => { + // Unknown facet (e.g. `is:due`): degrade to plain terms. + clauses.push(quote(prefix)); + clauses.push(quote(value)); + } + } + } else if !token.is_empty() { + clauses.push(quote(token)); + } + } + + if clauses.is_empty() { + None + } else { + Some(clauses.join(" AND ")) + } } #[cfg(test)] @@ -164,4 +189,12 @@ mod tests { // `is:due` isn't a known field; should not error. assert!(index.search("is:due hola", 10).is_ok()); } + + #[test] + fn special_characters_do_not_error() { + let index = index(); + assert!(index + .search("O'Brien \"quoted\" AND (test) * -foo", 10) + .is_ok()); + } } From e3ca594e871580552a3c21c92b2d2b12b6496c7f Mon Sep 17 00:00:00 2001 From: emadab <63538622+Emadab@users.noreply.github.com> Date: Thu, 2 Jul 2026 12:17:18 +0330 Subject: [PATCH 2/4] ci: ignore RUSTSEC-2026-0194 (quick-xml DoS) via transitive plist dep quick-xml < 0.41.0 has a quadratic-time duplicate-attribute check, pulled in transitively through tauri-utils -> plist 1.9.0, which pins quick-xml = "^0.39.2". plist is only used by Tauri for macOS Info.plist bundling; Synapse never parses untrusted XML/plist at runtime, so the DoS isn't reachable. No fixed plist release exists yet. --- audit.toml | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 audit.toml diff --git a/audit.toml b/audit.toml new file mode 100644 index 0000000..e40190d --- /dev/null +++ b/audit.toml @@ -0,0 +1,14 @@ +# cargo-audit configuration. See https://docs.rs/cargo-audit/latest/cargo_audit/ + +[advisories] +ignore = [ + # RUSTSEC-2026-0194: quadratic-time duplicate-attribute check in quick-xml + # < 0.41.0. Pulled in transitively via tauri-utils -> plist 1.9.0, which + # pins quick-xml = "^0.39.2" (plist 1.9.0 is its latest release; no fixed + # version is available upstream yet). plist is used by Tauri for + # macOS Info.plist handling during bundling — Synapse never parses + # user-supplied or otherwise untrusted XML/plist input at runtime, so the + # DoS is not reachable in this app. Revisit and drop this ignore once + # plist/tauri-utils bump their quick-xml dependency past 0.41.0. + "RUSTSEC-2026-0194", +] From d1bda4006235a83081fa8ac3bae5adafef43da4b Mon Sep 17 00:00:00 2001 From: emadab <63538622+Emadab@users.noreply.github.com> Date: Thu, 2 Jul 2026 12:21:39 +0330 Subject: [PATCH 3/4] ci: pass RUSTSEC-2026-0194 ignore to audit-check action directly rustsec/audit-check doesn't read audit.toml automatically -- it only respects advisory ids passed via its own `ignore` input. Keep audit.toml too, for local `cargo audit` runs. --- .github/workflows/ci.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 5451f86..ab45b7a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -34,6 +34,10 @@ jobs: uses: rustsec/audit-check@v2 with: token: ${{ secrets.GITHUB_TOKEN }} + # RUSTSEC-2026-0194: quick-xml quadratic-time DoS, pulled in + # transitively via tauri-utils -> plist (macOS bundling only, + # never parses untrusted input at runtime). See audit.toml. + ignore: RUSTSEC-2026-0194 web: name: Web (lint, types, test, build) From 35c1a8836e5b7d86ddbd3bd87419c25baa06219c Mon Sep 17 00:00:00 2001 From: emadab <63538622+Emadab@users.noreply.github.com> Date: Thu, 2 Jul 2026 12:25:28 +0330 Subject: [PATCH 4/4] ci: also ignore RUSTSEC-2026-0195 (quick-xml namespace DoS) Same transitive quick-xml dependency, same non-applicability as RUSTSEC-2026-0194, published to the advisory db moments after that first ignore was added. --- .github/workflows/ci.yml | 5 +++-- audit.toml | 10 ++++++---- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ab45b7a..0e02195 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -34,10 +34,11 @@ jobs: uses: rustsec/audit-check@v2 with: token: ${{ secrets.GITHUB_TOKEN }} - # RUSTSEC-2026-0194: quick-xml quadratic-time DoS, pulled in + # RUSTSEC-2026-0194/0195: quick-xml DoS advisories (quadratic-time + # attribute check / unbounded namespace allocation), pulled in # transitively via tauri-utils -> plist (macOS bundling only, # never parses untrusted input at runtime). See audit.toml. - ignore: RUSTSEC-2026-0194 + ignore: RUSTSEC-2026-0194,RUSTSEC-2026-0195 web: name: Web (lint, types, test, build) diff --git a/audit.toml b/audit.toml index e40190d..e957f7b 100644 --- a/audit.toml +++ b/audit.toml @@ -2,13 +2,15 @@ [advisories] ignore = [ - # RUSTSEC-2026-0194: quadratic-time duplicate-attribute check in quick-xml - # < 0.41.0. Pulled in transitively via tauri-utils -> plist 1.9.0, which - # pins quick-xml = "^0.39.2" (plist 1.9.0 is its latest release; no fixed + # RUSTSEC-2026-0194/0195: DoS advisories (quadratic-time duplicate-attribute + # check, unbounded namespace-declaration allocation) in quick-xml < 0.41.0. + # Pulled in transitively via tauri-utils -> plist 1.9.0, which pins + # quick-xml = "^0.39.2" (plist 1.9.0 is its latest release; no fixed # version is available upstream yet). plist is used by Tauri for # macOS Info.plist handling during bundling — Synapse never parses # user-supplied or otherwise untrusted XML/plist input at runtime, so the - # DoS is not reachable in this app. Revisit and drop this ignore once + # DoS is not reachable in this app. Revisit and drop these ignores once # plist/tauri-utils bump their quick-xml dependency past 0.41.0. "RUSTSEC-2026-0194", + "RUSTSEC-2026-0195", ]