From 28826af88dee93591f374a9985b55390ceecd7af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C4=81nis=20L?= Date: Thu, 4 Jun 2026 23:57:44 +0300 Subject: [PATCH] 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 --- .dockerignore | 6 + .gitignore | 5 + Cargo.lock | 1608 +++++++++++++++++ Cargo.toml | 27 + Dockerfile | 33 + README.md | 43 + build.rs | 21 + docker-entrypoint.sh | 12 + .../protobuf/sync_pb/app_list_specifics.proto | 110 ++ .../sync_pb/app_setting_specifics.proto | 28 + schema/protobuf/sync_pb/app_specifics.proto | 103 ++ .../sync_pb/arc_package_specifics.proto | 32 + .../sync_pb/autofill_offer_specifics.proto | 110 ++ .../protobuf/sync_pb/autofill_specifics.proto | 665 +++++++ ...autofill_wallet_credential_specifics.proto | 29 + .../autofill_wallet_usage_specifics.proto | 45 + .../sync_pb/bookmark_model_metadata.proto | 81 + .../protobuf/sync_pb/bookmark_specifics.proto | 97 + .../sync_pb/brave_device_info_specifics.proto | 19 + schema/protobuf/sync_pb/client_commands.proto | 57 + .../protobuf/sync_pb/client_debug_info.proto | 94 + .../collaboration_group_specifics.proto | 29 + .../protobuf/sync_pb/compare_specifics.proto | 42 + .../sync_pb/contact_info_specifics.proto | 217 +++ .../sync_pb/data_type_progress_marker.proto | 185 ++ .../sync_pb/device_info_specifics.proto | 225 +++ .../sync_pb/dictionary_specifics.proto | 25 + schema/protobuf/sync_pb/encryption.proto | 36 + schema/protobuf/sync_pb/entity_metadata.proto | 103 ++ .../protobuf/sync_pb/entity_specifics.proto | 189 ++ .../protobuf/sync_pb/experiment_status.proto | 45 + .../sync_pb/experiments_specifics.proto | 88 + .../sync_pb/extension_setting_specifics.proto | 31 + .../sync_pb/extension_specifics.proto | 58 + .../sync_pb/favicon_image_specifics.proto | 49 + .../sync_pb/favicon_tracking_specifics.proto | 33 + .../sync_pb/gaia_password_reuse.proto | 106 ++ .../sync_pb/get_updates_caller_info.proto | 27 + .../history_delete_directive_specifics.proto | 77 + .../protobuf/sync_pb/history_specifics.proto | 154 ++ schema/protobuf/sync_pb/history_status.proto | 25 + schema/protobuf/sync_pb/loopback_server.proto | 50 + .../managed_user_setting_specifics.proto | 25 + ...anaged_user_shared_setting_specifics.proto | 33 + .../protobuf/sync_pb/model_type_state.proto | 99 + .../model_type_store_schema_descriptor.proto | 24 + .../protobuf/sync_pb/nigori_local_data.proto | 133 ++ .../protobuf/sync_pb/nigori_specifics.proto | 295 +++ schema/protobuf/sync_pb/note_entity.proto | 38 + .../sync_pb/os_preference_specifics.proto | 28 + .../os_priority_preference_specifics.proto | 28 + ...assword_sharing_invitation_specifics.proto | 134 ++ .../sync_pb/password_sharing_recipients.proto | 41 + .../protobuf/sync_pb/password_specifics.proto | 367 ++++ .../sync_pb/persisted_entity_data.proto | 28 + .../sync_pb/plus_address_specifics.proto | 29 + .../sync_pb/power_bookmark_specifics.proto | 59 + .../sync_pb/preference_specifics.proto | 25 + .../protobuf/sync_pb/printer_specifics.proto | 83 + ...nters_authorization_server_specifics.proto | 27 + .../priority_preference_specifics.proto | 26 + .../sync_pb/reading_list_specifics.proto | 43 + .../sync_pb/saved_tab_group_specifics.proto | 85 + .../sync_pb/search_engine_specifics.proto | 98 + .../sync_pb/security_event_specifics.proto | 29 + .../sync_pb/segmentation_specifics.proto | 113 ++ .../sync_pb/send_tab_to_self_specifics.proto | 47 + .../protobuf/sync_pb/session_specifics.proto | 198 ++ .../shared_tab_group_data_specifics.proto | 70 + .../sync_pb/sharing_message_specifics.proto | 87 + schema/protobuf/sync_pb/sync.proto | 505 ++++++ schema/protobuf/sync_pb/sync_entity.proto | 235 +++ schema/protobuf/sync_pb/sync_enums.proto | 225 +++ .../sync_pb/sync_invalidations_payload.proto | 39 + schema/protobuf/sync_pb/test.proto | 25 + schema/protobuf/sync_pb/theme_specifics.proto | 49 + .../sync_pb/typed_url_specifics.proto | 42 + schema/protobuf/sync_pb/unique_position.proto | 84 + .../sync_pb/user_consent_specifics.proto | 113 ++ .../protobuf/sync_pb/user_consent_types.proto | 173 ++ .../sync_pb/user_event_specifics.proto | 142 ++ .../protobuf/sync_pb/web_apk_specifics.proto | 52 + .../protobuf/sync_pb/web_app_specifics.proto | 98 + .../webauthn_credential_specifics.proto | 173 ++ .../wifi_configuration_specifics.proto | 94 + .../sync_pb/workspace_desk_specifics.proto | 291 +++ src/auth.rs | 131 ++ src/cache.rs | 84 + src/command.rs | 722 ++++++++ src/datastore.rs | 778 ++++++++ src/main.rs | 231 +++ src/proto.rs | 5 + src/util.rs | 64 + 93 files changed, 11666 insertions(+) create mode 100644 .dockerignore create mode 100644 .gitignore create mode 100644 Cargo.lock create mode 100644 Cargo.toml create mode 100644 Dockerfile create mode 100644 README.md create mode 100644 build.rs create mode 100644 docker-entrypoint.sh create mode 100644 schema/protobuf/sync_pb/app_list_specifics.proto create mode 100644 schema/protobuf/sync_pb/app_setting_specifics.proto create mode 100644 schema/protobuf/sync_pb/app_specifics.proto create mode 100644 schema/protobuf/sync_pb/arc_package_specifics.proto create mode 100644 schema/protobuf/sync_pb/autofill_offer_specifics.proto create mode 100644 schema/protobuf/sync_pb/autofill_specifics.proto create mode 100644 schema/protobuf/sync_pb/autofill_wallet_credential_specifics.proto create mode 100644 schema/protobuf/sync_pb/autofill_wallet_usage_specifics.proto create mode 100644 schema/protobuf/sync_pb/bookmark_model_metadata.proto create mode 100644 schema/protobuf/sync_pb/bookmark_specifics.proto create mode 100644 schema/protobuf/sync_pb/brave_device_info_specifics.proto create mode 100644 schema/protobuf/sync_pb/client_commands.proto create mode 100644 schema/protobuf/sync_pb/client_debug_info.proto create mode 100644 schema/protobuf/sync_pb/collaboration_group_specifics.proto create mode 100644 schema/protobuf/sync_pb/compare_specifics.proto create mode 100644 schema/protobuf/sync_pb/contact_info_specifics.proto create mode 100644 schema/protobuf/sync_pb/data_type_progress_marker.proto create mode 100644 schema/protobuf/sync_pb/device_info_specifics.proto create mode 100644 schema/protobuf/sync_pb/dictionary_specifics.proto create mode 100644 schema/protobuf/sync_pb/encryption.proto create mode 100644 schema/protobuf/sync_pb/entity_metadata.proto create mode 100644 schema/protobuf/sync_pb/entity_specifics.proto create mode 100644 schema/protobuf/sync_pb/experiment_status.proto create mode 100644 schema/protobuf/sync_pb/experiments_specifics.proto create mode 100644 schema/protobuf/sync_pb/extension_setting_specifics.proto create mode 100644 schema/protobuf/sync_pb/extension_specifics.proto create mode 100644 schema/protobuf/sync_pb/favicon_image_specifics.proto create mode 100644 schema/protobuf/sync_pb/favicon_tracking_specifics.proto create mode 100644 schema/protobuf/sync_pb/gaia_password_reuse.proto create mode 100644 schema/protobuf/sync_pb/get_updates_caller_info.proto create mode 100644 schema/protobuf/sync_pb/history_delete_directive_specifics.proto create mode 100644 schema/protobuf/sync_pb/history_specifics.proto create mode 100644 schema/protobuf/sync_pb/history_status.proto create mode 100644 schema/protobuf/sync_pb/loopback_server.proto create mode 100644 schema/protobuf/sync_pb/managed_user_setting_specifics.proto create mode 100644 schema/protobuf/sync_pb/managed_user_shared_setting_specifics.proto create mode 100644 schema/protobuf/sync_pb/model_type_state.proto create mode 100644 schema/protobuf/sync_pb/model_type_store_schema_descriptor.proto create mode 100644 schema/protobuf/sync_pb/nigori_local_data.proto create mode 100644 schema/protobuf/sync_pb/nigori_specifics.proto create mode 100644 schema/protobuf/sync_pb/note_entity.proto create mode 100644 schema/protobuf/sync_pb/os_preference_specifics.proto create mode 100644 schema/protobuf/sync_pb/os_priority_preference_specifics.proto create mode 100644 schema/protobuf/sync_pb/password_sharing_invitation_specifics.proto create mode 100644 schema/protobuf/sync_pb/password_sharing_recipients.proto create mode 100644 schema/protobuf/sync_pb/password_specifics.proto create mode 100644 schema/protobuf/sync_pb/persisted_entity_data.proto create mode 100644 schema/protobuf/sync_pb/plus_address_specifics.proto create mode 100644 schema/protobuf/sync_pb/power_bookmark_specifics.proto create mode 100644 schema/protobuf/sync_pb/preference_specifics.proto create mode 100644 schema/protobuf/sync_pb/printer_specifics.proto create mode 100644 schema/protobuf/sync_pb/printers_authorization_server_specifics.proto create mode 100644 schema/protobuf/sync_pb/priority_preference_specifics.proto create mode 100644 schema/protobuf/sync_pb/reading_list_specifics.proto create mode 100644 schema/protobuf/sync_pb/saved_tab_group_specifics.proto create mode 100644 schema/protobuf/sync_pb/search_engine_specifics.proto create mode 100644 schema/protobuf/sync_pb/security_event_specifics.proto create mode 100644 schema/protobuf/sync_pb/segmentation_specifics.proto create mode 100644 schema/protobuf/sync_pb/send_tab_to_self_specifics.proto create mode 100644 schema/protobuf/sync_pb/session_specifics.proto create mode 100644 schema/protobuf/sync_pb/shared_tab_group_data_specifics.proto create mode 100644 schema/protobuf/sync_pb/sharing_message_specifics.proto create mode 100644 schema/protobuf/sync_pb/sync.proto create mode 100644 schema/protobuf/sync_pb/sync_entity.proto create mode 100644 schema/protobuf/sync_pb/sync_enums.proto create mode 100644 schema/protobuf/sync_pb/sync_invalidations_payload.proto create mode 100644 schema/protobuf/sync_pb/test.proto create mode 100644 schema/protobuf/sync_pb/theme_specifics.proto create mode 100644 schema/protobuf/sync_pb/typed_url_specifics.proto create mode 100644 schema/protobuf/sync_pb/unique_position.proto create mode 100644 schema/protobuf/sync_pb/user_consent_specifics.proto create mode 100644 schema/protobuf/sync_pb/user_consent_types.proto create mode 100644 schema/protobuf/sync_pb/user_event_specifics.proto create mode 100644 schema/protobuf/sync_pb/web_apk_specifics.proto create mode 100644 schema/protobuf/sync_pb/web_app_specifics.proto create mode 100644 schema/protobuf/sync_pb/webauthn_credential_specifics.proto create mode 100644 schema/protobuf/sync_pb/wifi_configuration_specifics.proto create mode 100644 schema/protobuf/sync_pb/workspace_desk_specifics.proto create mode 100644 src/auth.rs create mode 100644 src/cache.rs create mode 100644 src/command.rs create mode 100644 src/datastore.rs create mode 100644 src/main.rs create mode 100644 src/proto.rs create mode 100644 src/util.rs 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 (