commit 28826af88dee93591f374a9985b55390ceecd7af Author: Jānis L Date: Thu Jun 4 23:57:44 2026 +0300 Port Brave Sync server to Rust Use SQLite for persistence and generate Rust protobuf bindings at build time. Add Docker image support for containerized deployment. Co-Authored-By: codex diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..05355cf --- /dev/null +++ b/.dockerignore @@ -0,0 +1,6 @@ +target +.git +.serena +*.sqlite3 +*.sqlite3-shm +*.sqlite3-wal diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..2bffe2d --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +/target +.serena/ +*.sqlite3 +*.sqlite3-shm +*.sqlite3-wal diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..6a4098b --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,1608 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "adler2" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "320119579fcad9c21884f5c4861d16174d0e06250625266f50fe6898340abefa" + +[[package]] +name = "aho-corasick" +version = "1.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ddd31a130427c27518df266943a5308ed92d4b226cc639f5a8f1002816174301" +dependencies = [ + "memchr", +] + +[[package]] +name = "anyhow" +version = "1.0.102" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f202df86484c868dbad7eaa557ef785d5c66295e41b460ef922eca0723b842c" + +[[package]] +name = "async-trait" +version = "0.1.89" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9035ad2d096bed7955a320ee7e2230574d28fd3c3a0f186cbea1ff3c7eed5dbb" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "atomic-waker" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" + +[[package]] +name = "axum" +version = "0.8.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "31b698c5f9a010f6573133b09e0de5408834d0c82f8d7475a89fc1867a71cd90" +dependencies = [ + "axum-core", + "axum-macros", + "bytes", + "form_urlencoded", + "futures-util", + "http", + "http-body", + "http-body-util", + "hyper", + "hyper-util", + "itoa", + "matchit", + "memchr", + "mime", + "percent-encoding", + "pin-project-lite", + "serde_core", + "serde_json", + "serde_path_to_error", + "serde_urlencoded", + "sync_wrapper", + "tokio", + "tower", + "tower-layer", + "tower-service", + "tracing", +] + +[[package]] +name = "axum-core" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08c78f31d7b1291f7ee735c1c6780ccde7785daae9a9206026862dab7d8792d1" +dependencies = [ + "bytes", + "futures-core", + "http", + "http-body", + "http-body-util", + "mime", + "pin-project-lite", + "sync_wrapper", + "tower-layer", + "tower-service", + "tracing", +] + +[[package]] +name = "axum-macros" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7aa268c23bfbbd2c4363b9cd302a4f504fb2a9dfe7e3451d66f35dd392e20aca" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "base64" +version = "0.22.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" + +[[package]] +name = "base64ct" +version = "1.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2af50177e190e07a26ab74f8b1efbfe2ef87da2116221318cb1c2e82baf7de06" + +[[package]] +name = "bitflags" +version = "2.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "84d7ced0ae9557296835c32bf1b1e02b44c746701f898460fb000d7eaa84f00a" + +[[package]] +name = "block-buffer" +version = "0.10.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71" +dependencies = [ + "generic-array", +] + +[[package]] +name = "brave-sync-rs" +version = "0.1.0" +dependencies = [ + "anyhow", + "async-trait", + "axum", + "base64", + "bytes", + "ed25519-dalek", + "flate2", + "hex", + "prost", + "prost-build", + "protoc-bin-vendored", + "regex", + "rusqlite", + "thiserror", + "tokio", + "tower-http", + "tracing", + "tracing-subscriber", + "uuid", +] + +[[package]] +name = "bumpalo" +version = "3.20.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72f5acc6cb2ba439de613abc23857ec3d78374d8ed5ac84e9d11336e87da8649" + +[[package]] +name = "bytes" +version = "1.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e748733b7cbc798e1434b6ac524f0c1ff2ab456fe201501e6497c8417a4fc33" + +[[package]] +name = "cc" +version = "1.2.63" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "556e016178bb5662a08681bbe0f00f8e17631781a4dfc8c45e466e4b185ec27f" +dependencies = [ + "find-msvc-tools", + "shlex", +] + +[[package]] +name = "cfg-if" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" + +[[package]] +name = "const-oid" +version = "0.9.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" + +[[package]] +name = "cpufeatures" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59ed5838eebb26a2bb2e58f6d5b5316989ae9d08bab10e0e6d103e656d1b0280" +dependencies = [ + "libc", +] + +[[package]] +name = "crc32fast" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9481c1c90cbf2ac953f07c8d4a58aa3945c425b7185c9154d67a65e4230da511" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "crypto-common" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78c8292055d1c1df0cce5d180393dc8cce0abec0a7102adb6c7b1eef6016d60a" +dependencies = [ + "generic-array", + "typenum", +] + +[[package]] +name = "curve25519-dalek" +version = "4.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97fb8b7c4503de7d6ae7b42ab72a5a59857b4c937ec27a3d4539dba95b5ab2be" +dependencies = [ + "cfg-if", + "cpufeatures", + "curve25519-dalek-derive", + "digest", + "fiat-crypto", + "rustc_version", + "subtle", + "zeroize", +] + +[[package]] +name = "curve25519-dalek-derive" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "der" +version = "0.7.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7c1832837b905bbfb5101e07cc24c8deddf52f93225eee6ead5f4d63d53ddcb" +dependencies = [ + "const-oid", + "zeroize", +] + +[[package]] +name = "digest" +version = "0.10.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" +dependencies = [ + "block-buffer", + "crypto-common", +] + +[[package]] +name = "ed25519" +version = "2.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "115531babc129696a58c64a4fef0a8bf9e9698629fb97e9e40767d235cfbcd53" +dependencies = [ + "pkcs8", + "signature", +] + +[[package]] +name = "ed25519-dalek" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70e796c081cee67dc755e1a36a0a172b897fab85fc3f6bc48307991f64e4eca9" +dependencies = [ + "curve25519-dalek", + "ed25519", + "serde", + "sha2", + "subtle", + "zeroize", +] + +[[package]] +name = "either" +version = "1.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91622ff5e7162018101f2fea40d6ebf4a78bbe5a49736a2020649edf9693679e" + +[[package]] +name = "equivalent" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" + +[[package]] +name = "errno" +version = "0.3.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" +dependencies = [ + "libc", + "windows-sys", +] + +[[package]] +name = "fallible-iterator" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2acce4a10f12dc2fb14a218589d4f1f62ef011b2d0cc4b3cb1bba8e94da14649" + +[[package]] +name = "fallible-streaming-iterator" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7360491ce676a36bf9bb3c56c1aa791658183a54d2744120f27285738d90465a" + +[[package]] +name = "fastrand" +version = "2.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f1f227452a390804cdb637b74a86990f2a7d7ba4b7d5693aac9b4dd6defd8d6" + +[[package]] +name = "fiat-crypto" +version = "0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28dea519a9695b9977216879a3ebfddf92f1c08c05d984f8996aecd6ecdc811d" + +[[package]] +name = "find-msvc-tools" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582" + +[[package]] +name = "fixedbitset" +version = "0.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d674e81391d1e1ab681a28d99df07927c6d4aa5b027d7da16ba32d1d21ecd99" + +[[package]] +name = "flate2" +version = "1.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "843fba2746e448b37e26a819579957415c8cef339bf08564fe8b7ddbd959573c" +dependencies = [ + "crc32fast", + "miniz_oxide", +] + +[[package]] +name = "foldhash" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" + +[[package]] +name = "form_urlencoded" +version = "1.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb4cb245038516f5f85277875cdaa4f7d2c9a0fa0468de06ed190163b1581fcf" +dependencies = [ + "percent-encoding", +] + +[[package]] +name = "futures-channel" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07bbe89c50d7a535e539b8c17bc0b49bdb77747034daa8087407d655f3f7cc1d" +dependencies = [ + "futures-core", +] + +[[package]] +name = "futures-core" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e3450815272ef58cec6d564423f6e755e25379b217b0bc688e295ba24df6b1d" + +[[package]] +name = "futures-task" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "037711b3d59c33004d3856fbdc83b99d4ff37a24768fa1be9ce3538a1cde4393" + +[[package]] +name = "futures-util" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "389ca41296e6190b48053de0321d02a77f32f8a5d2461dd38762c0593805c6d6" +dependencies = [ + "futures-core", + "futures-task", + "pin-project-lite", + "slab", +] + +[[package]] +name = "generic-array" +version = "0.14.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +dependencies = [ + "typenum", + "version_check", +] + +[[package]] +name = "getrandom" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff2abc00be7fca6ebc474524697ae276ad847ad0a6b3faa4bcb027e9a4614ad0" +dependencies = [ + "cfg-if", + "libc", + "wasi", +] + +[[package]] +name = "getrandom" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0de51e6874e94e7bf76d726fc5d13ba782deca734ff60d5bb2fb2607c7406555" +dependencies = [ + "cfg-if", + "libc", + "r-efi", + "wasip2", + "wasip3", +] + +[[package]] +name = "hashbrown" +version = "0.15.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1" +dependencies = [ + "foldhash", +] + +[[package]] +name = "hashbrown" +version = "0.17.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed5909b6e89a2db4456e54cd5f673791d7eca6732202bbf2a9cc504fe2f9b84a" + +[[package]] +name = "hashlink" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7382cf6263419f2d8df38c55d7da83da5c18aef87fc7a7fc1fb1e344edfe14c1" +dependencies = [ + "hashbrown 0.15.5", +] + +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" + +[[package]] +name = "http" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8be7462df143984c4598a256ef469b251d7d7f9e271135073e78fc535414f3d0" +dependencies = [ + "bytes", + "itoa", +] + +[[package]] +name = "http-body" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" +dependencies = [ + "bytes", + "http", +] + +[[package]] +name = "http-body-util" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b021d93e26becf5dc7e1b75b1bed1fd93124b374ceb73f43d4d4eafec896a64a" +dependencies = [ + "bytes", + "futures-core", + "http", + "http-body", + "pin-project-lite", +] + +[[package]] +name = "httparse" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87" + +[[package]] +name = "httpdate" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" + +[[package]] +name = "hyper" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55281c53a1894c864990125767da440a4e630446785086f52523b20033b74498" +dependencies = [ + "atomic-waker", + "bytes", + "futures-channel", + "futures-core", + "http", + "http-body", + "httparse", + "httpdate", + "itoa", + "pin-project-lite", + "smallvec", + "tokio", +] + +[[package]] +name = "hyper-util" +version = "0.1.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "96547c2556ec9d12fb1578c4eaf448b04993e7fb79cbaad930a656880a6bdfa0" +dependencies = [ + "bytes", + "http", + "http-body", + "hyper", + "pin-project-lite", + "tokio", + "tower-service", +] + +[[package]] +name = "id-arena" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d3067d79b975e8844ca9eb072e16b31c3c1c36928edf9c6789548c524d0d954" + +[[package]] +name = "indexmap" +version = "2.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d466e9454f08e4a911e14806c24e16fba1b4c121d1ea474396f396069cf949d9" +dependencies = [ + "equivalent", + "hashbrown 0.17.1", + "serde", + "serde_core", +] + +[[package]] +name = "itertools" +version = "0.14.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2b192c782037fadd9cfa75548310488aabdbf3d2da73885b31bd0abd03351285" +dependencies = [ + "either", +] + +[[package]] +name = "itoa" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682" + +[[package]] +name = "js-sys" +version = "0.3.99" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "142bc4740e452c1e57ade0cbc129f139c9093e354346f0872ef985f4f5cf5f11" +dependencies = [ + "cfg-if", + "futures-util", + "once_cell", + "wasm-bindgen", +] + +[[package]] +name = "lazy_static" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" + +[[package]] +name = "leb128fmt" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09edd9e8b54e49e587e4f6295a7d29c3ea94d469cb40ab8ca70b288248a81db2" + +[[package]] +name = "libc" +version = "0.2.186" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68ab91017fe16c622486840e4c83c9a37afeff978bd239b5293d61ece587de66" + +[[package]] +name = "libsqlite3-sys" +version = "0.35.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "133c182a6a2c87864fe97778797e46c7e999672690dc9fa3ee8e241aa4a9c13f" +dependencies = [ + "cc", + "pkg-config", + "vcpkg", +] + +[[package]] +name = "linux-raw-sys" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a66949e030da00e8c7d4434b251670a91556f4144941d37452769c25d58a53" + +[[package]] +name = "log" +version = "0.4.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "953f07c43838f8e6f9758cab68bf5bed85465e7587ebe0b823f1bcd81978ad3a" + +[[package]] +name = "matchers" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1525a2a28c7f4fa0fc98bb91ae755d1e2d1505079e05539e35bc876b5d65ae9" +dependencies = [ + "regex-automata", +] + +[[package]] +name = "matchit" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47e1ffaa40ddd1f3ed91f717a33c8c0ee23fff369e3aa8772b9605cc1d22f4c3" + +[[package]] +name = "memchr" +version = "2.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b947ae49db0d222b1dbc6b113ce7248a3fc3a6ca21b696717bfc000ba4484d8" + +[[package]] +name = "mime" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" + +[[package]] +name = "miniz_oxide" +version = "0.8.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fa76a2c86f704bdb222d66965fb3d63269ce38518b83cb0575fca855ebb6316" +dependencies = [ + "adler2", + "simd-adler32", +] + +[[package]] +name = "mio" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "02bd0af71c67b473010cbbc60715ee815645a4dc942899111f494b4b737d6fda" +dependencies = [ + "libc", + "wasi", + "windows-sys", +] + +[[package]] +name = "multimap" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d87ecb2933e8aeadb3e3a02b828fed80a7528047e68b4f424523a0981a3a084" + +[[package]] +name = "nu-ansi-term" +version = "0.50.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7957b9740744892f114936ab4a57b3f487491bbeafaf8083688b16841a4240e5" +dependencies = [ + "windows-sys", +] + +[[package]] +name = "once_cell" +version = "1.21.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50" + +[[package]] +name = "percent-encoding" +version = "2.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" + +[[package]] +name = "petgraph" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8701b58ea97060d5e5b155d383a69952a60943f0e6dfe30b04c287beb0b27455" +dependencies = [ + "fixedbitset", + "hashbrown 0.15.5", + "indexmap", +] + +[[package]] +name = "pin-project-lite" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd" + +[[package]] +name = "pkcs8" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" +dependencies = [ + "der", + "spki", +] + +[[package]] +name = "pkg-config" +version = "0.3.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19f132c84eca552bf34cab8ec81f1c1dcc229b811638f9d283dceabe58c5569e" + +[[package]] +name = "prettyplease" +version = "0.2.37" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b" +dependencies = [ + "proc-macro2", + "syn", +] + +[[package]] +name = "proc-macro2" +version = "1.0.106" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "prost" +version = "0.14.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2ea70524a2f82d518bce41317d0fae74151505651af45faf1ffbd6fd33f0568" +dependencies = [ + "bytes", + "prost-derive", +] + +[[package]] +name = "prost-build" +version = "0.14.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "343d3bd7056eda839b03204e68deff7d1b13aba7af2b2fd16890697274262ee7" +dependencies = [ + "heck", + "itertools", + "log", + "multimap", + "petgraph", + "prettyplease", + "prost", + "prost-types", + "regex", + "syn", + "tempfile", +] + +[[package]] +name = "prost-derive" +version = "0.14.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "27c6023962132f4b30eb4c172c91ce92d933da334c59c23cddee82358ddafb0b" +dependencies = [ + "anyhow", + "itertools", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "prost-types" +version = "0.14.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8991c4cbdb8bc5b11f0b074ffe286c30e523de90fee5ba8132f1399f23cb3dd7" +dependencies = [ + "prost", +] + +[[package]] +name = "protoc-bin-vendored" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1c381df33c98266b5f08186583660090a4ffa0889e76c7e9a5e175f645a67fa" +dependencies = [ + "protoc-bin-vendored-linux-aarch_64", + "protoc-bin-vendored-linux-ppcle_64", + "protoc-bin-vendored-linux-s390_64", + "protoc-bin-vendored-linux-x86_32", + "protoc-bin-vendored-linux-x86_64", + "protoc-bin-vendored-macos-aarch_64", + "protoc-bin-vendored-macos-x86_64", + "protoc-bin-vendored-win32", +] + +[[package]] +name = "protoc-bin-vendored-linux-aarch_64" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c350df4d49b5b9e3ca79f7e646fde2377b199e13cfa87320308397e1f37e1a4c" + +[[package]] +name = "protoc-bin-vendored-linux-ppcle_64" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a55a63e6c7244f19b5c6393f025017eb5d793fd5467823a099740a7a4222440c" + +[[package]] +name = "protoc-bin-vendored-linux-s390_64" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1dba5565db4288e935d5330a07c264a4ee8e4a5b4a4e6f4e83fad824cc32f3b0" + +[[package]] +name = "protoc-bin-vendored-linux-x86_32" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8854774b24ee28b7868cd71dccaae8e02a2365e67a4a87a6cd11ee6cdbdf9cf5" + +[[package]] +name = "protoc-bin-vendored-linux-x86_64" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b38b07546580df720fa464ce124c4b03630a6fb83e05c336fea2a241df7e5d78" + +[[package]] +name = "protoc-bin-vendored-macos-aarch_64" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "89278a9926ce312e51f1d999fee8825d324d603213344a9a706daa009f1d8092" + +[[package]] +name = "protoc-bin-vendored-macos-x86_64" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81745feda7ccfb9471d7a4de888f0652e806d5795b61480605d4943176299756" + +[[package]] +name = "protoc-bin-vendored-win32" +version = "3.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95067976aca6421a523e491fce939a3e65249bac4b977adee0ee9771568e8aa3" + +[[package]] +name = "quote" +version = "1.0.45" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41f2619966050689382d2b44f664f4bc593e129785a36d6ee376ddf37259b924" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "r-efi" +version = "6.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8dcc9c7d52a811697d2151c701e0d08956f92b0e24136cf4cf27b57a6a0d9bf" + +[[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 = "regex" +version = "1.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e10754a14b9137dd7b1e3e5b0493cc9171fdd105e0ab477f51b72e7f3ac0e276" +dependencies = [ + "aho-corasick", + "memchr", + "regex-automata", + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e1dd4122fc1595e8162618945476892eefca7b88c52820e74af6262213cae8f" +dependencies = [ + "aho-corasick", + "memchr", + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.8.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc897dd8d9e8bd1ed8cdad82b5966c3e0ecae09fb1907d58efaa013543185d0a" + +[[package]] +name = "rusqlite" +version = "0.37.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "165ca6e57b20e1351573e3729b958bc62f0e48025386970b6e4d29e7a7e71f3f" +dependencies = [ + "bitflags", + "fallible-iterator", + "fallible-streaming-iterator", + "hashlink", + "libsqlite3-sys", + "smallvec", +] + +[[package]] +name = "rustc_version" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" +dependencies = [ + "semver", +] + +[[package]] +name = "rustix" +version = "1.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6fe4565b9518b83ef4f91bb47ce29620ca828bd32cb7e408f0062e9930ba190" +dependencies = [ + "bitflags", + "errno", + "libc", + "linux-raw-sys", + "windows-sys", +] + +[[package]] +name = "rustversion" +version = "1.0.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" + +[[package]] +name = "ryu" +version = "1.0.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9774ba4a74de5f7b1c1451ed6cd5285a32eddb5cccb8cc655a4e50009e06477f" + +[[package]] +name = "semver" +version = "1.0.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a7852d02fc848982e0c167ef163aaff9cd91dc640ba85e263cb1ce46fae51cd" + +[[package]] +name = "serde" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" +dependencies = [ + "serde_core", +] + +[[package]] +name = "serde_core" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json" +version = "1.0.150" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8014e44b4736ed0538adeecded0fce2a272f22dc9578a7eb6b2d9993c74cfb9" +dependencies = [ + "itoa", + "memchr", + "serde", + "serde_core", + "zmij", +] + +[[package]] +name = "serde_path_to_error" +version = "0.1.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "10a9ff822e371bb5403e391ecd83e182e0e77ba7f6fe0160b795797109d1b457" +dependencies = [ + "itoa", + "serde", + "serde_core", +] + +[[package]] +name = "serde_urlencoded" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" +dependencies = [ + "form_urlencoded", + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "sha2" +version = "0.10.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283" +dependencies = [ + "cfg-if", + "cpufeatures", + "digest", +] + +[[package]] +name = "sharded-slab" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" +dependencies = [ + "lazy_static", +] + +[[package]] +name = "shlex" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8fadd59c855ef2080decdef8ff161eb6661b86933c9d82e5ba29dc602a55aba" + +[[package]] +name = "signal-hook-registry" +version = "1.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c4db69cba1110affc0e9f7bcd48bbf87b3f4fc7c61fc9155afd4c469eb3d6c1b" +dependencies = [ + "errno", + "libc", +] + +[[package]] +name = "signature" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" +dependencies = [ + "rand_core", +] + +[[package]] +name = "simd-adler32" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "703d5c7ef118737c72f1af64ad2f6f8c5e1921f818cdcb97b8fe6fc69bf66214" + +[[package]] +name = "slab" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c790de23124f9ab44544d7ac05d60440adc586479ce501c1d6d7da3cd8c9cf5" + +[[package]] +name = "smallvec" +version = "1.15.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03" + +[[package]] +name = "socket2" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52d1cfed4120b4d927bf7c0f86d2087a4a7d6027c906d9f9d525a80573b9be51" +dependencies = [ + "libc", + "windows-sys", +] + +[[package]] +name = "spki" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d" +dependencies = [ + "base64ct", + "der", +] + +[[package]] +name = "subtle" +version = "2.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" + +[[package]] +name = "syn" +version = "2.0.117" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e665b8803e7b1d2a727f4023456bbbbe74da67099c585258af0ad9c5013b9b99" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "sync_wrapper" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bf256ce5efdfa370213c1dabab5935a12e49f2c58d15e9eac2870d3b4f27263" + +[[package]] +name = "tempfile" +version = "3.27.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32497e9a4c7b38532efcdebeef879707aa9f794296a4f0244f6f69e9bc8574bd" +dependencies = [ + "fastrand", + "getrandom 0.4.2", + "once_cell", + "rustix", + "windows-sys", +] + +[[package]] +name = "thiserror" +version = "2.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4288b5bcbc7920c07a1149a35cf9590a2aa808e0bc1eafaade0b80947865fbc4" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "2.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebc4ee7f67670e9b64d05fa4253e753e016c6c95ff35b89b7941d6b856dec1d5" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "thread_local" +version = "1.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f60246a4944f24f6e018aa17cdeffb7818b76356965d03b07d6a9886e8962185" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "tokio" +version = "1.52.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fc7f01b389ac15039e4dc9531aa973a135d7a4135281b12d7c1bc79fd57fffe" +dependencies = [ + "libc", + "mio", + "pin-project-lite", + "signal-hook-registry", + "socket2", + "tokio-macros", + "windows-sys", +] + +[[package]] +name = "tokio-macros" +version = "2.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "385a6cb71ab9ab790c5fe8d67f1645e6c450a7ce006a33de03daa956cf70a496" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "tower" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebe5ef63511595f1344e2d5cfa636d973292adc0eec1f0ad45fae9f0851ab1d4" +dependencies = [ + "futures-core", + "futures-util", + "pin-project-lite", + "sync_wrapper", + "tokio", + "tower-layer", + "tower-service", + "tracing", +] + +[[package]] +name = "tower-http" +version = "0.6.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4cfcf7e2740e6fc6d4d688b4ef00650406bb94adf4731e43c096c3a19fe40840" +dependencies = [ + "bitflags", + "bytes", + "http", + "http-body", + "http-body-util", + "pin-project-lite", + "tower-layer", + "tower-service", + "tracing", +] + +[[package]] +name = "tower-layer" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "121c2a6cda46980bb0fcd1647ffaf6cd3fc79a013de288782836f6df9c48780e" + +[[package]] +name = "tower-service" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" + +[[package]] +name = "tracing" +version = "0.1.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "63e71662fa4b2a2c3a26f570f037eb95bb1f85397f3cd8076caed2f026a6d100" +dependencies = [ + "log", + "pin-project-lite", + "tracing-attributes", + "tracing-core", +] + +[[package]] +name = "tracing-attributes" +version = "0.1.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7490cfa5ec963746568740651ac6781f701c9c5ea257c58e057f3ba8cf69e8da" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "tracing-core" +version = "0.1.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db97caf9d906fbde555dd62fa95ddba9eecfd14cb388e4f491a66d74cd5fb79a" +dependencies = [ + "once_cell", + "valuable", +] + +[[package]] +name = "tracing-log" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3" +dependencies = [ + "log", + "once_cell", + "tracing-core", +] + +[[package]] +name = "tracing-subscriber" +version = "0.3.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb7f578e5945fb242538965c2d0b04418d38ec25c79d160cd279bf0731c8d319" +dependencies = [ + "matchers", + "nu-ansi-term", + "once_cell", + "regex-automata", + "sharded-slab", + "smallvec", + "thread_local", + "tracing", + "tracing-core", + "tracing-log", +] + +[[package]] +name = "typenum" +version = "1.20.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6f5e870be6c3b371b77fe0ee0bafb859fa4964b4404c27de1d380043c4dda20" + +[[package]] +name = "unicode-ident" +version = "1.0.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6e4313cd5fcd3dad5cafa179702e2b244f760991f45397d14d4ebf38247da75" + +[[package]] +name = "unicode-xid" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" + +[[package]] +name = "uuid" +version = "1.23.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d258b83ceec21034727ecee8c382cfa6c3e133699b0742c64571814fb420c9f7" +dependencies = [ + "getrandom 0.4.2", + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "valuable" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba73ea9cf16a25df0c8caa16c51acb937d5712a8429db78a3ee29d5dcacd3a65" + +[[package]] +name = "vcpkg" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" + +[[package]] +name = "version_check" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" + +[[package]] +name = "wasi" +version = "0.11.1+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" + +[[package]] +name = "wasip2" +version = "1.0.3+wasi-0.2.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "20064672db26d7cdc89c7798c48a0fdfac8213434a1186e5ef29fd560ae223d6" +dependencies = [ + "wit-bindgen 0.57.1", +] + +[[package]] +name = "wasip3" +version = "0.4.0+wasi-0.3.0-rc-2026-01-06" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5428f8bf88ea5ddc08faddef2ac4a67e390b88186c703ce6dbd955e1c145aca5" +dependencies = [ + "wit-bindgen 0.51.0", +] + +[[package]] +name = "wasm-bindgen" +version = "0.2.122" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ed04576f974d2b2fba0f38c51dbc5518011e38c36bf1143164be765528fd409" +dependencies = [ + "cfg-if", + "once_cell", + "rustversion", + "wasm-bindgen-macro", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.122" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "916151b09da36bd82f6615cbf3a419e2f0ba23a03c6160e8e92eb6bd4aa1dec6" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.122" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "299047362ccbfce148b67ab7e73349f77748e00c8296f9542adfad2ad82c5c5e" +dependencies = [ + "bumpalo", + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.122" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a929b2c61f11ba3e9bc35b50c1f25cb38e0e892c0c231ae2b8cf78d5dad4437" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "wasm-encoder" +version = "0.244.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "990065f2fe63003fe337b932cfb5e3b80e0b4d0f5ff650e6985b1048f62c8319" +dependencies = [ + "leb128fmt", + "wasmparser", +] + +[[package]] +name = "wasm-metadata" +version = "0.244.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb0e353e6a2fbdc176932bbaab493762eb1255a7900fe0fea1a2f96c296cc909" +dependencies = [ + "anyhow", + "indexmap", + "wasm-encoder", + "wasmparser", +] + +[[package]] +name = "wasmparser" +version = "0.244.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47b807c72e1bac69382b3a6fb3dbe8ea4c0ed87ff5629b8685ae6b9a611028fe" +dependencies = [ + "bitflags", + "hashbrown 0.15.5", + "indexmap", + "semver", +] + +[[package]] +name = "windows-link" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" + +[[package]] +name = "windows-sys" +version = "0.61.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc" +dependencies = [ + "windows-link", +] + +[[package]] +name = "wit-bindgen" +version = "0.51.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7249219f66ced02969388cf2bb044a09756a083d0fab1e566056b04d9fbcaa5" +dependencies = [ + "wit-bindgen-rust-macro", +] + +[[package]] +name = "wit-bindgen" +version = "0.57.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ebf944e87a7c253233ad6766e082e3cd714b5d03812acc24c318f549614536e" + +[[package]] +name = "wit-bindgen-core" +version = "0.51.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea61de684c3ea68cb082b7a88508a8b27fcc8b797d738bfc99a82facf1d752dc" +dependencies = [ + "anyhow", + "heck", + "wit-parser", +] + +[[package]] +name = "wit-bindgen-rust" +version = "0.51.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b7c566e0f4b284dd6561c786d9cb0142da491f46a9fbed79ea69cdad5db17f21" +dependencies = [ + "anyhow", + "heck", + "indexmap", + "prettyplease", + "syn", + "wasm-metadata", + "wit-bindgen-core", + "wit-component", +] + +[[package]] +name = "wit-bindgen-rust-macro" +version = "0.51.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c0f9bfd77e6a48eccf51359e3ae77140a7f50b1e2ebfe62422d8afdaffab17a" +dependencies = [ + "anyhow", + "prettyplease", + "proc-macro2", + "quote", + "syn", + "wit-bindgen-core", + "wit-bindgen-rust", +] + +[[package]] +name = "wit-component" +version = "0.244.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d66ea20e9553b30172b5e831994e35fbde2d165325bec84fc43dbf6f4eb9cb2" +dependencies = [ + "anyhow", + "bitflags", + "indexmap", + "log", + "serde", + "serde_derive", + "serde_json", + "wasm-encoder", + "wasm-metadata", + "wasmparser", + "wit-parser", +] + +[[package]] +name = "wit-parser" +version = "0.244.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ecc8ac4bc1dc3381b7f59c34f00b67e18f910c2c0f50015669dde7def656a736" +dependencies = [ + "anyhow", + "id-arena", + "indexmap", + "log", + "semver", + "serde", + "serde_derive", + "serde_json", + "unicode-xid", + "wasmparser", +] + +[[package]] +name = "zeroize" +version = "1.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b97154e67e32c85465826e8bcc1c59429aaaf107c1e4a9e53c8d8ccd5eff88d0" + +[[package]] +name = "zmij" +version = "1.0.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8848ee67ecc8aedbaf3e4122217aff892639231befc6a1b58d29fff4c2cabaa" diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..a7c1a8f --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,27 @@ +[package] +name = "brave-sync-rs" +version = "0.1.0" +edition = "2024" + +[dependencies] +anyhow = "1" +async-trait = "0.1" +axum = { version = "0.8", features = ["macros"] } +base64 = "0.22" +bytes = "1" +ed25519-dalek = "2" +flate2 = "1" +hex = "0.4" +prost = "0.14" +regex = "1" +rusqlite = { version = "0.37", features = ["bundled"] } +thiserror = "2" +tokio = { version = "1", features = ["macros", "net", "rt-multi-thread", "signal"] } +tower-http = { version = "0.6", features = ["limit", "trace"] } +tracing = "0.1" +tracing-subscriber = { version = "0.3", features = ["env-filter"] } +uuid = { version = "1", features = ["v4"] } + +[build-dependencies] +prost-build = "0.14" +protoc-bin-vendored = "3" diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..8e5ba24 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,33 @@ +FROM rust:1.96-bookworm AS builder + +WORKDIR /app + +COPY Cargo.toml Cargo.lock build.rs ./ +COPY schema ./schema +COPY src ./src + +RUN cargo build --release --locked + +FROM debian:bookworm-slim AS runtime + +RUN apt-get update \ + && apt-get install -y --no-install-recommends gosu \ + && rm -rf /var/lib/apt/lists/* \ + && useradd --system --uid 10001 --home-dir /var/lib/brave-sync brave-sync \ + && mkdir -p /var/lib/brave-sync \ + && chown -R brave-sync:brave-sync /var/lib/brave-sync + +COPY --from=builder /app/target/release/brave-sync-rs /usr/local/bin/brave-sync-rs +COPY docker-entrypoint.sh /usr/local/bin/docker-entrypoint.sh +RUN chmod +x /usr/local/bin/docker-entrypoint.sh + +WORKDIR /var/lib/brave-sync + +ENV LISTEN_ADDR=0.0.0.0:8295 +ENV SQLITE_PATH=/var/lib/brave-sync/brave-sync.sqlite3 + +EXPOSE 8295 +VOLUME ["/var/lib/brave-sync"] + +ENTRYPOINT ["docker-entrypoint.sh"] +CMD ["/usr/local/bin/brave-sync-rs"] diff --git a/README.md b/README.md new file mode 100644 index 0000000..e264b55 --- /dev/null +++ b/README.md @@ -0,0 +1,43 @@ +# Brave Sync Server v2 Rust Port + +Rust port of the Brave Sync v2 command server from `/home/user/go-sync`. + +The server exposes: + +- `GET /` +- `GET /health-check` +- `POST /v2/command/` +- `GET /metrics` + +## Storage + +This port uses SQLite instead of DynamoDB. On startup it creates the required +tables automatically. + +Environment variables: + +- `SQLITE_PATH`: SQLite database path. Defaults to `brave-sync.sqlite3`. +- `LISTEN_ADDR`: HTTP listen address. Defaults to `0.0.0.0:8295`. +- `BLOCKED_CLIENT_IDS`: comma-separated lowercase or uppercase client public key hex values. +- `HIGH_DEVICE_LIMIT_CLIENT_IDS`: comma-separated client IDs allowed up to 100 active devices. + +## Build and Test + +```sh +cargo test +cargo run +``` + +## Docker + +```sh +docker build -t brave-sync-rs . +docker run --rm -p 8295:8295 -v brave-sync-data:/var/lib/brave-sync brave-sync-rs +``` + +For bind mounts, the container starts as root only long enough to create/chown +the SQLite directory, then runs the server as the `brave-sync` user. + +The protobuf Rust bindings are generated at build time from +`schema/protobuf/sync_pb`. A vendored `protoc` binary is used, so a system +`protoc` install is not required. diff --git a/build.rs b/build.rs new file mode 100644 index 0000000..eec1291 --- /dev/null +++ b/build.rs @@ -0,0 +1,21 @@ +use std::{env, path::PathBuf}; + +fn main() -> Result<(), Box> { + let proto_dir = PathBuf::from("schema/protobuf/sync_pb"); + let mut protos = Vec::new(); + for entry in std::fs::read_dir(&proto_dir)? { + let path = entry?.path(); + if path.extension().is_some_and(|ext| ext == "proto") { + println!("cargo:rerun-if-changed={}", path.display()); + protos.push(path); + } + } + + let protoc = protoc_bin_vendored::protoc_bin_path()?; + unsafe { + env::set_var("PROTOC", protoc); + } + + prost_build::Config::new().compile_protos(&protos, &[proto_dir])?; + Ok(()) +} diff --git a/docker-entrypoint.sh b/docker-entrypoint.sh new file mode 100644 index 0000000..e052679 --- /dev/null +++ b/docker-entrypoint.sh @@ -0,0 +1,12 @@ +#!/bin/sh +set -eu + +data_dir="${SQLITE_PATH%/*}" +if [ "$data_dir" = "$SQLITE_PATH" ]; then + data_dir="/var/lib/brave-sync" +fi + +mkdir -p "$data_dir" +chown -R brave-sync:brave-sync "$data_dir" + +exec gosu brave-sync "$@" diff --git a/schema/protobuf/sync_pb/app_list_specifics.proto b/schema/protobuf/sync_pb/app_list_specifics.proto new file mode 100644 index 0000000..4af34a0 --- /dev/null +++ b/schema/protobuf/sync_pb/app_list_specifics.proto @@ -0,0 +1,110 @@ +// Copyright 2013 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Sync protocol datatype extension for the app list (aka app launcher). + +// If you change or add any fields in this file, update proto_visitors.h and +// potentially proto_enum_conversions.{h, cc}. + +syntax = "proto2"; + +option go_package = "./sync_pb"; + +option java_multiple_files = true; +option java_package = "org.chromium.components.sync.protocol"; + +option optimize_for = LITE_RUNTIME; + +package sync_pb; + +// Properties of app list objects. +message AppListSpecifics { + // Unique identifier for the item: + // * TYPE_FOLDER: Folder id (generated) + // * TYPE_APP: App Id + optional string item_id = 1; + + // What type of item this is. + enum AppListItemType { + // An app, whether a web app, Android app, etc. + // + // For bookmark apps (URL shortcuts), additional information such as their + // URLs are kept in the AppSpecifics.bookmark_app_foobar fields. + TYPE_APP = 1; + // A request to remove any matching default installed apps. + TYPE_REMOVE_DEFAULT_APP = 2; + // A folder containing entries whose |parent_id| matches |item_id|. + TYPE_FOLDER = 3; + // Obsolete type, intended for URL shortcuts, that was never implemented. + TYPE_OBSOLETE_URL = 4; + // A "page break" item (Indicate creation of a new page in app list). + TYPE_PAGE_BREAK = 5; + } + optional AppListItemType item_type = 2; + + // Item name (FOLDER). + optional string item_name = 3; + + // Id of the parent (folder) item. + optional string parent_id = 4; + + // Marked OBSOLETE because this is unused for the app list. + // Which page this item will appear on in the app list. + optional string OBSOLETE_page_ordinal = 5 [deprecated = true]; + + // Where on a page this item will appear. + optional string item_ordinal = 6; + + // Where on a shelf this item will appear. + // Note that not all apps are pinned to the shelf by the user -- some might + // originate from the PinnedLauncherApps policy. See `is_user_pinned` for more + // details. + optional string item_pin_ordinal = 7; + + // The color groups used for grouping together icons by colors. + enum ColorGroup { + COLOR_EMPTY = 0; + COLOR_WHITE = 1; + COLOR_RED = 2; + COLOR_ORANGE = 3; + COLOR_YELLOW = 4; + COLOR_GREEN = 5; + COLOR_BLUE = 6; + COLOR_MAGENTA = 7; + COLOR_BLACK = 8; + } + + message IconColor { + // The item icon's background color. + optional ColorGroup background_color = 1; + + // The item icon's hue. + optional int32 hue = 2; + } + optional IconColor item_color = 8; + + // Whether the app was pinned to shelf by the user or not (apps can also be + // pinned by other means such as enterprise policies). + // The eventual consistency (a sufficient amount of time after the rollout) + // promise here is for this field to be synced with the pin ordinal: + // `item_pin_ordinal.IsValid() <=> is_user_pinned.has_value()`. + // However, it's okay for this contract to be violated in the meantine. + // + // * missing value indicates that either `item_pin_ordinal` is invalid or + // this field is new and hasn't yet been processed by sync. + // * `true` means that the app was pinned by the user. + // This definition is used in a relaxed way -- for instance, default + // OS apps that are shown in the shelf (like Chrome itself) also have this + // value set to true. + // * `false` means that the app was pinned by PinnedLauncherApps policy. + // Note that user pin has priority: if an app was first pinned by the user + // and then additionally specified in PinnedLauncherApps, this value will + // be set to true. + optional bool is_user_pinned = 9; + + // Identifier for the app package of the item. Package Ids are stable and + // globally unique across app platforms, whereas App Id stored in item_id is + // not. + optional string promise_package_id = 10; +} diff --git a/schema/protobuf/sync_pb/app_setting_specifics.proto b/schema/protobuf/sync_pb/app_setting_specifics.proto new file mode 100644 index 0000000..40de725 --- /dev/null +++ b/schema/protobuf/sync_pb/app_setting_specifics.proto @@ -0,0 +1,28 @@ +// Copyright 2012 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Sync protocol datatype extension for an app setting. +// This is the same as for an extension setting, but uses a separate datatype +// in order to control syncability separately. + +// If you change or add any fields in this file, update proto_visitors.h and +// potentially proto_enum_conversions.{h, cc}. + +syntax = "proto2"; + +option go_package = "./sync_pb"; + +option java_multiple_files = true; +option java_package = "org.chromium.components.sync.protocol"; + +option optimize_for = LITE_RUNTIME; + +package sync_pb; + +import "extension_setting_specifics.proto"; + +// Properties of app setting sync objects; just an extension setting. +message AppSettingSpecifics { + optional ExtensionSettingSpecifics extension_setting = 1; +} diff --git a/schema/protobuf/sync_pb/app_specifics.proto b/schema/protobuf/sync_pb/app_specifics.proto new file mode 100644 index 0000000..c8354c8 --- /dev/null +++ b/schema/protobuf/sync_pb/app_specifics.proto @@ -0,0 +1,103 @@ +// Copyright 2012 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Sync protocol datatype extension for apps. + +// If you change or add any fields in this file, update proto_visitors.h and +// potentially proto_enum_conversions.{h, cc}. + +syntax = "proto2"; + +option go_package = "./sync_pb"; + +option java_multiple_files = true; +option java_package = "org.chromium.components.sync.protocol"; + +option optimize_for = LITE_RUNTIME; + +package sync_pb; + +import "extension_specifics.proto"; + +// Settings related to push notifications for apps. +message AppNotificationSettings { + // DEPRECATED: Use oauth_client_id below. + // Whether or not the user has setup notifications at least once. + // The value for this field will start out false and will be set + // to true when the user accepts receiving notifications for the + // first time and then it will always remain true. + optional bool initial_setup_done = 1 [deprecated = true]; + + // Whether or not the user has disabled notifications. + optional bool disabled = 2; + + // OAuth2 client id to which the user granted the notification permission. + // This field will start out empty. + // It will be set when the user accepts receiving notifications. + // This field is used when the user revokes the notifications permission. + // Note that it is never cleared after it was set once. Hence, the presence + // of this field can be used to determine if the user has setup notifications + // at least once for the given app. + optional string oauth_client_id = 3; +} + +// Information about a linked app icon. +message LinkedAppIconInfo { + // The URL of the app icon. + optional string url = 1; + + // The size of the app icon in DIPs. + optional uint32 size = 2; +} + +// Properties of app sync objects. +// +// For now, an app is just an extension. We keep the two data types +// separate for future-proofing purposes. +message AppSpecifics { + // Extension data. + optional ExtensionSpecifics extension = 1; + + // Notification settings. + optional AppNotificationSettings notification_settings = 2; + + // This controls where on a page this application icon will appear. + optional string app_launch_ordinal = 3; + + // This specifics which page the application icon will appear on in the NTP. + // This values only provide the order within the application pages, not within + // all of the panels in the NTP. + optional string page_ordinal = 4; + + // The possible launch types for an app. + // This enum should be kept in sync with extensions::LaunchType. + enum LaunchType { + PINNED = 0; + REGULAR = 1; + FULLSCREEN = 2; + WINDOW = 3; + } + + // This describes how the extension should be launched. + optional LaunchType launch_type = 5; + + // DEPRECATED. See https://crbug.com/1233303. + optional string bookmark_app_url = 6 [deprecated = true]; + + // DEPRECATED. See https://crbug.com/1233303. + optional string bookmark_app_description = 7 [deprecated = true]; + + // DEPRECATED. See https://crbug.com/1233303. + optional string bookmark_app_icon_color = 8 [deprecated = true]; + + // This is information about linked icons (that is, icons that are downloaded + // from outside the app's bundle of files. + repeated LinkedAppIconInfo linked_app_icons = 9; + + // DEPRECATED. See https://crbug.com/1233303. + optional string bookmark_app_scope = 10 [deprecated = true]; + + // DEPRECATED. See https://crbug.com/1233303. + optional uint32 bookmark_app_theme_color = 11 [deprecated = true]; +} diff --git a/schema/protobuf/sync_pb/arc_package_specifics.proto b/schema/protobuf/sync_pb/arc_package_specifics.proto new file mode 100644 index 0000000..e24f1ee --- /dev/null +++ b/schema/protobuf/sync_pb/arc_package_specifics.proto @@ -0,0 +1,32 @@ +// Copyright 2016 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Sync protocol datatype extension for ARC pakcages. + +// If you change or add any fields in this file, update proto_visitors.h and +// potentially proto_enum_conversions.{h, cc}. + +syntax = "proto2"; + +option go_package = "./sync_pb"; + +option java_multiple_files = true; +option java_package = "org.chromium.components.sync.protocol"; + +option optimize_for = LITE_RUNTIME; + +package sync_pb; + +// Properties of arc package objects. +message ArcPackageSpecifics { + // Unique identifier for the item: + // Android package name. + optional string package_name = 1; + // Android package version. + optional int32 package_version = 2; + // Last Android id generated when Android side backups data. + optional int64 last_backup_android_id = 3; + // Last time internal value that Android side backups data. + optional int64 last_backup_time = 4; +} diff --git a/schema/protobuf/sync_pb/autofill_offer_specifics.proto b/schema/protobuf/sync_pb/autofill_offer_specifics.proto new file mode 100644 index 0000000..457b919 --- /dev/null +++ b/schema/protobuf/sync_pb/autofill_offer_specifics.proto @@ -0,0 +1,110 @@ +// Copyright 2020 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// If you change or add any fields in this file, update proto_visitors.h and +// potentially proto_enum_conversions.{h, cc}. + +syntax = "proto2"; + +option go_package = "./sync_pb"; + +option java_multiple_files = true; +option java_package = "org.chromium.components.sync.protocol"; + +option optimize_for = LITE_RUNTIME; + +package sync_pb; + +// Properties of Autofill wallet offer related objects. + +// Next tag: 11 +message AutofillOfferSpecifics { + // The id for this offer data. Will be used as the client tag. + optional int64 id = 1; + + // The link leading to the offer details page on Gpay app. Will be populated + // on Android only. + optional string offer_details_url = 2; + + // Merchant domain and merchant app package name refers to the merchant this + // offer is applied to. + repeated string merchant_domain = 3; + repeated string merchant_app_package = 4; + + // The expiry of this offer. Will be represented in the form of unix epoch + // time in seconds. Once the offer is expired it will not be shown in the + // client. + optional int64 offer_expiry_date = 5; + + // Proto containing data specific to a card-linked offer. + message CardLinkedOfferData { + reserved 1, 2; + + // The server id of the card to which the offer is linked. + repeated int64 instrument_id = 3; + } + + // Proto containing data specific to a promo code offer. + message PromoCodeOfferData { + // The actual promo code which can be applied at checkout. + optional string promo_code = 1; + } + + // The unique offer data for different offer types. + oneof type_specific_offer_data { + CardLinkedOfferData card_linked_offer_data = 6; + PromoCodeOfferData promo_code_offer_data = 9; + } + + // Strings to be shown in client UI, based on the offer type and details. + message DisplayStrings { + // A message translated in the user's GPay app locale, explaining the value + // of the offer. For example, a promo code offer might display + // "$5 off on shoes, up to $50." + optional string value_prop_text = 1; + + // A message translated in the user's GPay app locale and shown on mobile as + // a link, prompting the user to click it to learn more about the offer. + // Generally, "See details". + optional string see_details_text_mobile = 2; + + // A message translated in the user's GPay app locale and shown on desktop + // (not as a link), informing the user that exclusions and restrictions may + // apply to the value prop text. Generally, "Terms apply." + optional string see_details_text_desktop = 3; + + // A message translated in the user's GPay app locale and shown on mobile, + // instructing them on how to redeem the offer. For example, a promo code + // offer might display "Tap the promo code field at checkout to autofill + // it." + optional string usage_instructions_text_mobile = 4; + + // A message translated in the user's GPay app locale and shown on desktop, + // instructing them on how to redeem the offer. For example, a promo code + // offer might display "Click the promo code field at checkout to autofill + // it." + optional string usage_instructions_text_desktop = 5; + } + optional DisplayStrings display_strings = 10; + + // This value will be shown in the offer text template as "XXX% cashback". + // Percentage has a range of (0, 100]. + message PercentageReward { + // The string contains a number and a percent sign. + optional string percentage = 1; + } + + // This value will be shown in the offer text template as "XXX$ off". + message FixedAmountReward { + // The string contains a number and a currency sign. + optional string amount = 1; + } + + // The reward type of the offer. Will be used to generate the display text in + // the UI. Each type has its own client side text template. + oneof reward_type { + PercentageReward percentage_reward = 7; + FixedAmountReward fixed_amount_reward = 8; + } +} diff --git a/schema/protobuf/sync_pb/autofill_specifics.proto b/schema/protobuf/sync_pb/autofill_specifics.proto new file mode 100644 index 0000000..6e4a969 --- /dev/null +++ b/schema/protobuf/sync_pb/autofill_specifics.proto @@ -0,0 +1,665 @@ +// Copyright 2012 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Sync protocol datatype extension for autofill. + +// If you change or add any fields in this file, update proto_visitors.h and +// potentially proto_enum_conversions.{h, cc}. + +syntax = "proto2"; + +option go_package = "./sync_pb"; + +option java_multiple_files = true; +option java_package = "org.chromium.components.sync.protocol"; + +option optimize_for = LITE_RUNTIME; + +package sync_pb; + +// Properties of autofill sync objects. + +// An AutofillProfile. +message AutofillProfileSpecifics { + // Represents the validation status of value stored in the AutofillProfile. + enum VerificationStatus { + // No verification status assigned. + VERIFICATION_STATUS_UNSPECIFIED = 0; + // The value token was parsed from a parent token. + // For example, the first name was derived by splitting a full name into + // its components. + PARSED = 1; + // Value was built from its subcomponents. + // For example, the full name was built from the first, middle and last + // name. + FORMATTED = 2; + // The value was observed in a form transmission. + // For example, the user filled a form that contained at NAME_FULL field. + // The value of NAME_FULL will be stored as OBSERVED. + OBSERVED = 3; + // The user used the autofill settings to verify and store this token. + // This is currently only applicable to the full name, since users cannot + // edit individual components of their name. + USER_VERIFIED = 4; + // The token was parsed remotely. + SERVER_PARSED = 5; + } + + optional string guid = 15; + // Starting from M115, Autofill ignores the origin and doesn't distinguish + // between verified (meaning `deprecated_origin == kSettingsOrigin`) and + // unverified profiles anymore. However, clients prior to this milestone only + // accept updates to verified profiles through Sync if the remote profile is + // verified as well. For this reason, M115 clients and above always set the + // origin to kSettingsOrigin. + // TODO(crbug.com/1441905): Remove in a few milestones. + optional string deprecated_origin = 16; + optional int64 use_count = 22; + + // The time_t value of the last time this profile was used. This + // value makes sense wrt base::Time::To/FromTimeT, which measures + // from the Windows epoch. + optional int64 use_date = 23; + + // A user chosen profile label that is used to identify the profile. + // The value of the label can be freely chosen by the user. Two possible label + // values are '$HOME$' or '$WORK$' which have a special meaning. + optional string profile_label = 62; + + // Contact info name fields. + repeated string name_first = 2; + repeated string name_middle = 3; + repeated string name_last = 4; + // Sometimes the last name is composed of two names as it is common for + // Hispanic/Latinx names. In the unstructured representation of the last name, + // there may be even a conjunction between the first and the second last + // name. For example, the more-complete version of Pablo Picasso's surname is + // "Ruiz y Picasso" containing a first last name, a conjunction (the y) and a + // second last name. + repeated string name_last_first = 27; + repeated string name_last_conjunction = 28; + repeated string name_last_second = 29; + repeated string name_full = 21; + + reserved 60; + reserved "name_full_with_honorific"; + + // Validation status records for name fields. + reserved 30; + reserved "name_honorific_status"; + repeated VerificationStatus name_first_status = 31; + repeated VerificationStatus name_middle_status = 32; + repeated VerificationStatus name_last_status = 33; + repeated VerificationStatus name_last_first_status = 34; + repeated VerificationStatus name_last_conjunction_status = 35; + repeated VerificationStatus name_last_second_status = 36; + repeated VerificationStatus name_full_status = 37; + reserved 61; + reserved "name_full_with_honorific_status"; + + // Contact info additional fields. + repeated string email_address = 5; + optional string company_name = 6; + + // Address field. + // The address_home_line1/2 fields are deprecated and + // address_home_street_address should be used instead by + // joining address_home_line1/2 with a newline ("\n"). + // Full deprecation can not be achieved before all sync profiles have been + // updated with a M86+ client. + // TODO(crbug/1111740): Remove usages of address_home_line1/2 and mark field + // as deprecated. + optional string address_home_line1 = 7; + optional string address_home_line2 = 8; + optional string address_home_city = 9; + optional string address_home_state = 10; + optional string address_home_zip = 11; + optional string address_home_country = 12; + optional string address_home_admin_level_2 = 71; + + // Additional address fields for i18n. + optional string address_home_street_address = 17; + optional string address_home_sorting_code = 18; + optional string address_home_dependent_locality = 19; + optional string address_home_language_code = 20; + optional string address_home_thoroughfare_name = 38; + optional string address_home_thoroughfare_number = 39; + optional string address_home_street_location = 73; + optional string address_home_subpremise_name = 42; + // All the information related to the apartment. Normally a combination of the + // apartment type (address_home_apt_type) and number (address_home_apt_num). + // E.g. "Apt 5". + optional string address_home_apt = 85; + // The raw number (or identifier) of an apartment (e.g. "5") but without a + // prefix. The value "apt 5" would correspond to the address_home_apt. + optional string address_home_apt_num = 56; + // Information describing the type of apartment (e.g. Apt, Apartamento, Sala, + // Departamento). + optional string address_home_apt_type = 87; + optional string address_home_floor = 57; + optional string address_home_landmark = 67; + // The type indicates that the address is at the intersection between two + // streets. This is a common way of writing addresses in Mexico. + optional string address_home_between_streets = 69; + // The meaning of the field is similar to address_home_between_streets. The + // type should be used for "Entre calle 1" in MX addresses which also + // contain the "Entre calle 2" field. + optional string address_home_between_streets_1 = 77; + // The meaning of the field is similar to address_home_between_streets. The + // type should be used for "Entre calle 2" in MX addresses which also + // contain the "Entre calle 1" field. + optional string address_home_between_streets_2 = 79; + optional string address_home_overflow = 75; + // Combination of types address_home_between_streets or address_home_landmark. + // Note that some address forms require the combination of both in a single + // field as opposed to each one separately. + optional string address_home_between_streets_or_landmark = 81; + // Combination of types address_home_overflow and address_home_landmark. + // Note that some address forms require the combination of both in a single + // field as opposed to each one separately. + optional string address_home_overflow_and_landmark = 83; + // Combination of types address_home_street_location and + // address_home_dependent_locality. Note that some address forms require the + // combination of both in a single field as opposed to each one separately. + optional string address_home_street_location_and_locality = 89; + + // Validation status records for address fields. + optional VerificationStatus address_home_city_status = 43; + optional VerificationStatus address_home_state_status = 44; + optional VerificationStatus address_home_zip_status = 45; + optional VerificationStatus address_home_country_status = 46; + optional VerificationStatus address_home_landmark_status = 68; + optional VerificationStatus address_home_between_streets_status = 70; + optional VerificationStatus address_home_between_streets_1_status = 78; + optional VerificationStatus address_home_between_streets_2_status = 80; + optional VerificationStatus address_home_admin_level_2_status = 72; + optional VerificationStatus address_home_overflow_status = 76; + optional VerificationStatus address_home_between_streets_or_landmark_status = + 82; + optional VerificationStatus address_home_overflow_and_landmark_status = 84; + optional VerificationStatus address_home_street_location_and_locality_status = + 90; + optional VerificationStatus address_home_street_address_status = 47; + optional VerificationStatus address_home_sorting_code_status = 48; + optional VerificationStatus address_home_dependent_locality_status = 49; + optional VerificationStatus address_home_language_code_status = 50; + optional VerificationStatus address_home_thoroughfare_name_status = 51; + optional VerificationStatus address_home_thoroughfare_number_status = 52; + optional VerificationStatus address_home_street_location_status = 74; + optional VerificationStatus address_home_subpremise_name_status = 55; + optional VerificationStatus address_home_apt_status = 86; + optional VerificationStatus address_home_apt_num_status = 58; + optional VerificationStatus address_home_apt_type_status = 88; + optional VerificationStatus address_home_floor_status = 59; + + // Phone. + repeated string phone_home_whole_number = 13; + + reserved 63; + reserved "disallow_settings_visible_updates"; + + // Removed in M123. + reserved 64; + reserved "birthdate_day"; + reserved 65; + reserved "birthdate_month"; + reserved 66; + reserved "birthdate_year"; + + // Deprecated. + optional string deprecated_label = 1 [deprecated = true]; + optional string phone_fax_whole_number = 14 [deprecated = true]; + // The following validity-related fields have only been used in combination + // with an experimental features that are disabled for all clients and have + // been removed in M100. + optional int64 validity_state_bitfield = 24 [deprecated = true]; + optional bool is_client_validity_states_updated = 25 [deprecated = true]; + // Removed in M118. + reserved 40; + reserved "address_home_dependent_thoroughfare_name"; + reserved 41; + reserved "address_home_premise_name"; + reserved 53; + reserved "address_home_dependent_thoroughfare_name_status"; + reserved 54; + reserved "address_home_premise_name_status"; + // Removed in M122. + reserved 26; + reserved "name_honorific"; +} + +message AutofillSpecifics { + // If any of these 3 fields are present, then all 3 should be, and it implies + // that this entity represents a classic autofill object. In this case, + // none of the autofill++ objects below should be present. + optional string name = 1; + optional string value = 2; + repeated int64 usage_timestamp = 3; + + // An autofill++ profile object. If present, indicates this entity + // represents an AutofillProfile exclusively, and no other fields (such as + // name/value or credit_card) should be present. + optional AutofillProfileSpecifics profile = 4; + + reserved 5; + reserved "encrypted_credit_card"; + reserved 6; + reserved "credit_card"; +} + +// TODO(crbug.com/1020740): Deprecated, remove this once dependent change is +// done. Use WalletCreditCardCloudTokenData instead. +message CloudTokenData { + // Last 4-5 digits of the Cloud Primary Account Number (CPAN). + optional string suffix = 1; + + // CPAN Month number 1-12. + optional int32 exp_month = 2; + + // CPAN Four-digit year (e.g. 2017). + optional int32 exp_year = 3; + + // URL of the card art to be displayed for CPAN. + optional string art_fife_url = 4; + + // Opaque identifier for the cloud token associated with the payment + // instrument. + optional string instrument_token = 5; +} + +// Next id: 8 +message CardBenefit { + // The unique identifier of the benefit. Generated originally in Chrome Sync + // server. + optional string benefit_id = 7; + + // The benefit description (Engligh only currently) to be shown in the UI. + optional string benefit_description = 1; + + // When the benefit should be displayed, in UTC time. + optional int64 start_time_unix_epoch_milliseconds = 2; + optional int64 end_time_unix_epoch_milliseconds = 3; + + // Proto containing data specific to a flat rate benefit. Empty as flat rate + // benefits don't have unique fields. The actual benefit (e.g. "2% cash back") + // is already included in the `benefit_description`. + message FlatRateBenefit {} + + // For category benefits, represents the category of purchases that the + // benefit can be applied to. + enum CategoryBenefitType { + CATEGORY_BENEFIT_TYPE_UNKNOWN = 0; + SUBSCRIPTION = 1; + FLIGHTS = 2; + DINING = 3; + ENTERTAINMENT = 4; + STREAMING = 5; + GROCERY_STORES = 6; + } + + // Proto containing data specific to a category benefit. + message CategoryBenefit { + // The type of category purchases the benefit is eligible on. + optional CategoryBenefitType category_benefit_type = 1; + } + + // Proto containing data specific to a merchant benefit. + message MerchantBenefit { + // The merchant domain that the benefit is eligible on. + // Example: https://www.acme.com + repeated string merchant_domain = 1; + } + + // Proto data representing the actual data of the credit card benefit, + // depending on the benefit type. + oneof DomainSpecificBenefit { + FlatRateBenefit flat_rate_benefit = 4; + CategoryBenefit category_benefit = 5; + MerchantBenefit merchant_benefit = 6; + } +} + +message CardIssuer { + enum Issuer { + ISSUER_UNKNOWN = 0; + // Card where the issuer is Google. + GOOGLE = 1; + // Card where the issuer is external. + EXTERNAL_ISSUER = 2; + } + optional Issuer issuer = 1; + + // Uniquely identifies the issuer of the card. This field is required when + // Issuer is EXTERNAL_ISSUER. + // Example: capitalone, amex. + optional string issuer_id = 2; +} + +message WalletMaskedCreditCard { + reserved 9, 14; + reserved "card_class"; + + enum WalletCardStatus { + VALID = 0; + EXPIRED = 1; + } + + enum WalletCardType { + UNKNOWN = 0; + AMEX = 1; + DISCOVER = 2; + JCB = 3; + MAESTRO = 4; + MASTER_CARD = 5; + SOLO = 6; + SWITCH = 7; + VISA = 8; + UNIONPAY = 9; + ELO = 10; + } + + enum VirtualCardEnrollmentState { + UNSPECIFIED = 0; + UNENROLLED = 1 [deprecated = true]; + ENROLLED = 2; + UNENROLLED_AND_NOT_ELIGIBLE = 3; + UNENROLLED_AND_ELIGIBLE = 4; + } + + enum VirtualCardEnrollmentType { + TYPE_UNSPECIFIED = 0; + ISSUER = 1; + NETWORK = 2; + } + + // Server-generated unique ID string. This is opaque to the client. + // This is the legacy version of |instrument_id|. + optional string id = 1; + + // What the server thinks of this card. + optional WalletCardStatus status = 2; + + optional string name_on_card = 3; + + optional WalletCardType type = 4; + + // Last 4 digits of the credit card number. + optional string last_four = 5; + + // Month number 1-12. + optional int32 exp_month = 6; + + // Four-digit year (e.g. 2017). + optional int32 exp_year = 7; + + // The WalletPostalAddress.id of the billing address. + optional string billing_address_id = 8; + + // Issuing Bank name which is internationalized (e.g. "Chase", "工商银行") + optional string bank_name = 10; + + // TODO(crbug.com/1020740): Deprecated, remove this once dependent change is + // done. + // Use WalletCreditCardCloudTokenData instead. This field will be set if + // a cloud token is available for the instrument. + optional CloudTokenData cloud_token_data = 11; + + // The card's nickname, if it exists. + optional string nickname = 12; + + // Issuer of the card. + optional CardIssuer card_issuer = 13; + + // Server-generated unique ID. This is opaque to the client. + // |id| is the legacy version of this. + optional int64 instrument_id = 15; + + // The state of virtual card enrollment. + optional VirtualCardEnrollmentState virtual_card_enrollment_state = 16; + + // The URL for the client to fetch the card art image. + optional string card_art_url = 17; + + // The product description for the card. Used to be shown in the UI. + optional string product_description = 18; + + // The type of virtual card enrollment. kTypeUnspecified indicates that the + // card is unenrolled. + optional VirtualCardEnrollmentType virtual_card_enrollment_type = 19; + + // The benefits (e.g. points or discounts) associated with purchases made + // with the card. + repeated CardBenefit card_benefit = 20; + + // Separate link from the card issuer which provides additional context or + // terms and conditions regarding the credit card product and its benefits. + optional string product_terms_url = 21; +} + +// Unused by the client since M121. +// TODO(crbug.com/1457187): Some server-side code still relies on this message. +// To keep the protos in sync, it is kept until that code is cleaned up. +// Different than an AutofillProfile because this represents some known address +// on the server that is pulled down rather than synced between Chromes. +message WalletPostalAddress { + optional string id = 1; + + optional string recipient_name = 12; + optional string company_name = 2; + + // This is the street address, of which there may be multiple lines. This + // corresponds to "address_home_line[1|2] in the AutofillProfileSpecifics + // message above. In some locales there may be more than two lines. + repeated string street_address = 3; + + // Also known as "administrative area". This is normally the state or + // province in most countries. + optional string address_1 = 4; + + // Also known as "locality". In the US this is the city. + optional string address_2 = 5; + + // A sub-classification beneath the city, e.g. an inner-city district or + // suburb. Also known as "dependent_locality" + optional string address_3 = 6; + + // Used in certain countries. Also known as "sub_dependent_locality". + optional string address_4 = 7; + + optional string postal_code = 8; + + // Similar to the zipcode column, but used for businesses or organizations + // that might not be geographically contiguous. The canonical example is + // CEDEX in France. + optional string sorting_code = 9; + + optional string country_code = 10; + optional string language_code = 11; + + // Phone number. The format is unspecified and will be explicitly ignored. + optional string phone_number = 13; +} + +// Contains information about a Payments Customer. +message PaymentsCustomerData { + // The billable customer ID associated with the account. + optional string id = 1; +} + +// Contains information about the cloud token data of server credit cards. +message WalletCreditCardCloudTokenData { + // Server-generated ID string for the card this cloud token data is related + // to. This should match the id in WalletMaskedCreditCard for to fetch the + // corresponding actual card data. Note this is not unique across all cloud + // token data, which means one card can have multiple sets of cloud token data + // with the same masked_card_id. + optional string masked_card_id = 1; + + // Last 4-5 digits of the Cloud Primary Account Number (CPAN). + optional string suffix = 2; + + // CPAN Month number 1-12. + optional int32 exp_month = 3; + + // CPAN Four-digit year (e.g. 2017). + optional int32 exp_year = 4; + + // URL of the card art to be displayed for CPAN. + optional string art_fife_url = 5; + + // Opaque identifier for the cloud token. + optional string instrument_token = 6; +} + +// Contains information of payment instruments that can be used by the user. +message PaymentInstrument { + // Opaque identifier for the account stored in Payments Platform. + // This will be used to initiate the payment. + optional int64 instrument_id = 1; + + // Supported payment infrastructures (rail) that allow users to send money + // between the payer and the payee. https://en.wikipedia.org/wiki/Payment_rail + enum SupportedRail { + SUPPORTED_RAIL_UNKNOWN = 0; + // Payment rails for Brazil Open Banking. + PIX = 1; + // International Bank Account Numbers. + IBAN = 2; + } + // The supported rails for which a payment can be made for the given account. + // For example, Pix is the open-banking rail in Brazil, UPI is the + // open-banking rail in India. + repeated SupportedRail supported_rails = 2; + + // The URL for the image to be displayed when showing the account to the + // user. + optional string display_icon_url = 3; + + // Nickname for the instrument. + optional string nickname = 4; + + // The backing source for the applicable rails. + oneof instrument_details { + BankAccountDetails bank_account = 5; + WalletMaskedIban iban = 6; + } +} + +// Contains information of server IBAN (International Bank Account Number). +message WalletMaskedIban { + // Opaque identifier for the account stored in Payments Platform. + optional string instrument_id = 1; + + // Prefix of the full IBAN value, if available. + optional string prefix = 2; + + // Suffix of the full IBAN value, if available. + optional string suffix = 3; + + // Length of the full IBAN value, if available. + optional int32 length = 4; + + // Nickname for the IBAN, if available. + optional string nickname = 5; +} + +// Details of a bank account required to show it in the payment instrument +// selector. +message BankAccountDetails { + // The name of the bank where the user has an account. + optional string bank_name = 1; + + // The last four digits of the account number to help the user identify their + // account. + optional string account_number_suffix = 2; + + enum AccountType { + ACCOUNT_TYPE_UNSPECIFIED = 0; + CHECKING = 1; + SAVINGS = 2; + CURRENT = 3; + SALARY = 4; + TRANSACTING_ACCOUNT = 5; + } + // The type of bank account. + optional AccountType account_type = 3; +} + +message AutofillWalletSpecifics { + enum WalletInfoType { + UNKNOWN = 0; + MASKED_CREDIT_CARD = 1; + // POSTAL_ADDRESS is unused by the client since M121. + POSTAL_ADDRESS = 2; + CUSTOMER_DATA = 3; + CREDIT_CARD_CLOUD_TOKEN_DATA = 4; + PAYMENT_INSTRUMENT = 5; + MASKED_IBAN = 6 [deprecated = true]; + } + + optional WalletInfoType type = 1; + + // This field exists if and only if the "type" field equals to + // MASKED_CREDIT_CARD. + optional WalletMaskedCreditCard masked_card = 2; + + // Unused by the client since M121. + // This field exists if and only if the `type` equals POSTAL_ADDRESS. + // TODO(crbug.com/1457187): Some server-side code still relies on this field. + // To keep the protos in sync, it is kept until that code is cleaned up. + optional WalletPostalAddress address = 3; + + // This field exists if and only if the "type" field equals to CUSTOMER_DATA. + optional PaymentsCustomerData customer_data = 4; + + // This field exists if and only if the "type" field equals to + // CREDIT_CARD_CLOUD_TOKEN_DATA. + optional WalletCreditCardCloudTokenData cloud_token_data = 5; + + // This field exists if and only if the "type" field equals to + // PAYMENT_INSTRUMENT. + optional PaymentInstrument payment_instrument = 6; + + // This field exists if and only if the `type` field equals to + // MASKED_IBAN. + optional WalletMaskedIban masked_iban = 7 [deprecated = true]; +} + +// Wallet card usage information that can be synced. +message WalletMetadataSpecifics { + enum Type { + UNKNOWN = 0; + CARD = 1; + // Unused by the client since M121. + // TODO(crbug.com/1457187): Some server-side code still relies on this. + // To keep the protos in sync, it is kept until that code is cleaned up. + ADDRESS = 2; + IBAN = 3; + } + + // The type of the Wallet metadata. + optional Type type = 1; + + // Base64 encoding of the unique ID string of the corresponding + // AutofillMetadata. + // For Wallet cards, this value is WalletMaskedCreditCard::id. + // For Wallet IBANs, this value is WalletMaskedIban::instrument_id. + optional string id = 2; + + // The number of times that this Wallet card or address was used. + optional int64 use_count = 3; + + // The last use date of this Wallet card or address. Measured in microseconds + // since the Windows epoch (1601). + optional int64 use_date = 4; + + // The id of the profile/address that represents the billing address of this + // Wallet card. + optional string card_billing_address_id = 5; + + // Unused by the client since M121. + // TODO(crbug.com/1457187): Some server-side code still relies on this field. + // To keep the protos in sync, it is kept until that code is cleaned up. + optional bool address_has_converted = 6; +} diff --git a/schema/protobuf/sync_pb/autofill_wallet_credential_specifics.proto b/schema/protobuf/sync_pb/autofill_wallet_credential_specifics.proto new file mode 100644 index 0000000..cf0a183 --- /dev/null +++ b/schema/protobuf/sync_pb/autofill_wallet_credential_specifics.proto @@ -0,0 +1,29 @@ +// Copyright 2023 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// If you change or add any fields in this file, update proto_visitors.h and +// potentially proto_enum_conversions.{h, cc}. + +syntax = "proto2"; + +option go_package = "./sync_pb"; + +option java_multiple_files = true; +option java_package = "org.chromium.components.sync.protocol"; + +option optimize_for = LITE_RUNTIME; + +package sync_pb; + +// Autofill wallet data which stores the relevant card credential data. +message AutofillWalletCredentialSpecifics { + // A server-generated unique ID for the instrument/card. + optional string instrument_id = 1; + + // A 3 or 4 digit card verification code. + optional string cvc = 2; + + // The timestamp of the last update. Used to determine data freshness. + optional int64 last_updated_time_unix_epoch_millis = 3; +} diff --git a/schema/protobuf/sync_pb/autofill_wallet_usage_specifics.proto b/schema/protobuf/sync_pb/autofill_wallet_usage_specifics.proto new file mode 100644 index 0000000..151fe0f --- /dev/null +++ b/schema/protobuf/sync_pb/autofill_wallet_usage_specifics.proto @@ -0,0 +1,45 @@ +// Copyright 2022 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// If you change or add any fields in this file, update proto_visitors.h and +// potentially proto_enum_conversions.{h, cc}. + +syntax = "proto2"; + +option go_package = "./sync_pb"; + +option java_multiple_files = true; +option java_package = "org.chromium.components.sync.protocol"; + +option optimize_for = LITE_RUNTIME; + +package sync_pb; + +// Autofill usage data related objects which contains usage data of a payment +// method related to a specific merchant. + +message AutofillWalletUsageSpecifics { + // A unique ID identifying this item. Used as the client tag. + optional string guid = 1; + + // The type of usage data this entity is associated with. + oneof usage_data_type { + VirtualCardUsageData virtual_card_usage_data = 2; + } + + message VirtualCardUsageData { + // The instrument id of the actual card that the virtual card is related to. + optional int64 instrument_id = 1; + + // The last four of the virtual card number. This is tied to the usage + // data because the virtual card number may vary depending on merchants. + optional string virtual_card_last_four = 2; + + // The url of the merchant where the virtual card is used. + optional string merchant_url = 3; + + // The merchant the usage data is related to on the Android platform. + optional string merchant_app_package = 4; + } +} diff --git a/schema/protobuf/sync_pb/bookmark_model_metadata.proto b/schema/protobuf/sync_pb/bookmark_model_metadata.proto new file mode 100644 index 0000000..8bf821d --- /dev/null +++ b/schema/protobuf/sync_pb/bookmark_model_metadata.proto @@ -0,0 +1,81 @@ +// Copyright 2018 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +syntax = "proto2"; + +option go_package = "./sync_pb"; + +option java_multiple_files = true; +option java_package = "org.chromium.components.sync.protocol"; + +option optimize_for = LITE_RUNTIME; + +package sync_pb; + +import "model_type_state.proto"; +import "entity_metadata.proto"; + +// Corresponds to a single bookmark id/metadata pair. +message BookmarkMetadata { + // Bookmark local id. + optional int64 id = 1; + + // Bookmarks sync metadata. + optional EntityMetadata metadata = 2; +} + +// Sync proto to carry the sync metadata for the bookmarks model. It is used for +// persisting and loading sync metadata from disk. +message BookmarkModelMetadata { + // Bookmark global metadata. + optional ModelTypeState model_type_state = 1; + + // A set of all bookmarks metadata. + repeated BookmarkMetadata bookmarks_metadata = 2; + + reserved 3; + + reserved 4; + + reserved 5; + + // Indicates whether the reupload of bookmarks has been triggered such that + // they include fields like |type|, |unique_position| and |parent_guid|, which + // means that their sequence number has been increased (independently of + // whether the commit has succeeded or even started). + // TODO(crbug.com/1232951): remove this code when most of bookmarks are + // reuploaded. + optional bool bookmarks_hierarchy_fields_reuploaded = 6; + + // Number of remote updates that were ignored because the parent folder could + // not be determined since sync (bookmark sync) started (since initial sync, + // including initial sync itself). Note that this excludes updates + // representing changes (moves) to existing/tracked bookmarks (i.e. the parent + // folder used to be known, but the new one specified in the update isn't). + // + // Only a minority of users should have a non-zero value, due to a) corrupt + // data, reasons unknown; or b) permanent folders that were unsupported at the + // time the update was received (either for the permanent folder itself or for + // descendants). The absence of this field should be interpreted as 'unknown', + // which roughly means the counter wasn't supported by the browser -M77 or + // below- at the time sync was enabled (it also means, it will remain + // 'unknown' until initial sync is exercised, e.g. sync disabled and + // reenabled). + optional int64 num_ignored_updates_due_to_missing_parent = 7; + + // See field above. Among such ignored updates, this field tracks which was + // the highest server version. This may be useful -in the future- to get a + // sense of "time" (or, since versions are opaque to the client, at least a + // notion of ordering with respect to other updates). The absence of this + // field should be interpreted as 'unknown' and does not distinguish the + // case between a) no updates ignored; and b) field wasn't supported at the + // time the last update was ignored. To distinguish between these two, the + // field above can be used. + optional int64 max_version_among_ignored_updates_due_to_missing_parent = 8; + + // Indicates whether the count of remote updates during the latest initial + // merge exceeded the bookmark limit. This field is mutually exclusive to all + // the other fields and is managed completely by the processor. + optional bool last_initial_merge_remote_updates_exceeded_limit = 9; +} diff --git a/schema/protobuf/sync_pb/bookmark_specifics.proto b/schema/protobuf/sync_pb/bookmark_specifics.proto new file mode 100644 index 0000000..6ebfe62 --- /dev/null +++ b/schema/protobuf/sync_pb/bookmark_specifics.proto @@ -0,0 +1,97 @@ +// Copyright 2012 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Sync protocol datatype extension for bookmarks. + +// If you change or add any fields in this file, update proto_visitors.h and +// potentially proto_enum_conversions.{h, cc}. + +syntax = "proto2"; + +option go_package = "./sync_pb"; + +option java_multiple_files = true; +option java_package = "org.chromium.components.sync.protocol"; + +option optimize_for = LITE_RUNTIME; + +package sync_pb; + +import "unique_position.proto"; + +// Corresponds to a single meta info key/value pair for a bookmark node. +message MetaInfo { + optional string key = 1; + optional string value = 2; +} + +// Properties of bookmark sync objects. +message BookmarkSpecifics { + // URL of the bookmarked page (unset for folders). + optional string url = 1; + // PNG-encoded content of the favicon image (in practice 16x16, as determined + // by |kFaviconSize|). Empty if the bookmark has no favicon (which includes + // bookmark folders). + optional bytes favicon = 2; + // Contains legacy title which is truncated and may contain escaped symbols. + optional string legacy_canonicalized_title = 3; + // Corresponds to BookmarkNode::date_added() represented as microseconds since + // the Windows epoch. + optional int64 creation_time_us = 4; + // The URL of the favicon image encoded in field |favicon|. Note that there + // are various cases where this URL may be missing (field unset or empty) even + // if the |favicon| field (image content) is populated: + // 1. WebUI pages such as "chrome://bookmarks/" are missing a favicon URL but + // they have a favicon. + // 2. Data generated by ancient clients (prior to M25) may not contain the + // favicon URL. + // 3. If the favicon URL is too large (determined by |kMaxFaviconUrlSize|) it + // may be omitted by clients to avoid running into the max-entity-size + // limit. Most notably, this includes URLs prefixed with the data: scheme + // that may encode the image content itself in the URL. + optional string icon_url = 5; + repeated MetaInfo meta_info = 6; + reserved 7; + reserved 8; + reserved 9; + // Introduced in M81, it represents a globally unique and immutable ID. + // + // If present, it must be the same as originator_client_item_id in lowercase, + // unless originator client item ID is not a valid GUID. In such cases (which + // is the case for bookmarks created before 2015), this GUID must match the + // value inferred from the combination of originator cache GUID and + // originator client item ID, see InferGuidForLegacyBookmark(). + // + // If not present, the value can be safely inferred using the very same + // methods listed above. + optional string guid = 10; + // Contains full title as is. |legacy_canonicalized_title| is a prefix of + // |full_title| with escaped symbols. + optional string full_title = 11; + reserved 12; + reserved 13; + // Introduced in M94, represents the GUID (field |guid|) of the parent. + optional string parent_guid = 14; + + // Introduced in M94, determines whether this entity represents a bookmark + // folder. This field is redundant to the similar field in SyncEntity. If this + // field in specifics is set, it takes precedence over the one in SyncEntity. + enum Type { + // |UNSPECIFIED| is relevant only for the case where the field is not set. + // M94 and above should not use this value. + UNSPECIFIED = 0; + URL = 1; + FOLDER = 2; + } + optional Type type = 15; + + // Introduced in M94, determines ordering among siblings. This field is + // redundant to the similar field in SyncEntity. If this field in specifics is + // set, it takes precedence over the one in SyncEntity. + optional UniquePosition unique_position = 16; + + // Introduced in M106, corresponds to BookmarkNode::date_last_used() + // represented as microseconds since the Windows epoch. + optional int64 last_used_time_us = 17; +} diff --git a/schema/protobuf/sync_pb/brave_device_info_specifics.proto b/schema/protobuf/sync_pb/brave_device_info_specifics.proto new file mode 100644 index 0000000..abdf7dd --- /dev/null +++ b/schema/protobuf/sync_pb/brave_device_info_specifics.proto @@ -0,0 +1,19 @@ +// Copyright (c) 2020 The Brave Authors. All rights reserved. +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this file, +// You can obtain one at http://mozilla.org/MPL/2.0/. + +syntax = "proto2"; + +option go_package = "./sync_pb"; + +option java_multiple_files = true; +option java_package = "org.chromium.components.sync.protocol"; + +option optimize_for = LITE_RUNTIME; + +package sync_pb; + +message BraveSpecificFields { + optional bool is_self_delete_supported = 1; +} diff --git a/schema/protobuf/sync_pb/client_commands.proto b/schema/protobuf/sync_pb/client_commands.proto new file mode 100644 index 0000000..7ed671f --- /dev/null +++ b/schema/protobuf/sync_pb/client_commands.proto @@ -0,0 +1,57 @@ +// Copyright 2012 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Sync protocol for communication between sync client and server. + +// If you change or add any fields in this file, update proto_visitors.h and +// potentially proto_enum_conversions.{h, cc}. + +syntax = "proto2"; + +option go_package = "./sync_pb"; + +option java_multiple_files = true; +option java_package = "org.chromium.components.sync.protocol"; + +option optimize_for = LITE_RUNTIME; + +package sync_pb; + +message CustomNudgeDelay { + optional int32 datatype_id = 1; // Datatype id. + optional int32 delay_ms = 2; // Delay in milliseconds. +} + +message ClientCommand { + // Time to wait before sending any requests to the server. + optional int32 set_sync_poll_interval = 1; // in seconds + // This has been deprecated since M75. + optional int32 set_sync_long_poll_interval = 2 [deprecated = true]; + + optional int32 max_commit_batch_size = 3; + + // Number of seconds to delay before the throttled client should retry. + optional int32 throttle_delay_seconds = 5; + + // This has been deprecated since M109. + optional int32 client_invalidation_hint_buffer_size = 6 [deprecated = true]; + + // Time to wait before issuing a retry GU. + optional int32 gu_retry_delay_seconds = 7; + + // A dictionary of custom nudge delays. + repeated CustomNudgeDelay custom_nudge_delays = 8; + + // Configuration for commit quota of extension-related data types. + // The maximum count of tokens (=initial at browser startup) and the + // interval for refilling one more token if not at maximum. + optional int32 extension_types_max_tokens = 9; + optional int32 extension_types_refill_interval_seconds = 10; + + // Extended nudge delay for data types with depleted quota. + optional int32 extension_types_depleted_quota_nudge_delay_seconds = 11; + + reserved 4; + reserved "sessions_commit_delay_seconds"; +} diff --git a/schema/protobuf/sync_pb/client_debug_info.proto b/schema/protobuf/sync_pb/client_debug_info.proto new file mode 100644 index 0000000..19794c3 --- /dev/null +++ b/schema/protobuf/sync_pb/client_debug_info.proto @@ -0,0 +1,94 @@ +// Copyright 2012 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Sync protocol for debug info clients can send to the sync server. + +// If you change or add any fields in this file, update proto_visitors.h and +// potentially proto_enum_conversions.{h, cc}. + +syntax = "proto2"; + +option go_package = "./sync_pb"; + +option java_multiple_files = true; +option java_package = "org.chromium.components.sync.protocol"; + +option optimize_for = LITE_RUNTIME; + +package sync_pb; + +import "get_updates_caller_info.proto"; +import "sync_enums.proto"; + +// Per-type hint information. +message TypeHint { + // The data type this hint applied to. + optional int32 data_type_id = 1; + + // Whether or not a valid hint is provided. + optional bool has_valid_hint = 2; +} + +// The additional info here is from the StatusController. They get sent when +// the event SYNC_CYCLE_COMPLETED is sent. +message SyncCycleCompletedEventInfo { + reserved 1; + reserved "syncer_stuck"; + reserved 2; + reserved "num_blocking_conflicts"; + reserved 3; + reserved "num_non_blocking_conflicts"; + + // These new conflict counters replace the ones above. + // TODO(crbug.com/1315573): Deprecated in M103. + optional int32 num_encryption_conflicts = 4 [deprecated = true]; + optional int32 num_hierarchy_conflicts = 5 [deprecated = true]; + optional int32 num_simple_conflicts = 6; // No longer sent since M24. + optional int32 num_server_conflicts = 7; + + // Counts to track the effective usefulness of our GetUpdate requests. + optional int32 num_updates_downloaded = 8; + // TODO(crbug.com/1315573): Deprecated in M103. + optional int32 num_reflected_updates_downloaded = 9 [deprecated = true]; + + // |caller_info| was mostly replaced by |get_updates_origin|; now it only + // contains the |notifications_enabled| flag. + optional GetUpdatesCallerInfo caller_info = 10; + + // Deprecated in M67. + reserved 11; + reserved "source_info"; + + optional SyncEnums.GetUpdatesOrigin get_updates_origin = 12; +} + +message DebugEventInfo { + // Each of the following fields correspond to different kinds of events. as + // a result, only one is set during any single DebugEventInfo. + // A singleton event. See enum definition. + optional SyncEnums.SingletonDebugEventType singleton_event = 1; + // A sync cycle completed. + optional SyncCycleCompletedEventInfo sync_cycle_completed_event_info = 2; + // A datatype triggered a nudge. + optional int32 nudging_datatype = 3; + // A notification triggered a nudge. + repeated int32 datatypes_notified_from_server = 4; + + reserved "datatype_association_stats"; + reserved 5; +} + +message DebugInfo { + repeated DebugEventInfo events = 1; + + // Whether cryptographer is ready to encrypt and decrypt data. + optional bool cryptographer_ready = 2; + + // Cryptographer has pending keys which indicates the correct passphrase + // has not been provided yet. + optional bool cryptographer_has_pending_keys = 3; + + // Indicates client has dropped some events to save bandwidth. + optional bool events_dropped = 4; +} diff --git a/schema/protobuf/sync_pb/collaboration_group_specifics.proto b/schema/protobuf/sync_pb/collaboration_group_specifics.proto new file mode 100644 index 0000000..d748fbb --- /dev/null +++ b/schema/protobuf/sync_pb/collaboration_group_specifics.proto @@ -0,0 +1,29 @@ +// Copyright 2024 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// If you change or add any fields in this file, update proto_visitors.h and +// potentially proto_enum_conversions.{h, cc}. + +syntax = "proto2"; + +option go_package = "./sync_pb"; + +option java_multiple_files = true; +option java_package = "org.chromium.components.sync.protocol"; + +option optimize_for = LITE_RUNTIME; + +package sync_pb; + +// Special sync datatype to notify client about People Group changes. +message CollaborationGroupSpecifics { + // Unique identifier for a collaboration group, also known as `group_id` or + // `group_name`. + optional string collaboration_id = 1; + + // Indicates staleness of the collaboration group, used to determine whether + // client should refresh cached group. Server-side derived from group + // `consistency_token`. + optional int64 last_updated_timestamp_millis_since_unix_epoch = 2; +} diff --git a/schema/protobuf/sync_pb/compare_specifics.proto b/schema/protobuf/sync_pb/compare_specifics.proto new file mode 100644 index 0000000..dbf3beb --- /dev/null +++ b/schema/protobuf/sync_pb/compare_specifics.proto @@ -0,0 +1,42 @@ +// Copyright 2024 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// Sync protocol datatype extension for compare. + +// If you change or add any fields in this file, update proto_visitors.h and +// potentially proto_enum_conversions.{h, cc}. + +syntax = "proto2"; + +option go_package = "./sync_pb"; + +option java_multiple_files = true; +option java_package = "org.chromium.components.sync.protocol"; + +option optimize_for = LITE_RUNTIME; + +package sync_pb; + +// A Compare sync entity, containing sufficient data to enable all data +// acquisition for rendering the Compare experience. +message CompareSpecifics { + // The primary key for local storage. + optional string uuid = 1; + + // Tracks when this entity was created. + optional int64 creation_time_unix_epoch_micros = 2; + + // Tracks when this entity was last modified. + optional int64 update_time_unix_epoch_micros = 3; + + // The name of the comparison group. + optional string name = 4; + + // The list of product URLs that constitute this comparison group. + repeated ComparisonData data = 5; +} + +message ComparisonData { + // The URL of the item in the comparison. + optional string url = 1; +} diff --git a/schema/protobuf/sync_pb/contact_info_specifics.proto b/schema/protobuf/sync_pb/contact_info_specifics.proto new file mode 100644 index 0000000..11f9140 --- /dev/null +++ b/schema/protobuf/sync_pb/contact_info_specifics.proto @@ -0,0 +1,217 @@ +// Copyright 2022 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// If you change or add any fields in this file, update proto_visitors.h and +// potentially proto_enum_conversions.{h, cc}. + +syntax = "proto2"; + +option go_package = "./sync_pb"; + +option java_multiple_files = true; +option java_package = "org.chromium.components.sync.protocol"; + +option optimize_for = LITE_RUNTIME; + +package sync_pb; + +message ContactInfoSpecifics { + // Represents the validation status of a stored value. + enum VerificationStatus { + // No verification status assigned. + VERIFICATION_STATUS_UNSPECIFIED = 0; + // The value token was parsed from a parent token. + // For example, the first name was derived by splitting a full name into + // its components. + PARSED = 1; + // Value was built from its subcomponents. + // For example, the full name was built from the first, middle and last + // name. + FORMATTED = 2; + // The value was observed in a form transmission. + // For example, the user filled a form that contained at NAME_FULL field. + // The value of NAME_FULL will be stored as OBSERVED. + OBSERVED = 3; + // The user used the settings UI to verify and store this token. + // This is currently only applicable to the full name, since users cannot + // edit individual components of their name. + USER_VERIFIED = 4; + // The token was parsed remotely. + SERVER_PARSED = 5; + } + + message Observation { + // An `autofill::ProfileTokenQuality::ObservationType`. Represented as a + // uint32 to retain future enum values (since this is proto2). + // The `ObservationType`'s underlying type is uint8_t, but this is not + // supported by protos. Since the uint32 Proto type uses variable-length + // encoding, uint32 has a similar size as a single element byte[]. + optional uint32 type = 1; + // The `autofill::ProfileTokenQuality::FormSignatureHash` has type uint8_t. + // Like for `type`, this should have the (non-existing) data type uint8. + optional uint32 form_hash = 2; + } + + // Metadata that is attached to every token type. + message TokenMetadata { + optional VerificationStatus status = 1; + repeated Observation observations = 2; + // Stores a hash of the token value that this metadata is associated with. + // This is used by Autofill to detect changes of the token value by external + // integrators. + optional uint32 value_hash = 3; + } + + // A token with a string interpretation of the value. + message StringToken { + optional string value = 1; + optional TokenMetadata metadata = 2; + } + + // A globally unique, immutable UUID represented in lowercase. + optional string guid = 1; + reserved 2; + reserved "source"; + // The number of time this profile has been used. + optional int64 use_count = 3; + + // The last time this profile was used. + optional int64 use_date_unix_epoch_seconds = 4; + + // The last time the profile was modified. + optional int64 date_modified_unix_epoch_seconds = 37; + + // The BCP 47 language code used to format the address for display. + optional string language_code = 38; + + // A user chosen profile label that is used to identify the profile. + // The value of the label can be freely chosen by the user. + optional string profile_label = 5; + + // Tracks the application that initially created the profile. The integer + // represents a value in the server-side enum `BillableService`. A value of + // 70073 represents Chrome (enum value BILLABLE_SERVICE_CHROME_PAYMENTS). + optional int32 initial_creator_id = 39; + // Tracks the application that applied the last modification to the + // non-metadata content of the profile. It represents a value in the same + // `BillableService` enum. + // All StringTokens, and the `profile_label` are considered non-metadata. + optional int32 last_modifier_id = 40; + + // Contact info name fields. + optional StringToken name_first = 7; + optional StringToken name_middle = 8; + optional StringToken name_last = 9; + // Sometimes the last name is composed of two names as it is common for + // Hispanic/Latinx names. In the unstructured representation of the last name, + // there may be even a conjunction between the first and the second last + // name. For example, the more-complete version of Pablo Picasso's surname is + // "Ruiz y Picasso" containing a first last name, a conjunction (the y) and a + // second last name. + optional StringToken name_last_first = 10; + optional StringToken name_last_conjunction = 11; + optional StringToken name_last_second = 12; + optional StringToken name_full = 13; + + reserved 14; + reserved "name_full_with_honorific"; + + // Contact info additional fields. + optional StringToken email_address = 15; + optional StringToken company_name = 16; + + // Address fields: These are user-provided values with no particular + // guarantees about their format. + optional StringToken address_city = 17; + optional StringToken address_state = 18; + optional StringToken address_zip = 19; + optional StringToken address_country = 20; + optional StringToken address_admin_level_2 = 43; + + // Additional address fields for i18n. + // Includes all of the lines of a street address, including newlines, e.g. + // 123 Main Street, + // Apt. #42 + optional StringToken address_street_address = 21; + // A sorting code is similar to a postal code. However, whereas a postal code + // normally refers to a single geographical location, a sorting code often + // does not. Instead, a sorting code is assigned to an organization, which + // might be geographically distributed. The most prominent example of a + // sorting code system is CEDEX in France. + optional StringToken address_sorting_code = 22; + // A dependent locality is a subunit of a locality, where a "locality" is + // roughly equivalent to a city. Examples of dependent localities include + // inner-city districts and suburbs. + optional StringToken address_dependent_locality = 23; + reserved 24; + reserved "address_language_code"; + // The street name of the address, without a house number. + optional StringToken address_thoroughfare_name = 25; + // The house number, which may be alphanumeric. + optional StringToken address_thoroughfare_number = 26; + // Deprecated in M118. + reserved 27; + reserved "address_dependent_thoroughfare_name"; + reserved 28; + reserved "address_thoroughfare_and_dependent_thoroughfare_name"; + reserved 29; + reserved "address_premise_name"; + // Contains the floor, staircase or apartment number within a building. + optional StringToken address_subpremise_name = 30; + // All the information related to the apartment. Normally a combination of the + // apartment type (address_apt_type) and number (address_apt_num). + // E.g. "Apt 5". + optional StringToken address_apt = 50; + // The apartment number within a building. + optional StringToken address_apt_num = 31; + // Information describing the type of apartment (e.g. Apt, Apartamento, Sala, + // Departamento). + optional StringToken address_apt_type = 51; + // The floor number within a building. + optional StringToken address_floor = 32; + // Contains both the street and house number. + optional StringToken address_street_location = 44; + + optional StringToken address_landmark = 41; + optional StringToken address_overflow = 45; + // Indicates that the address is at the intersection between two streets. + // It is normally a combination of between_streets_1 and _2. This is a common + // way of writing addresses in Mexico. + optional StringToken address_between_streets = 42; + // The meaning of the field is similar to address_between_streets. The + // type should be used for "Entre calle 1" in MX addresses which also + // contain the "Entre calle 2" field. + optional StringToken address_between_streets_1 = 46; + // The meaning of the field is similar to address_between_streets. The + // type should be used for "Entre calle 2" in MX addresses which also + // contain the "Entre calle 1" field. + optional StringToken address_between_streets_2 = 47; + // Combination of types address_between_streets or address_landmark. Note that + // some address forms require the combination of both in a single field as + // opposed to each one separately. + optional StringToken address_between_streets_or_landmark = 48; + // Combination of types address_overflow and address_landmark. Note that some + // address forms require the combination of both in a single field as opposed + // to each one separately. + optional StringToken address_overflow_and_landmark = 49; + // Combination of types address_street_location and + // address_dependent_locality. Note that some address forms require the + // combination of both in a single field as opposed to each one separately. + optional StringToken address_street_location_and_locality = 52; + + // Phone. + optional StringToken phone_home_whole_number = 33; + + // Removed in M123. + reserved 34; + reserved "birthdate_day"; + reserved 35; + reserved "birthdate_month"; + reserved 36; + reserved "birthdate_year"; + + // Removed in M122. + reserved 6; + reserved "name_honorific"; +} diff --git a/schema/protobuf/sync_pb/data_type_progress_marker.proto b/schema/protobuf/sync_pb/data_type_progress_marker.proto new file mode 100644 index 0000000..5b4328d --- /dev/null +++ b/schema/protobuf/sync_pb/data_type_progress_marker.proto @@ -0,0 +1,185 @@ +// Copyright 2021 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +syntax = "proto2"; + +option go_package = "./sync_pb"; + +option java_multiple_files = true; +option java_package = "org.chromium.components.sync.protocol"; + +option optimize_for = LITE_RUNTIME; + +package sync_pb; + +message DataTypeProgressMarker { + // An integer identifying the data type whose progress is tracked by this + // marker. The legitimate values of this field correspond to the protobuf + // field numbers of all EntitySpecifics fields supported by the server. + // These values are externally declared in per-datatype .proto files. + optional int32 data_type_id = 1; + + // An opaque-to-the-client sequence of bytes that the server may interpret + // as an indicator of the client's knowledge state. If this is empty or + // omitted by the client, it indicates that the client is initiating a + // a first-time sync of this datatype. Otherwise, clients must supply a + // value previously returned by the server in an earlier GetUpdatesResponse. + // These values are not comparable or generable on the client. + // + // The opaque semantics of this field are to afford server implementations + // some flexibility in implementing progress tracking. For instance, + // a server implementation built on top of a distributed storage service -- + // or multiple heterogenous such services -- might need to supply a vector + // of totally ordered monotonic update timestamps, rather than a single + // monotonically increasing value. Other optimizations may also be + // possible if the server is allowed to embed arbitrary information in + // the progress token. + // + // Server implementations should keep the size of these tokens relatively + // small, on the order of tens of bytes, and they should remain small + // regardless of the number of items synchronized. (A possible bad server + // implementation would be for progress_token to contain a list of all the + // items ever sent to the client. Servers shouldn't do this.) + optional bytes token = 2; + + reserved 3; + reserved "timestamp_token_for_migration"; + + reserved 4; + reserved "notification_hint"; + + // This field will be included only in GetUpdates with origin GU_TRIGGER. + optional GetUpdateTriggers get_update_triggers = 5; + + // The garbage collection directive for this data type. The client should + // purge items locally based on this directive. Since this directive is + // designed to be sent from server only, the client should persist it locally + // as needed and avoid sending it to the server. + optional GarbageCollectionDirective gc_directive = 6; +} + +// A single datatype's sync context. Allows the datatype to pass along +// datatype specific information with its own server backend. +message DataTypeContext { + // The type this context is associated with. + optional int32 data_type_id = 1; + // The context for the datatype. + optional bytes context = 2; + // The version of the context. + optional int64 version = 3; +} + +message GarbageCollectionDirective { + enum Type { + UNKNOWN = 0; + VERSION_WATERMARK = 1; + DEPRECATED_AGE_WATERMARK = 2 [deprecated = true]; + DEPRECATED_MAX_ITEM_COUNT = 3 [deprecated = true]; + } + + // Deprecated in M124. This field is unused because it would be hard to use + // `active_collaboration_ids`. The client should rely on the presence of the + // corresponding fields instead. + optional Type type = 1 [default = UNKNOWN, deprecated = true]; + + // This field specifies the watermark for the versions which should get + // garbage collected. The client should purge all sync entities when + // receiving any value of this. This is a change from previous behavior, + // where the client would only be required to purge items older than the + // specified watermark. + // TODO(crbug.com/877951): Rename this to make clear that whenever it's set, + // the client will delete ALL data, regardless of its value. + optional int64 version_watermark = 2; + + reserved 3; + reserved "age_watermark_in_days"; + + reserved 4; + reserved "max_number_of_items"; + + // This field contains a list of active collaboration IDs which are available + // to the user. The client should stop tracking any shared sync entities with + // collaborations which are not in the list. Note that if the list is empty, + // an empty `collaboration_gc` is expected to be provided by the server. + // Introduced in M124. + message CollaborationGarbageCollection { + repeated string active_collaboration_ids = 1; + } + optional CollaborationGarbageCollection collaboration_gc = 5; +} + +// This message communicates additional per-type information related to +// requests with origin GU_TRIGGER. This message is not relevant when any +// other origin value is used. +// Introduced in M29. +message GetUpdateTriggers { + // An opaque-to-the-client string of bytes, received through a notification, + // that the server may interpret as a hint about the location of the latest + // version of the data for this type. + // Introduced in M29. + repeated string notification_hint = 1; + + // This flag is set if the client was forced to drop hints because the number + // of queued hints exceeded its limit. The oldest hints will be discarded + // first. Introduced in M29. + optional bool client_dropped_hints = 2; + + // This flag is set when the client suspects that its list of invalidation + // hints may be incomplete. This may be the case if: + // - The client is syncing for the first time. + // - The client has just restarted and it was unable to keep track of + // invalidations that were received prior to the restart. + // - The client's connection to the invalidation server is currently or + // was recently broken. + // + // It's difficult to provide more details here. This is implemented by + // setting the flag to false whenever anything that might adversely affect + // notifications happens (eg. a crash, restart on a platform that doesn't + // support invalidation ack-tracking, transient invalidation error) and is + // unset only after we've experienced one successful sync cycle while + // notifications were enabled. + // + // This flag was introduced in M29. + optional bool invalidations_out_of_sync = 3; + + // This counts the number of times the syncer has been asked to commit + // changes for this type since the last successful sync cycle. The number of + // nudges may not be related to the actual number of items modified. It + // often correlates with the number of user actions, but that's not always + // the case. + // Introduced in M29. + optional int64 local_modification_nudges = 4; + + // This counts the number of times the syncer has been explicitly asked to + // fetch updates for this type since the last successful sync cycle. These + // explicit refresh requests should be relatively rare on most platforms, and + // associated with user actions. For example, at the time of this writing + // the most common (only?) source of refresh requests is when a user opens + // the new tab page on a platform that does not support sessions + // invalidations. + // Introduced in M29. + optional int64 datatype_refresh_nudges = 5; + + // This flag is set if the invalidation server reports that it may have + // dropped some invalidations at some point. Introduced in M33. + optional bool server_dropped_hints = 6; + + // This flag is set if this GetUpdate request is due at least in part due + // to the fact that this type has not finished initial sync yet, and the + // client would like to initialize itself with the server data. + // + // Only some types support performing an initial sync as part of a normal + // GetUpdate request. Many types must be in configure mode when fetching + // initial sync data. + // + // Introduced in M38. + optional bool initial_sync_in_progress = 7; + + // This flag is set if this GetUpdate request is due to client receiving + // conflict response from server, so client needs to sync and then resolve + // conflict locally, and then commit again. + // + // Introduced in M42. + optional bool sync_for_resolve_conflict_in_progress = 8; +} diff --git a/schema/protobuf/sync_pb/device_info_specifics.proto b/schema/protobuf/sync_pb/device_info_specifics.proto new file mode 100644 index 0000000..3025c68 --- /dev/null +++ b/schema/protobuf/sync_pb/device_info_specifics.proto @@ -0,0 +1,225 @@ +// Copyright 2012 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Sync protocol datatype extension for nigori keys. + +// If you change or add any fields in this file, update proto_visitors.h and +// potentially proto_enum_conversions.{h, cc}. + +syntax = "proto2"; + +option go_package = "./sync_pb"; + +option java_multiple_files = true; +option java_package = "org.chromium.components.sync.protocol"; + +option optimize_for = LITE_RUNTIME; + +package sync_pb; + +import "sync_enums.proto"; +import "brave_device_info_specifics.proto"; + +// Information about a device that is running a sync-enabled Chrome browser. We +// are mapping the per-client cache guid to more specific information about the +// device. +message DeviceInfoSpecifics { + // The cache_guid created to identify a sync client on this device. + optional string cache_guid = 1; + + // A non-unique but human readable name to describe this client. + optional string client_name = 2; + + // The platform of the device. + // Deprecated in M110, but still populated for backwards compatibility. + // Replaced by os_type + device_form_factor. + optional SyncEnums.DeviceType device_type = 3 [deprecated = true]; + + // The UserAgent used when contacting the Chrome Sync server. + // Only present when talking to the HTTP server. + optional string sync_user_agent = 4; + + // The Chrome instance's version. Updated (if necessary) on every startup. + // DEPRECATED in M92. Still populated for backward compatibility. + optional string chrome_version = 5 [deprecated = true]; + + // Last time when pre-sync data on the device was saved. The device can be + // restored to state back to this time. In millisecond since UNIX epoch. + // DEPRECATED in M50. + optional int64 deprecated_backup_timestamp = 6 [deprecated = true]; + + // Device_id that is stable until user signs out. This device_id is used for + // annotating login scoped refresh token. Present only for Chrome Clients. + optional string signin_scoped_device_id = 7; + + // This field is updated to be the current time periodically, and is also set + // to the current time whenever another field changes. By examining the + // difference between this field and the current time, it should be possible + // to reason about the inactivity of any device that was syncing at one time. + optional int64 last_updated_timestamp = 8; + + // Device info fields that are specific to a feature. This is information that + // can not be derived from the other fields in the proto and are not general + // enough to be used by another feature. + optional FeatureSpecificFields feature_fields = 9; + + // Device specific information for Sharing feature. + optional SharingSpecificFields sharing_fields = 10; + + // Model of device. + optional string model = 11; + + // Name of device manufacturer. + optional string manufacturer = 12; + + // The interval in minutes with which |last_updated_timestamp| is updated to + // the sync servers if online and while sync is actively running (e.g. + // excludes backgrounded apps on Android). Introduced in M81. The legacy + // default was 1 day. + optional int32 pulse_interval_in_minutes = 13; + + // Device specific information for Sync invalidations. + optional InvalidationSpecificFields invalidation_fields = 14; + + // Information for contacting this device in order to perform security key + // operations. + optional PhoneAsASecurityKeySpecificFields paask_fields = 15; + + // Unique hardware identifier string which details the HW combination of + // a ChromeOS device. This field will be empty on other OS devices. + optional string full_hardware_class = 16; + + // Version information to pin-point which client implementation this is. + oneof client_version_info { + ChromeVersionInfo chrome_version_info = 17; + GooglePlayServicesVersionInfo google_play_services_version_info = 18; + } + + // The OS type the device. + optional SyncEnums.OsType os_type = 19; + + // The form factor of the device. + optional SyncEnums.DeviceFormFactor device_form_factor = 20; + optional BraveSpecificFields brave_fields = 1000; +} + +// Feature specific information about the device that is running a sync-enabled +// Chrome browser. Adding to this proto is discouraged and should only be added +// when the information can not be derived more generally. +message FeatureSpecificFields { + // Tracks whether the SendTabToSelf feature is enabled on the device. For this + // to be true, two things must be true: (1) The receiving side of the feature + // must be enabled on the device (2) The user has enabled sync for this + // feature + optional bool send_tab_to_self_receiving_enabled = 1; +} + +// Device specific information for Sharing feature. Used to send end-to-end +// encrypted message through FCM to other devices. +message SharingSpecificFields { + // FCM registration token of device subscribed using VAPID key. + // TODO(crbug.com/1012226): Deprecate when VAPID migration is over. + optional string vapid_fcm_token = 1; + + // Public key for message encryption [RFC8291] using VAPID key. + // TODO(crbug.com/1012226): Deprecate when VAPID migration is over. + optional bytes vapid_p256dh = 2; + + // Auth secret for message encryption [RFC8291] using VAPID key. + // TODO(crbug.com/1012226): Deprecate when VAPID migration is over. + optional bytes vapid_auth_secret = 3; + + // Enum defining available Sharing features. + enum EnabledFeatures { + reserved 5; + reserved "PEER_CONNECTION"; + + UNKNOWN = 0; + // Supports Click to Call only via VAPID. + CLICK_TO_CALL_VAPID = 1; + // Supports Shared Clipboard only via VAPID. + SHARED_CLIPBOARD_VAPID = 2; + SMS_FETCHER = 3; + REMOTE_COPY = 4; + DISCOVERY = 6; + // Suppots Click to Call via both VAPID and sender ID. + CLICK_TO_CALL_V2 = 7; + // Suppots Shared Clipboard via both VAPID and sender ID. + SHARED_CLIPBOARD_V2 = 8; + // Supports optimization guide push notification. + OPTIMIZATION_GUIDE_PUSH_NOTIFICATION = 9; + } + + // A list of enabled Sharing features. + repeated EnabledFeatures enabled_features = 4; + + // Deprecated. Use sender_id_fcm_token_v2 for new clients. + optional string sender_id_fcm_token_deprecated = 5 [deprecated = true]; + + // Deprecated. Use sender_id_p256dh_v2 for new clients. + optional bytes sender_id_p256dh_deprecated = 6 [deprecated = true]; + + // Deprecated. Use sender_id_auth_secret_v2 for new clients. + optional bytes sender_id_auth_secret_deprecated = 7 [deprecated = true]; + + // FCM registration token of device subscribed using Sharing sender ID. + optional string sender_id_fcm_token_v2 = 8; + + // Public key for message encryption [RFC8291] using Sharing sender ID. + optional bytes sender_id_p256dh_v2 = 9; + + // Auth secret for message encryption [RFC8291] using Sharing sender ID. + optional bytes sender_id_auth_secret_v2 = 10; +} + +// Device specific information telling how to send invalidations to this device. +message InvalidationSpecificFields { + // FCM registration token of device (using Sync sender ID). + optional string instance_id_token = 1; + + // This device wants to receive only invalidations which are related to these + // types. The legitimate values of this field correspond to the protobuf field + // numbers of all EntitySpecifics fields supported by the server (see + // components/sync/protocol/sync.proto). + repeated int32 interested_data_type_ids = 2; +} + +message PhoneAsASecurityKeySpecificFields { + // The encoded tunnel server in the same format as in the BLE advert. See + // device::cablev2::tunnelserver::DecodeDomain. (Actually a uint16 but + // proto doesn't have that as a type.) + optional uint32 tunnel_server_domain = 1; + + // An FCM token that can be presented to the tunnel server to contact this + // device. + optional bytes contact_id = 2; + + // A shared secret key, used to enable communication across devices via + // unauthenticated channels. Knowledge of this secret acts as proof that the + // remote end is authorized to talk to the device publishing this secret. + optional bytes secret = 3; + + // An id that identifies |secret|. This, and |secret|, will be rotated and + // the ID allows this device to know which |secret| the counterparty is + // using. + optional fixed32 id = 4; + + // A P-256, X9.62-encoded public key for this device. Specific to the Chrome + // instance. + optional bytes peer_public_key_x962 = 5; + + // The credential ID for use when signing into accounts.google.com. This + // credential ID isn't published as a WebauthnCredentialSpecifics, unlike + // other passkeys, because it's auto-generated. + optional bytes google_credential_id = 6; +} + +message ChromeVersionInfo { + // Version number as per https://www.chromium.org/developers/version-numbers. + optional string version_number = 1; +} + +message GooglePlayServicesVersionInfo { + optional string apk_version_name = 1; +} diff --git a/schema/protobuf/sync_pb/dictionary_specifics.proto b/schema/protobuf/sync_pb/dictionary_specifics.proto new file mode 100644 index 0000000..2207621 --- /dev/null +++ b/schema/protobuf/sync_pb/dictionary_specifics.proto @@ -0,0 +1,25 @@ +// Copyright 2012 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Sync protocol datatype extension for the dictionary. + +// If you change or add any fields in this file, update proto_visitors.h and +// potentially proto_enum_conversions.{h, cc}. + +syntax = "proto2"; + +option go_package = "./sync_pb"; + +option java_multiple_files = true; +option java_package = "org.chromium.components.sync.protocol"; + +option optimize_for = LITE_RUNTIME; + +package sync_pb; + +// Properties of Dictionary objects. +message DictionarySpecifics { + // A spelling which when typed is treated as a correctly spelled word. + optional string word = 1; +} diff --git a/schema/protobuf/sync_pb/encryption.proto b/schema/protobuf/sync_pb/encryption.proto new file mode 100644 index 0000000..85d8527 --- /dev/null +++ b/schema/protobuf/sync_pb/encryption.proto @@ -0,0 +1,36 @@ +// Copyright 2012 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Common sync protocol for encrypted data. + +// If you change or add any fields in this file, update proto_visitors.h and +// potentially proto_enum_conversions.{h, cc}. + +syntax = "proto2"; + +option go_package = "./sync_pb"; + +option java_multiple_files = true; +option java_package = "org.chromium.components.sync.protocol"; + +option optimize_for = LITE_RUNTIME; + +package sync_pb; + +// Encrypted sync data consists of two parts: a key name and a blob. Key name is +// the name of the key that was used to encrypt blob and blob is encrypted data +// itself. +// +// The reason we need to keep track of the key name is that a sync user can +// change their passphrase (and thus their encryption key) at any time. When +// that happens, we make a best effort to reencrypt all nodes with the new +// passphrase, but since we don't have transactions on the server-side, we +// cannot guarantee that every node will be reencrypted. As a workaround, we +// keep track of all keys, assign each key a name (by using that key to encrypt +// a well known string) and keep track of which key was used to encrypt each +// node. +message EncryptedData { + optional string key_name = 1; + optional string blob = 2; // base64-encoded. +} diff --git a/schema/protobuf/sync_pb/entity_metadata.proto b/schema/protobuf/sync_pb/entity_metadata.proto new file mode 100644 index 0000000..7dffc32 --- /dev/null +++ b/schema/protobuf/sync_pb/entity_metadata.proto @@ -0,0 +1,103 @@ +// Copyright 2015 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// If you change or add any fields in this file, update proto_visitors.h and +// potentially proto_enum_conversions.{h, cc}. + +syntax = "proto2"; + +option go_package = "./sync_pb"; + +option java_multiple_files = true; +option java_package = "org.chromium.components.sync.protocol"; + +option optimize_for = LITE_RUNTIME; + +package sync_pb; + +import "entity_specifics.proto"; +import "unique_position.proto"; + +// Sync proto to store entity metadata in model type storage. +message EntityMetadata { + // A hash based on the client tag and model type. + // Used for various map lookups. Should always be available. + // Sent to the server as SyncEntity::client_tag_hash. + optional string client_tag_hash = 1; + + // The entity's server-assigned ID. + // + // Prior to the item's first commit, we leave this value as an empty string. + // The initial ID for a newly created item has to meet certain uniqueness + // requirements, and we handle those on the sync thread. + optional string server_id = 2; + + // Whether or not the entity is deleted. + optional bool is_deleted = 3; + + // A version number used to track in-progress commits. Each local change + // increments this number. + optional int64 sequence_number = 4; + + // The sequence number of the last item known to be successfully committed. + optional int64 acked_sequence_number = 5; + + // The server version on which this item is based. + // + // If there are no local changes, this is the version of the entity as we see + // it here. + // + // If there are local changes, this is the version of the entity on which + // those changes are based. + optional int64 server_version = 6 [default = -1]; + + // Entity creation and modification timestamps. Assigned by the client and + // synced by the server, though the server usually doesn't bother to inspect + // their values. They are encoded as milliseconds since the Unix epoch. + optional int64 creation_time = 7; + optional int64 modification_time = 8; + + // A hash of the current entity specifics value. Used to detect whether + // entity's specifics value has changed without having to keep specifics in + // memory. + optional string specifics_hash = 9; + + // A hash of the last specifics known by both the client and server. Used to + // detect when local commits and remote updates are just for encryption. This + // value will be the empty string only in the following cases: the entity is + // in sync with the server, has never been synced, or is deleted. + optional string base_specifics_hash = 10; + + // Used for positioning entities among their siblings. Relevant only for data + // types that support positions (e.g bookmarks). Refer to its definition in + // unique_position.proto for more information about its internal + // representation. + optional UniquePosition unique_position = 11; + + // Used only for bookmarks. It's analogous to |specifics_hash| but it + // exclusively hashes the content of the favicon image, as represented in + // proto field BookmarkSpecifics.favicon, using base::PersistentHash(). + optional fixed32 bookmark_favicon_hash = 12; + + // Last specifics known by both the client and server. Used during commits to + // the server in order to prevent data loss caused by older clients dealing + // with unknown proto fields (fields that were introduced later). Datatypes + // (ModelTypeSyncBridge) may implement logic to trim down (or fully clear) + // this proto prior to caching, to avoid the memory and I/O overhead of + // dealing with an extra copy of the data. Introduced in M101. + optional EntitySpecifics possibly_trimmed_base_specifics = 13; + + // If the entity is deleted, this field will record the chromium version + // (e.g. 117.0.5875.1) that originated the deletion. Introduced in M117. + optional string deleted_by_version = 14; + + // Metadata used for shared data types. Must not be present for regular data + // types. + // Introduced in M124. + message CollaborationMetadata { + // Collaboration ID which the current entity belongs to. + optional string collaboration_id = 1; + } + optional CollaborationMetadata collaboration = 15; +} diff --git a/schema/protobuf/sync_pb/entity_specifics.proto b/schema/protobuf/sync_pb/entity_specifics.proto new file mode 100644 index 0000000..04c2c3f --- /dev/null +++ b/schema/protobuf/sync_pb/entity_specifics.proto @@ -0,0 +1,189 @@ +// Copyright 2021 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +syntax = "proto2"; + +option go_package = "./sync_pb"; + +option java_multiple_files = true; +option java_package = "org.chromium.components.sync.protocol"; + +option optimize_for = LITE_RUNTIME; + +package sync_pb; + +import "encryption.proto"; +import "app_list_specifics.proto"; +import "app_setting_specifics.proto"; +import "app_specifics.proto"; +import "arc_package_specifics.proto"; +import "autofill_specifics.proto"; +import "autofill_offer_specifics.proto"; +import "autofill_wallet_credential_specifics.proto"; +import "autofill_wallet_usage_specifics.proto"; +import "bookmark_specifics.proto"; +import "collaboration_group_specifics.proto"; +import "compare_specifics.proto"; +import "contact_info_specifics.proto"; +import "device_info_specifics.proto"; +import "dictionary_specifics.proto"; +import "experiments_specifics.proto"; +import "extension_setting_specifics.proto"; +import "extension_specifics.proto"; +import "favicon_image_specifics.proto"; +import "favicon_tracking_specifics.proto"; +import "history_delete_directive_specifics.proto"; +import "history_specifics.proto"; +import "managed_user_setting_specifics.proto"; +import "managed_user_shared_setting_specifics.proto"; +import "nigori_specifics.proto"; +import "os_preference_specifics.proto"; +import "os_priority_preference_specifics.proto"; +import "password_sharing_invitation_specifics.proto"; +import "password_specifics.proto"; +import "plus_address_specifics.proto"; +import "power_bookmark_specifics.proto"; +import "preference_specifics.proto"; +import "printer_specifics.proto"; +import "printers_authorization_server_specifics.proto"; +import "priority_preference_specifics.proto"; +import "reading_list_specifics.proto"; +import "saved_tab_group_specifics.proto"; +import "search_engine_specifics.proto"; +import "security_event_specifics.proto"; +import "send_tab_to_self_specifics.proto"; +import "segmentation_specifics.proto"; +import "session_specifics.proto"; +import "shared_tab_group_data_specifics.proto"; +import "sharing_message_specifics.proto"; +import "theme_specifics.proto"; +import "typed_url_specifics.proto"; +import "user_consent_specifics.proto"; +import "user_event_specifics.proto"; +import "web_apk_specifics.proto"; +import "web_app_specifics.proto"; +import "webauthn_credential_specifics.proto"; +import "wifi_configuration_specifics.proto"; +import "workspace_desk_specifics.proto"; + +message EntitySpecifics { + // If a datatype is encrypted, this field will contain the encrypted + // original EntitySpecifics. The extension for the datatype will continue + // to exist, but contain only the default values. + // Note that currently passwords employ their own legacy encryption scheme and + // do not use this field. + optional EncryptedData encrypted = 1; + + // To add new datatype-specific fields to the protocol, extend + // EntitySpecifics. First, pick a non-colliding tag number by + // picking a Cr-Commit-Position of one of your past commits + // to src.chromium.org. Then, in a different protocol buffer + // definition, define your message type, and add an optional field + // to the list below using the unique tag value you selected. + // + // optional MyDatatypeSpecifics my_datatype = 32222; + // + // where: + // - 32222 is the non-colliding tag number you picked earlier. + // - MyDatatypeSpecifics is the type (probably a message type defined + // in your new .proto file) that you want to associate with each + // object of the new datatype. + // - my_datatype is the field identifier you'll use to access the + // datatype specifics from the code. + // + // Server implementations are obligated to preserve the contents of + // EntitySpecifics when it contains unrecognized fields. In this + // way, it is possible to add new datatype fields without having + // to update the server. + // + // Note: The tag selection process is based on legacy versions of the + // protocol which used protobuf extensions. We have kept the process + // consistent as the old values cannot change. The 5+ digit nature of the + // tags also makes them recognizable (individually and collectively) from + // noise in logs and debugging contexts, and creating a divergent subset of + // tags would only make things a bit more confusing. + + oneof specifics_variant { + AutofillSpecifics autofill = 31729; + BookmarkSpecifics bookmark = 32904; + PreferenceSpecifics preference = 37702; + TypedUrlSpecifics typed_url = 40781; + ThemeSpecifics theme = 41210; + PasswordSpecifics password = 45873; + NigoriSpecifics nigori = 47745; + ExtensionSpecifics extension = 48119; + AppSpecifics app = 48364; + SessionSpecifics session = 50119; + AutofillProfileSpecifics autofill_profile = 63951; + SearchEngineSpecifics search_engine = 88610; + ExtensionSettingSpecifics extension_setting = 96159; + AppSettingSpecifics app_setting = 103656; + HistoryDeleteDirectiveSpecifics history_delete_directive = 150251; + DeviceInfoSpecifics device_info = 154522; + PriorityPreferenceSpecifics priority_preference = 163425; + DictionarySpecifics dictionary = 170540; + ManagedUserSettingSpecifics managed_user_setting = 186662; + AppListSpecifics app_list = 229170; + AutofillWalletSpecifics autofill_wallet = 306270; + WalletMetadataSpecifics wallet_metadata = 330441; + ArcPackageSpecifics arc_package = 340906; + PrinterSpecifics printer = 410745; + ReadingListSpecifics reading_list = 411028; + UserEventSpecifics user_event = 455206; + UserConsentSpecifics user_consent = 556014; + SendTabToSelfSpecifics send_tab_to_self = 601980; + SecurityEventSpecifics security_event = 600372; + WebApkSpecifics web_apk = 1117170; + WebAppSpecifics web_app = 673225; + WifiConfigurationSpecifics wifi_configuration = 662827; + OsPreferenceSpecifics os_preference = 702141; + OsPriorityPreferenceSpecifics os_priority_preference = 703915; + SharingMessageSpecifics sharing_message = 728866; + AutofillOfferSpecifics autofill_offer = 774329; + WorkspaceDeskSpecifics workspace_desk = 874841; + WebauthnCredentialSpecifics webauthn_credential = 895275; + HistorySpecifics history = 963985; + PrintersAuthorizationServerSpecifics printers_authorization_server = 974304; + SavedTabGroupSpecifics saved_tab_group = 1004874; + AutofillWalletUsageSpecifics autofill_wallet_usage = 1033580; + ContactInfoSpecifics contact_info = 1034378; + SegmentationSpecifics segmentation = 1026052; + PowerBookmarkSpecifics power_bookmark = 1073150; + IncomingPasswordSharingInvitationSpecifics + incoming_password_sharing_invitation = 1141935; + OutgoingPasswordSharingInvitationSpecifics + outgoing_password_sharing_invitation = 1142081; + AutofillWalletCredentialSpecifics autofill_wallet_credential = 1164238; + SharedTabGroupDataSpecifics shared_tab_group_data = 1239418; + CollaborationGroupSpecifics collaboration_group = 1259076; + CompareSpecifics compare = 1329438; + PlusAddressSpecifics plus_address = 1267844; + // When adding a new type, follow the docs below and keep this comment as + // the last entry. + // https://www.chromium.org/developers/design-documents/sync/integration-checklist/ + + // No-longer-supported data types, in various stages of removal. + // TODO(crbug.com/1395003): Eventually, these should all become "reserved" + // fields, or at least use "EmptySpecifics". But some of them are still + // needed by the server, e.g. to support older clients. + EmptySpecifics app_notification = 45184 [deprecated = true]; + EmptySpecifics synced_notification = 153108 [deprecated = true]; + EmptySpecifics synced_notification_app_info = 235816 [deprecated = true]; + ExperimentsSpecifics experiments = 161496 [deprecated = true]; + FaviconTrackingSpecifics favicon_tracking = 181534 [deprecated = true]; + FaviconImageSpecifics favicon_image = 182019 [deprecated = true]; + EmptySpecifics managed_user = 194582 [deprecated = true]; + ManagedUserSharedSettingSpecifics managed_user_shared_setting = 202026 + [deprecated = true]; + EmptySpecifics managed_user_allowlist = 306060 [deprecated = true]; + } + reserved 218175; + reserved "wifi_credential"; + reserved 223759; + reserved "article"; + reserved 545005; + reserved "mountain_share"; +} + +message EmptySpecifics {} diff --git a/schema/protobuf/sync_pb/experiment_status.proto b/schema/protobuf/sync_pb/experiment_status.proto new file mode 100644 index 0000000..a1ead6b --- /dev/null +++ b/schema/protobuf/sync_pb/experiment_status.proto @@ -0,0 +1,45 @@ +// Copyright 2014 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// NOTE: This API is not used in Chromium anymore, but the server still needs to +// support it for the benefit of older clients (Chrome versions up to and +// including M80 rely on it, see crbug.com/1009361). + +syntax = "proto2"; + +option go_package = "./sync_pb"; + +option java_multiple_files = true; +option java_package = "org.chromium.components.sync.protocol"; + +option optimize_for = LITE_RUNTIME; + +package sync_pb; + +import "experiments_specifics.proto"; + +// This request allows an unauthenticated client to check the status of the +// experiments which do not require user authentication. The status of an +// experiment for a specific client can be determined based on the user agent +// string and/or the client id sent in the HTTPS POST request. +message ExperimentStatusRequest { + // Enumerates the experiments for which the status should be returned. An + // experiment name must be the same as one of the field names specified in + // ExperimentsSpecifics. See sync/protocol/experiments_specifics.proto. + repeated string experiment_name = 1; +} + +// Response to an experiment status request. +message ExperimentStatusResponse { + // Minimal time to wait before issuing another request. + optional int32 poll_interval_seconds = 1 [default = 3600]; + + // The experiments that the client has asked for, with each experiment + // containing exactly one experiment flag. The client can inspect the + // embedded flag to obtain the experiment status. Note that the number of + // experiments should be less than or equal to the number of experiment_name + // sent in the request since it is possible that there is no experiment + // matching an experiment_name. + repeated ExperimentsSpecifics experiment = 2; +} diff --git a/schema/protobuf/sync_pb/experiments_specifics.proto b/schema/protobuf/sync_pb/experiments_specifics.proto new file mode 100644 index 0000000..3d36512 --- /dev/null +++ b/schema/protobuf/sync_pb/experiments_specifics.proto @@ -0,0 +1,88 @@ +// Copyright 2012 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// This was a sync protocol datatype extension for experimental feature flags, +// also exposed via a separate ExperimentStatus API. As of M75, the datatype +// isn't used anymore, and as of M81 the ExperimentStatus API isn't used anymore +// either (see crbug.com/939819 and crbug.com/1009361). The proto definition +// needs to stay around for now so that the server can continue supporting these +// old clients . + +syntax = "proto2"; + +option go_package = "./sync_pb"; + +option java_multiple_files = true; +option java_package = "org.chromium.components.sync.protocol"; + +option optimize_for = LITE_RUNTIME; + +package sync_pb; + +// A flag to enable support for keystore encryption. +message KeystoreEncryptionFlags { + optional bool enabled = 1; +} + +// Whether history delete directives are enabled. +message HistoryDeleteDirectives { + optional bool enabled = 1; +} + +// Whether this client should cull (delete) expired autofill +// entries when autofill sync is enabled. +message AutofillCullingFlags { + optional bool enabled = 1; +} + +// Whether the favicon sync datatypes are enabled, and what parameters +// they should operate under. +message FaviconSyncFlags { + optional bool enabled = 1; + optional int32 favicon_sync_limit = 2 [default = 200]; +} + +// Flags for enabling the experimental no-precommit GU feature. +message PreCommitUpdateAvoidanceFlags { + optional bool enabled = 1; +} + +// Flags for enabling the GCM feature. +message GcmChannelFlags { + optional bool enabled = 1; +} + +// Flags for enabling the experimental enhanced bookmarks feature. +message EnhancedBookmarksFlags { + optional bool enabled = 1; + optional string extension_id = 2; +} + +// Flags for enabling GCM channel for invalidations. +message GcmInvalidationsFlags { + optional bool enabled = 1; +} + +// Flags for enabling wallet data syncing. +message WalletSyncFlags { + optional bool enabled = 1; +} + +// Contains one flag or set of related flags. Each node of the experiments type +// will have a unique_client_tag identifying which flags it contains. By +// convention, the tag name should match the sub-message name. +message ExperimentsSpecifics { + optional KeystoreEncryptionFlags keystore_encryption = 1; + optional HistoryDeleteDirectives history_delete_directives = 2; + optional AutofillCullingFlags autofill_culling = 3; + optional FaviconSyncFlags favicon_sync = 4; + optional PreCommitUpdateAvoidanceFlags pre_commit_update_avoidance = 5; + optional GcmChannelFlags gcm_channel = 6; + // No longer used as of M43. + optional EnhancedBookmarksFlags obsolete_enhanced_bookmarks = 7; + // No longer used as of M72. + optional GcmInvalidationsFlags gcm_invalidations = 8; + // No longer used as of M51. + optional WalletSyncFlags obsolete_wallet_sync = 9; +} diff --git a/schema/protobuf/sync_pb/extension_setting_specifics.proto b/schema/protobuf/sync_pb/extension_setting_specifics.proto new file mode 100644 index 0000000..8eb69f8 --- /dev/null +++ b/schema/protobuf/sync_pb/extension_setting_specifics.proto @@ -0,0 +1,31 @@ +// Copyright 2012 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Sync protocol datatype extension for an extension setting. + +// If you change or add any fields in this file, update proto_visitors.h and +// potentially proto_enum_conversions.{h, cc}. + +syntax = "proto2"; + +option go_package = "./sync_pb"; + +option java_multiple_files = true; +option java_package = "org.chromium.components.sync.protocol"; + +option optimize_for = LITE_RUNTIME; + +package sync_pb; + +// Properties of extension setting sync objects. +message ExtensionSettingSpecifics { + // Id of the extension the setting is for. + optional string extension_id = 1; + + // Setting key. + optional string key = 2; + + // Setting value serialized as JSON. + optional string value = 3; +} diff --git a/schema/protobuf/sync_pb/extension_specifics.proto b/schema/protobuf/sync_pb/extension_specifics.proto new file mode 100644 index 0000000..1fac8ce --- /dev/null +++ b/schema/protobuf/sync_pb/extension_specifics.proto @@ -0,0 +1,58 @@ +// Copyright 2012 The Chromium Authors +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Sync protocol datatype extension for extensions. + +// If you change or add any fields in this file, update proto_visitors.h and +// potentially proto_enum_conversions.{h, cc}. + +syntax = "proto2"; + +option go_package = "./sync_pb"; + +option java_multiple_files = true; +option java_package = "org.chromium.components.sync.protocol"; + +option optimize_for = LITE_RUNTIME; + +package sync_pb; + +// Properties of extension sync objects. +// +// Merge policy: the settings for the higher version number win; in +// the case of a tie, server wins. +message ExtensionSpecifics { + // Globally unique id for this extension. + optional string id = 1; + // The known installed version. + optional string version = 2; + + // Auto-update URL to use for this extension. May be blank, in + // which case the default one (i.e., the one for the Chrome + // Extensions Gallery) is used. + optional string update_url = 3; + // Whether or not this extension is enabled. + optional bool enabled = 4; + // Whether or not this extension is enabled in incognito mode. + optional bool incognito_enabled = 5; + + // DEPRECATED. See https://crbug.com/1233303. + optional string name = 6 [deprecated = true]; + + // Whether this extension was installed remotely, and hasn't been approved by + // a user in chrome yet. + optional bool remote_install = 7; + + // DEPRECATED. See https://crbug.com/1014183. + optional bool installed_by_custodian = 8 [deprecated = true]; + + // DEPRECATED. See https://crbug.com/839681. + optional bool all_urls_enabled = 9 [deprecated = true]; + + // Bitmask of the set of reasons why the extension is disabled (see + // extensions::disable_reason::DisableReason). Only relevant when enabled == + // false. Note that old clients (