diff --git a/BUILDS.md b/BUILDS.md index 8f43485c..eb4abc7a 100644 --- a/BUILDS.md +++ b/BUILDS.md @@ -6,9 +6,12 @@ * Go 1.18 * Bash with basic build utils: make, gcc, sed, find, grep, ... - For Windows, it is recommended to use MinGW 64bit shell from [MSYS2](https://www.msys2.org/) -* GCC (linux), msvc (windows) or Xcode (macOS) -* Windres (windows) -* libglvnd and libsecret development files (linux) +* GCC (Linux), msvc (Windows) or Xcode (macOS) +* Windres (Windows) +* libglvnd and libsecret development files (Linux) +* pkg-config (Linux) +* cmake, ninja-build and Qt 6 are required to build the graphical user interface. On Linux, +the Mesa OpenGL development files are also needed. To enable the sending of crash reports using Sentry please set the `DSN_SENTRY` environment variable with the client key of your sentry project before build. diff --git a/Changelog.md b/Changelog.md index d283c6fb..97d717d1 100644 --- a/Changelog.md +++ b/Changelog.md @@ -2,13 +2,31 @@ Changelog [format](http://keepachangelog.com/en/1.0.0/) +## [Bridge 3.2.0] Rialto + +### Changed +* GODT-2502: Improve logs. +* GODT-2551: Store and Recover Last User Agent from Vault. +* GODT-2550: Verify IMAP ID is set properly. +* GODT-2554: Compute telemetry availability from API UserSettings. +* Add missing double quotes in test. +* GODT-2239: Unit tests for BridgeUtils.cpp in bridgepp. +* Replace go-rfc5322 with gluon's rfc5322 parser. +* GODT-2483: Install cert without external tool on macOS. + +### Fixed +* GODT-2550: Announce IMAP ID Capability. +* GODT-2574: Fix label/unlabel of large amounts of messages. +* GODT-2573: Handle invalid header fields in message. +* GODT-2573: Crash on null update. +* GODT-2407: Replace invalid email addresses with emtpy for new Drafts. + ## [Bridge 3.1.2] Quebec ### Changed * GODT-2582 Dedup recovered messages folder. - ## [Bridge 3.1.1] Quebec ### Fixed diff --git a/Makefile b/Makefile index 50b250d5..e3587b15 100644 --- a/Makefile +++ b/Makefile @@ -256,6 +256,8 @@ mocks: mockgen --package mocks github.com/ProtonMail/gluon/async PanicHandler > internal/bridge/mocks/async_mocks.go mockgen --package mocks github.com/ProtonMail/gluon/reporter Reporter > internal/bridge/mocks/gluon_mocks.go mockgen --package mocks github.com/ProtonMail/proton-bridge/v3/internal/updater Downloader,Installer > internal/updater/mocks/mocks.go + mockgen --package mocks github.com/ProtonMail/proton-bridge/v3/internal/telemetry HeartbeatManager > internal/telemetry/mocks/mocks.go + cp internal/telemetry/mocks/mocks.go internal/bridge/mocks/telemetry_mocks.go lint: gofiles lint-golang lint-license lint-dependencies lint-changelog diff --git a/go.mod b/go.mod index 1d3f7e4a..74f26400 100644 --- a/go.mod +++ b/go.mod @@ -5,10 +5,10 @@ go 1.18 require ( github.com/0xAX/notificator v0.0.0-20220220101646-ee9b8921e557 github.com/Masterminds/semver/v3 v3.2.0 - github.com/ProtonMail/gluon v0.15.1-0.20230425092028-a5ce20d22175 + github.com/ProtonMail/gluon v0.16.1-0.20230425073628-8ec759b512f1 github.com/ProtonMail/go-autostart v0.0.0-20210130080809-00ed301c8e9a - github.com/ProtonMail/go-proton-api v0.4.1-0.20230406143739-c7596e170799 - github.com/ProtonMail/gopenpgp/v2 v2.5.2 + github.com/ProtonMail/go-proton-api v0.4.1-0.20230426081144-f77778bae1be + github.com/ProtonMail/gopenpgp/v2 v2.7.1-proton github.com/PuerkitoBio/goquery v1.8.1 github.com/abiosoft/ishell v2.0.0+incompatible github.com/allan-simon/go-singleinstance v0.0.0-20210120080615-d0997106ab37 @@ -43,9 +43,9 @@ require ( github.com/vmihailenco/msgpack/v5 v5.3.5 go.uber.org/goleak v1.2.1 golang.org/x/exp v0.0.0-20230213192124-5e25df0256eb - golang.org/x/net v0.7.0 - golang.org/x/sys v0.5.0 - golang.org/x/text v0.7.0 + golang.org/x/net v0.8.0 + golang.org/x/sys v0.6.0 + golang.org/x/text v0.8.0 google.golang.org/grpc v1.53.0 google.golang.org/protobuf v1.28.1 howett.net/plist v1.0.0 @@ -55,8 +55,8 @@ require ( ariga.io/atlas v0.9.1-0.20230119145809-92243f7c55cb // indirect entgo.io/ent v0.11.8 // indirect github.com/ProtonMail/bcrypt v0.0.0-20211005172633-e235017c1baf // indirect - github.com/ProtonMail/go-crypto v0.0.0-20230217124315-7d5c6f04bbb8 // indirect - github.com/ProtonMail/go-mime v0.0.0-20221031134845-8fd9bc37cf08 // indirect + github.com/ProtonMail/go-crypto v0.0.0-20230322105811-d73448b7e800 // indirect + github.com/ProtonMail/go-mime v0.0.0-20230322103455-7d82a3887f2f // indirect github.com/ProtonMail/go-srp v0.0.5 // indirect github.com/abiosoft/readline v0.0.0-20180607040430-155bce2042db // indirect github.com/agext/levenshtein v1.2.3 // indirect @@ -116,10 +116,10 @@ require ( github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect github.com/zclconf/go-cty v1.12.1 // indirect golang.org/x/arch v0.2.0 // indirect - golang.org/x/crypto v0.6.0 // indirect + golang.org/x/crypto v0.7.0 // indirect golang.org/x/mod v0.8.0 // indirect golang.org/x/sync v0.1.0 // indirect - golang.org/x/tools v0.3.1-0.20221202221704-aa9f4b2f3d57 // indirect + golang.org/x/tools v0.6.0 // indirect google.golang.org/genproto v0.0.0-20230221151758-ace64dc21148 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index bd2f7779..c4eaef2f 100644 --- a/go.sum +++ b/go.sum @@ -28,24 +28,23 @@ github.com/ProtonMail/bcrypt v0.0.0-20211005172633-e235017c1baf h1:yc9daCCYUefEs github.com/ProtonMail/bcrypt v0.0.0-20211005172633-e235017c1baf/go.mod h1:o0ESU9p83twszAU8LBeJKFAAMX14tISa0yk4Oo5TOqo= github.com/ProtonMail/docker-credential-helpers v1.1.0 h1:+kvUIpwWcbtP3WFv5sSvkFn/XLzSqPOB5AAthuk9xPk= github.com/ProtonMail/docker-credential-helpers v1.1.0/go.mod h1:mK0aBveCxhnQ756AmaTfXMZDeULvheYVhF/MWMErN5g= -github.com/ProtonMail/gluon v0.15.1-0.20230425092028-a5ce20d22175 h1:gVTIzUcXhIyv10rAy1t+6dvMOLdEhYoF+vwXp29Wtrg= -github.com/ProtonMail/gluon v0.15.1-0.20230425092028-a5ce20d22175/go.mod h1:yA4hk6CJw0BMo+YL8Y3ckCYs5L20sysu9xseshwY3QI= +github.com/ProtonMail/gluon v0.16.1-0.20230425073628-8ec759b512f1 h1:6YTRwn95hnTymOz5g+MbikfJXYE4xGJkIgTLm0t/1w8= +github.com/ProtonMail/gluon v0.16.1-0.20230425073628-8ec759b512f1/go.mod h1:yA4hk6CJw0BMo+YL8Y3ckCYs5L20sysu9xseshwY3QI= github.com/ProtonMail/go-autostart v0.0.0-20210130080809-00ed301c8e9a h1:D+aZah+k14Gn6kmL7eKxoo/4Dr/lK3ChBcwce2+SQP4= github.com/ProtonMail/go-autostart v0.0.0-20210130080809-00ed301c8e9a/go.mod h1:oTGdE7/DlWIr23G0IKW3OXK9wZ5Hw1GGiaJFccTvZi4= github.com/ProtonMail/go-crypto v0.0.0-20210428141323-04723f9f07d7/go.mod h1:z4/9nQmJSSwwds7ejkxaJwO37dru3geImFUdJlaLzQo= -github.com/ProtonMail/go-crypto v0.0.0-20230124153114-0acdc8ae009b/go.mod h1:I0gYDMZ6Z5GRU7l58bNFSkPTFN6Yl12dsUlAZ8xy98g= -github.com/ProtonMail/go-crypto v0.0.0-20230217124315-7d5c6f04bbb8 h1:wPbRQzjjwFc0ih8puEVAOFGELsn1zoIIYdxvML7mDxA= -github.com/ProtonMail/go-crypto v0.0.0-20230217124315-7d5c6f04bbb8/go.mod h1:I0gYDMZ6Z5GRU7l58bNFSkPTFN6Yl12dsUlAZ8xy98g= +github.com/ProtonMail/go-crypto v0.0.0-20230322105811-d73448b7e800 h1:o8/VQLSiuRkkSAfVOpFCG1GnTsWxFIOPLvJ2O7hJcFg= +github.com/ProtonMail/go-crypto v0.0.0-20230322105811-d73448b7e800/go.mod h1:8TI4H3IbrackdNgv+92dI+rhpCaLqM0IfpgCgenFvRE= github.com/ProtonMail/go-message v0.0.0-20210611055058-fabeff2ec753 h1:I8IsYA297x0QLU80G5I6aLYUu3JYNSpo8j5fkXtFDW0= github.com/ProtonMail/go-message v0.0.0-20210611055058-fabeff2ec753/go.mod h1:NBAn21zgCJ/52WLDyed18YvYFm5tEoeDauubFqLokM4= -github.com/ProtonMail/go-mime v0.0.0-20221031134845-8fd9bc37cf08 h1:dS7r5z4iGS0qCjM7UwWdsEMzQesUQbGcXdSm2/tWboA= -github.com/ProtonMail/go-mime v0.0.0-20221031134845-8fd9bc37cf08/go.mod h1:qRZgbeASl2a9OwmsV85aWwRqic0NHPh+9ewGAzb4cgM= -github.com/ProtonMail/go-proton-api v0.4.1-0.20230406143739-c7596e170799 h1:slk4Drrkij1EVTnFOlIDyJsfjt69tnw8w2g1NMb253U= -github.com/ProtonMail/go-proton-api v0.4.1-0.20230406143739-c7596e170799/go.mod h1:kis4GD6FHp1ZWnenSBepldt8ai+vYalDPeey9yGwyXk= +github.com/ProtonMail/go-mime v0.0.0-20230322103455-7d82a3887f2f h1:tCbYj7/299ekTTXpdwKYF8eBlsYsDVoggDAuAjoK66k= +github.com/ProtonMail/go-mime v0.0.0-20230322103455-7d82a3887f2f/go.mod h1:gcr0kNtGBqin9zDW9GOHcVntrwnjrK+qdJ06mWYBybw= +github.com/ProtonMail/go-proton-api v0.4.1-0.20230426081144-f77778bae1be h1:TNHnEyUQDf97CRGCFWLxg7I5ASSEMO3TN2lbNw2cD6U= +github.com/ProtonMail/go-proton-api v0.4.1-0.20230426081144-f77778bae1be/go.mod h1:UkrG9gN2o9mzdx/an0XRc6a4s5Haef1A7Eyd2iXlw28= github.com/ProtonMail/go-srp v0.0.5 h1:xhUioxZgDbCnpo9JehyFhwwsn9JLWkUGfB0oiKXgiGg= github.com/ProtonMail/go-srp v0.0.5/go.mod h1:06iYHtLXW8vjLtccWj++x3MKy65sIT8yZd7nrJF49rs= -github.com/ProtonMail/gopenpgp/v2 v2.5.2 h1:97SjlWNAxXl9P22lgwgrZRshQdiEfAht0g3ZoiA1GCw= -github.com/ProtonMail/gopenpgp/v2 v2.5.2/go.mod h1:52qDaCnto6r+CoWbuU50T77XQt99lIs46HtHtvgFO3o= +github.com/ProtonMail/gopenpgp/v2 v2.7.1-proton h1:YS6M20yvjCJPR1r4ADW5TPn6rahs4iAyZaACei86bEc= +github.com/ProtonMail/gopenpgp/v2 v2.7.1-proton/go.mod h1:S1lYsaGHykYpxxh2SnJL6ypcAlANKj5NRSY6HxKryKQ= github.com/PuerkitoBio/goquery v1.8.1 h1:uQxhNlArOIdbrH1tr0UXwdVFgDcZDrZVdcpygAcwmWM= github.com/PuerkitoBio/goquery v1.8.1/go.mod h1:Q8ICL1kNUJ2sXGoAhPGUdYDJvgQgHzJsnnd3H7Ho5jQ= github.com/abiosoft/ishell v2.0.0+incompatible h1:zpwIuEHc37EzrsIYah3cpevrIc8Oma7oZPxr03tlmmw= @@ -433,12 +432,11 @@ golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.6.0 h1:qfktjS5LUO+fFKeJXZ+ikTRijMmljikvG68fpMMruSc= -golang.org/x/crypto v0.6.0/go.mod h1:OFC/31mSvZgRz0V1QTNCzfAI1aIRzbiufJtkMIlEp58= +golang.org/x/crypto v0.7.0 h1:AvwMYaRytfdeVt3u6mLaxYtErKYjxA2OXjJ1HHq6t3A= +golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= -golang.org/x/exp v0.0.0-20190731235908-ec7cb31e5a56/go.mod h1:JhuoJpWY28nO4Vef9tZUw9qufEGTyX1+7lmHxV5q5G4= golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= golang.org/x/exp v0.0.0-20230213192124-5e25df0256eb h1:PaBZQdo+iSDyHT053FjUCgZQ/9uqVwPOcl7KSWhKn6w= @@ -454,7 +452,6 @@ golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHl golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= -golang.org/x/mobile v0.0.0-20221110043201-43a038452099/go.mod h1:aAjjkJNdrh3PMckS4B10TGS2nag27cbKR1y2BpUxsiY= golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= @@ -481,8 +478,10 @@ golang.org/x/net v0.0.0-20210726213435-c6fcb2dbf985/go.mod h1:9nx3DQGgdP8bBQD5qx golang.org/x/net v0.0.0-20210916014120-12bc252f5db8/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20211029224645-99673261e6eb/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.7.0 h1:rJrUqqhjsgNp7KqAIc25s9pZnjU7TUcSY7HcVZjdn1g= +golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.8.0 h1:Zrh2ngAOFYneWTAIAPethzeaQLuHwhuBkuV6ZiRnUaQ= +golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -493,7 +492,6 @@ golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20220819030929-7fc1605a5dde/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -525,11 +523,13 @@ golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU= golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.6.0 h1:MVltZSvRTcU2ljQOhs94SXPftV6DCNnZViHeQps87pQ= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= +golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= @@ -537,8 +537,9 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5-0.20201125200606-c27b9fd57aec/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.7.0 h1:4BRB4x83lYWy72KwLD/qYDuTu7q9PjSagHvijDw7cLo= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.8.0 h1:57P1ETyNKtuIjB4SRd15iJxuhj8Gc416Y78H3qgMh68= +golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -562,8 +563,8 @@ golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtn golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.6-0.20210726203631-07bc1bf47fb2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -golang.org/x/tools v0.3.1-0.20221202221704-aa9f4b2f3d57 h1:/X0t/E4VxbZE7MLS7auvE7YICHeVvbIa9vkOVvYW/24= -golang.org/x/tools v0.3.1-0.20221202221704-aa9f4b2f3d57/go.mod h1:/rWhSS2+zyEVwoJf8YAX6L2f0ntZ7Kn/mGgAWcipA5k= +golang.org/x/tools v0.6.0 h1:BOw41kyTf3PuCW1pVQf8+Cyg8pMlkYB1oo9iJ6D/lKM= +golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/internal/app/app.go b/internal/app/app.go index 3ee0d038..16487e51 100644 --- a/internal/app/app.go +++ b/internal/app/app.go @@ -22,6 +22,7 @@ import ( "math/rand" "net/http" "net/http/cookiejar" + "net/url" "os" "path/filepath" "runtime" @@ -35,6 +36,7 @@ import ( "github.com/ProtonMail/proton-bridge/v3/internal/crash" "github.com/ProtonMail/proton-bridge/v3/internal/events" "github.com/ProtonMail/proton-bridge/v3/internal/focus" + "github.com/ProtonMail/proton-bridge/v3/internal/frontend/theme" "github.com/ProtonMail/proton-bridge/v3/internal/locations" "github.com/ProtonMail/proton-bridge/v3/internal/logging" "github.com/ProtonMail/proton-bridge/v3/internal/sentry" @@ -244,6 +246,15 @@ func run(c *cli.Context) error { } } + logrus.WithFields(logrus.Fields{ + "lastVersion": v.GetLastVersion().String(), + "showAllMail": v.GetShowAllMail(), + "updateCh": v.GetUpdateChannel(), + "autoUpdate": v.GetAutoUpdate(), + "rollout": v.GetUpdateRollout(), + "DoH": v.GetProxyAllowed(), + }).Info("Vault loaded") + // Load the cookies from the vault. return withCookieJar(v, func(cookieJar http.CookieJar) error { // Create a new bridge instance. @@ -258,6 +269,9 @@ func run(c *cli.Context) error { b.PushError(bridge.ErrVaultCorrupt) } + // Start telemetry heartbeat process + b.StartHeartbeat(b) + // Run the frontend. return runFrontend(c, crashHandler, restarter, locations, b, eventCh, quitCh, c.Int(flagParentPID)) }) @@ -417,6 +431,10 @@ func withCookieJar(vault *vault.Vault, fn func(http.CookieJar) error) error { return fmt.Errorf("could not create cookie jar: %w", err) } + if err := setDeviceCookies(persister); err != nil { + return fmt.Errorf("could not set device cookies: %w", err) + } + // Persist the cookies to the vault when we close. defer func() { logrus.Debug("Persisting cookies") @@ -428,3 +446,21 @@ func withCookieJar(vault *vault.Vault, fn func(http.CookieJar) error) error { return fn(persister) } + +func setDeviceCookies(jar *cookies.Jar) error { + url, err := url.Parse(constants.APIHost) + if err != nil { + return err + } + + for name, value := range map[string]string{ + "hhn": sentry.GetProtectedHostname(), + "tz": sentry.GetTimeZone(), + "lng": sentry.GetSystemLang(), + "clr": string(theme.DefaultTheme()), + } { + jar.SetCookies(url, []*http.Cookie{{Name: name, Value: value, Secure: true}}) + } + + return nil +} diff --git a/internal/bridge/api_qa.go b/internal/bridge/api_qa.go index db342811..6bdcd6d4 100644 --- a/internal/bridge/api_qa.go +++ b/internal/bridge/api_qa.go @@ -20,6 +20,7 @@ package bridge import ( + "crypto/tls" "net/http" "os" @@ -36,6 +37,14 @@ func newAPIOptions( transport http.RoundTripper, panicHandler async.PanicHandler, ) []proton.Option { + + if allow := os.Getenv("BRIDGE_ALLOW_PROXY"); allow != "" { + transport = &http.Transport{ + Proxy: http.ProxyFromEnvironment, + TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, + } + } + opt := defaultAPIOptions(apiURL, version, cookieJar, transport, panicHandler) if host := os.Getenv("BRIDGE_API_HOST"); host != "" { diff --git a/internal/bridge/bridge.go b/internal/bridge/bridge.go index f675cbe7..29a87b1f 100644 --- a/internal/bridge/bridge.go +++ b/internal/bridge/bridge.go @@ -41,6 +41,7 @@ import ( "github.com/ProtonMail/proton-bridge/v3/internal/focus" "github.com/ProtonMail/proton-bridge/v3/internal/safe" "github.com/ProtonMail/proton-bridge/v3/internal/sentry" + "github.com/ProtonMail/proton-bridge/v3/internal/telemetry" "github.com/ProtonMail/proton-bridge/v3/internal/user" "github.com/ProtonMail/proton-bridge/v3/internal/vault" "github.com/bradenaw/juniper/xslices" @@ -78,6 +79,9 @@ type Bridge struct { updater Updater installCh chan installJob + // heartbeat is the telemetry heartbeat for metrics. + heartbeat telemetry.Heartbeat + // curVersion is the current version of the bridge, // newVersion is the version that was installed by the updater. curVersion *semver.Version @@ -126,6 +130,9 @@ type Bridge struct { // goUpdate triggers a check/install of updates. goUpdate func() + // goHeartbeat triggers a check/sending if heartbeat is needed. + goHeartbeat func() + uidValidityGenerator imap.UIDValidityGenerator } @@ -237,6 +244,8 @@ func newBridge( return nil, fmt.Errorf("failed to save last version indicator: %w", err) } + identifier.SetClientString(vault.GetLastUserAgent()) + imapServer, err := newIMAPServer( gluonCacheDir, gluonDataDir, diff --git a/internal/bridge/bridge_test.go b/internal/bridge/bridge_test.go index b6191a3d..65939daa 100644 --- a/internal/bridge/bridge_test.go +++ b/internal/bridge/bridge_test.go @@ -49,6 +49,7 @@ import ( "github.com/ProtonMail/proton-bridge/v3/internal/vault" "github.com/ProtonMail/proton-bridge/v3/tests" "github.com/bradenaw/juniper/xslices" + imapid "github.com/emersion/go-imap-id" "github.com/emersion/go-imap/client" "github.com/stretchr/testify/require" ) @@ -170,6 +171,92 @@ func TestBridge_UserAgent(t *testing.T) { }) } +func TestBridge_UserAgent_Persistence(t *testing.T) { + withEnv(t, func(ctx context.Context, s *server.Server, netCtl *proton.NetCtl, locator bridge.Locator, vaultKey []byte) { + withBridge(ctx, t, s.GetHostURL(), netCtl, locator, vaultKey, func(b *bridge.Bridge, mocks *bridge.Mocks) { + currentUserAgent := b.GetCurrentUserAgent() + require.Contains(t, currentUserAgent, vault.DefaultUserAgent) + + imapClient, err := client.Dial(fmt.Sprintf("%v:%v", constants.Host, b.GetIMAPPort())) + require.NoError(t, err) + defer func() { _ = imapClient.Logout() }() + + idClient := imapid.NewClient(imapClient) + + // Set IMAP ID before Login to have the value capture in the Login API Call. + _, err = idClient.ID(imapid.ID{ + imapid.FieldName: "MyFancyClient", + imapid.FieldVersion: "0.1.2", + }) + + require.NoError(t, err) + + // Login the user. + _, err = b.LoginFull(context.Background(), username, password, nil, nil) + require.NoError(t, err) + + // Assert that the user agent then contains the platform. + require.Contains(t, b.GetCurrentUserAgent(), "MyFancyClient/0.1.2") + }) + + withBridge(ctx, t, s.GetHostURL(), netCtl, locator, vaultKey, func(bridge *bridge.Bridge, mocks *bridge.Mocks) { + currentUserAgent := bridge.GetCurrentUserAgent() + require.Contains(t, currentUserAgent, "MyFancyClient/0.1.2") + }) + }) +} + +func TestBridge_UserAgentFromIMAPID(t *testing.T) { + withEnv(t, func(ctx context.Context, s *server.Server, netCtl *proton.NetCtl, locator bridge.Locator, vaultKey []byte) { + var ( + calls []server.Call + lock sync.Mutex + ) + + s.AddCallWatcher(func(call server.Call) { + lock.Lock() + defer lock.Unlock() + + calls = append(calls, call) + }) + + withBridge(ctx, t, s.GetHostURL(), netCtl, locator, vaultKey, func(b *bridge.Bridge, mocks *bridge.Mocks) { + imapClient, err := client.Dial(fmt.Sprintf("%v:%v", constants.Host, b.GetIMAPPort())) + require.NoError(t, err) + defer func() { _ = imapClient.Logout() }() + + idClient := imapid.NewClient(imapClient) + + // Set IMAP ID before Login to have the value capture in the Login API Call. + _, err = idClient.ID(imapid.ID{ + imapid.FieldName: "MyFancyClient", + imapid.FieldVersion: "0.1.2", + }) + + require.NoError(t, err) + + // Login the user. + userID, err := b.LoginFull(context.Background(), username, password, nil, nil) + require.NoError(t, err) + + info, err := b.GetUserInfo(userID) + require.NoError(t, err) + require.True(t, info.State == bridge.Connected) + + require.NoError(t, imapClient.Login(info.Addresses[0], string(info.BridgePass))) + + lock.Lock() + defer lock.Unlock() + + userAgent := calls[len(calls)-1].RequestHeader.Get("User-Agent") + + // Assert that the user agent was sent to the API. + require.Contains(t, userAgent, b.GetCurrentUserAgent()) + require.Contains(t, userAgent, "MyFancyClient/0.1.2") + }) + }) +} + func TestBridge_Cookies(t *testing.T) { withEnv(t, func(ctx context.Context, s *server.Server, netCtl *proton.NetCtl, locator bridge.Locator, vaultKey []byte) { var ( @@ -736,6 +823,9 @@ func withBridgeNoMocks( require.NoError(t, err) require.Empty(t, bridge.GetErrors()) + // Start the Heartbeat process. + bridge.StartHeartbeat(mocks.Heartbeat) + // Wait for bridge to finish loading users. waitForEvent(t, eventCh, events.AllUsersLoaded{}) // Wait for bridge to start the IMAP server. diff --git a/internal/bridge/heartbeat.go b/internal/bridge/heartbeat.go new file mode 100644 index 00000000..a24fad96 --- /dev/null +++ b/internal/bridge/heartbeat.go @@ -0,0 +1,128 @@ +// Copyright (c) 2023 Proton AG +// +// This file is part of Proton Mail Bridge. +// +// Proton Mail Bridge is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Proton Mail Bridge is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Proton Mail Bridge. If not, see . + +package bridge + +import ( + "context" + "encoding/json" + "time" + + "github.com/ProtonMail/gluon/reporter" + "github.com/ProtonMail/proton-bridge/v3/internal/safe" + "github.com/ProtonMail/proton-bridge/v3/internal/telemetry" + "github.com/ProtonMail/proton-bridge/v3/internal/vault" + "github.com/ProtonMail/proton-bridge/v3/pkg/keychain" + "github.com/sirupsen/logrus" +) + +const HeartbeatCheckInterval = time.Hour + +func (bridge *Bridge) IsTelemetryAvailable() bool { + var flag = true + if bridge.GetTelemetryDisabled() { + return false + } + + safe.RLock(func() { + for _, user := range bridge.users { + flag = flag && user.IsTelemetryEnabled(context.Background()) + } + }, bridge.usersLock) + + return flag +} + +func (bridge *Bridge) SendHeartbeat(heartbeat *telemetry.HeartbeatData) bool { + data, err := json.Marshal(heartbeat) + if err != nil { + if err := bridge.reporter.ReportMessageWithContext("Cannot parse heartbeat data.", reporter.Context{ + "error": err, + }); err != nil { + logrus.WithError(err).Error("Failed to parse heartbeat data.") + } + return false + } + + var sent = false + + safe.RLock(func() { + for _, user := range bridge.users { + if err := user.SendTelemetry(context.Background(), data); err == nil { + sent = true + break + } + } + }, bridge.usersLock) + + return sent +} + +func (bridge *Bridge) GetLastHeartbeatSent() time.Time { + return bridge.vault.GetLastHeartbeatSent() +} + +func (bridge *Bridge) SetLastHeartbeatSent(timestamp time.Time) error { + return bridge.vault.SetLastHeartbeatSent(timestamp) +} + +func (bridge *Bridge) StartHeartbeat(manager telemetry.HeartbeatManager) { + bridge.heartbeat = telemetry.NewHeartbeat(manager, 1143, 1025, bridge.GetGluonCacheDir(), keychain.DefaultHelper) + + // Check for heartbeat when triggered. + bridge.goHeartbeat = bridge.tasks.PeriodicOrTrigger(HeartbeatCheckInterval, 0, func(ctx context.Context) { + logrus.Debug("Checking for heartbeat") + + bridge.heartbeat.TrySending() + }) + + bridge.heartbeat.SetRollout(bridge.GetUpdateRollout()) + bridge.heartbeat.SetAutoStart(bridge.GetAutostart()) + bridge.heartbeat.SetAutoUpdate(bridge.GetAutoUpdate()) + bridge.heartbeat.SetBeta(bridge.GetUpdateChannel()) + bridge.heartbeat.SetDoh(bridge.GetProxyAllowed()) + bridge.heartbeat.SetShowAllMail(bridge.GetShowAllMail()) + bridge.heartbeat.SetIMAPConnectionMode(bridge.GetIMAPSSL()) + bridge.heartbeat.SetSMTPConnectionMode(bridge.GetSMTPSSL()) + bridge.heartbeat.SetIMAPPort(bridge.GetIMAPPort()) + bridge.heartbeat.SetSMTPPort(bridge.GetSMTPPort()) + bridge.heartbeat.SetCacheLocation(bridge.GetGluonCacheDir()) + if val, err := bridge.GetKeychainApp(); err != nil { + bridge.heartbeat.SetKeyChainPref(val) + } else { + bridge.heartbeat.SetKeyChainPref(keychain.DefaultHelper) + } + bridge.heartbeat.SetPrevVersion(bridge.GetLastVersion().String()) + + safe.RLock(func() { + var splitMode = false + for _, user := range bridge.users { + if user.GetAddressMode() == vault.SplitMode { + splitMode = true + break + } + } + var nbAccount = len(bridge.users) + bridge.heartbeat.SetNbAccount(nbAccount) + bridge.heartbeat.SetSplitMode(splitMode) + + // Do not try to send if there is no user yet. + if nbAccount > 0 { + defer bridge.goHeartbeat() + } + }, bridge.usersLock) +} diff --git a/internal/bridge/identifier.go b/internal/bridge/identifier.go index 4cad4822..2fa46727 100644 --- a/internal/bridge/identifier.go +++ b/internal/bridge/identifier.go @@ -17,6 +17,8 @@ package bridge +import "github.com/sirupsen/logrus" + func (bridge *Bridge) GetCurrentUserAgent() string { return bridge.identifier.GetUserAgent() } @@ -24,3 +26,17 @@ func (bridge *Bridge) GetCurrentUserAgent() string { func (bridge *Bridge) SetCurrentPlatform(platform string) { bridge.identifier.SetPlatform(platform) } + +func (bridge *Bridge) setUserAgent(name, version string) { + currentUserAgent := bridge.identifier.GetClientString() + + bridge.identifier.SetClient(name, version) + + newUserAgent := bridge.identifier.GetClientString() + + if currentUserAgent != newUserAgent { + if err := bridge.vault.SetLastUserAgent(newUserAgent); err != nil { + logrus.WithError(err).Error("Failed to write new user agent to vault") + } + } +} diff --git a/internal/bridge/imap.go b/internal/bridge/imap.go index bdd51845..a5d94fe0 100644 --- a/internal/bridge/imap.go +++ b/internal/bridge/imap.go @@ -41,18 +41,16 @@ import ( "github.com/sirupsen/logrus" ) -const ( - defaultClientName = "UnknownClient" - defaultClientVersion = "0.0.1" -) - func (bridge *Bridge) serveIMAP() error { port, err := func() (int, error) { if bridge.imapServer == nil { return 0, fmt.Errorf("no IMAP server instance running") } - logrus.Info("Starting IMAP server") + logrus.WithFields(logrus.Fields{ + "port": bridge.vault.GetIMAPPort(), + "ssl": bridge.vault.GetIMAPSSL(), + }).Info("Starting IMAP server") imapListener, err := newListener(bridge.vault.GetIMAPPort(), bridge.vault.GetIMAPSSL(), bridge.tlsConfig) if err != nil { @@ -249,11 +247,6 @@ func (bridge *Bridge) handleIMAPEvent(event imapEvents.Event) { }).Info("Received mailbox message count") } - case imapEvents.SessionAdded: - if !bridge.identifier.HasClient() { - bridge.identifier.SetClient(defaultClientName, defaultClientVersion) - } - case imapEvents.IMAPID: logrus.WithFields(logrus.Fields{ "sessionID": event.SessionID, @@ -262,7 +255,7 @@ func (bridge *Bridge) handleIMAPEvent(event imapEvents.Event) { }).Info("Received IMAP ID") if event.IMAPID.Name != "" && event.IMAPID.Version != "" { - bridge.identifier.SetClient(event.IMAPID.Name, event.IMAPID.Version) + bridge.setUserAgent(event.IMAPID.Name, event.IMAPID.Version) } case imapEvents.LoginFailed: diff --git a/internal/bridge/mocks.go b/internal/bridge/mocks.go index 6f5c943f..1c7bf934 100644 --- a/internal/bridge/mocks.go +++ b/internal/bridge/mocks.go @@ -24,6 +24,7 @@ type Mocks struct { CrashHandler *mocks.MockPanicHandler Reporter *mocks.MockReporter + Heartbeat *mocks.MockHeartbeatManager } func NewMocks(tb testing.TB, version, minAuto *semver.Version) *Mocks { @@ -39,14 +40,18 @@ func NewMocks(tb testing.TB, version, minAuto *semver.Version) *Mocks { CrashHandler: mocks.NewMockPanicHandler(ctl), Reporter: mocks.NewMockReporter(ctl), + Heartbeat: mocks.NewMockHeartbeatManager(ctl), } // When getting the TLS issue channel, we want to return the test channel. mocks.TLSReporter.EXPECT().GetTLSIssueCh().Return(mocks.TLSIssueCh).AnyTimes() - // This is called at he end of any go-routine: + // This is called at the end of any go-routine: mocks.CrashHandler.EXPECT().HandlePanic(gomock.Any()).AnyTimes() + // this is called at start of heartbeat process. + mocks.Heartbeat.EXPECT().IsTelemetryAvailable().AnyTimes() + return mocks } diff --git a/internal/bridge/mocks/telemetry_mocks.go b/internal/bridge/mocks/telemetry_mocks.go new file mode 100644 index 00000000..be5251e2 --- /dev/null +++ b/internal/bridge/mocks/telemetry_mocks.go @@ -0,0 +1,92 @@ +// Code generated by MockGen. DO NOT EDIT. +// Source: github.com/ProtonMail/proton-bridge/v3/internal/telemetry (interfaces: HeartbeatManager) + +// Package mocks is a generated GoMock package. +package mocks + +import ( + reflect "reflect" + time "time" + + telemetry "github.com/ProtonMail/proton-bridge/v3/internal/telemetry" + gomock "github.com/golang/mock/gomock" +) + +// MockHeartbeatManager is a mock of HeartbeatManager interface. +type MockHeartbeatManager struct { + ctrl *gomock.Controller + recorder *MockHeartbeatManagerMockRecorder +} + +// MockHeartbeatManagerMockRecorder is the mock recorder for MockHeartbeatManager. +type MockHeartbeatManagerMockRecorder struct { + mock *MockHeartbeatManager +} + +// NewMockHeartbeatManager creates a new mock instance. +func NewMockHeartbeatManager(ctrl *gomock.Controller) *MockHeartbeatManager { + mock := &MockHeartbeatManager{ctrl: ctrl} + mock.recorder = &MockHeartbeatManagerMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockHeartbeatManager) EXPECT() *MockHeartbeatManagerMockRecorder { + return m.recorder +} + +// GetLastHeartbeatSent mocks base method. +func (m *MockHeartbeatManager) GetLastHeartbeatSent() time.Time { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetLastHeartbeatSent") + ret0, _ := ret[0].(time.Time) + return ret0 +} + +// GetLastHeartbeatSent indicates an expected call of GetLastHeartbeatSent. +func (mr *MockHeartbeatManagerMockRecorder) GetLastHeartbeatSent() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetLastHeartbeatSent", reflect.TypeOf((*MockHeartbeatManager)(nil).GetLastHeartbeatSent)) +} + +// IsTelemetryAvailable mocks base method. +func (m *MockHeartbeatManager) IsTelemetryAvailable() bool { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "IsTelemetryAvailable") + ret0, _ := ret[0].(bool) + return ret0 +} + +// IsTelemetryAvailable indicates an expected call of IsTelemetryAvailable. +func (mr *MockHeartbeatManagerMockRecorder) IsTelemetryAvailable() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "IsTelemetryAvailable", reflect.TypeOf((*MockHeartbeatManager)(nil).IsTelemetryAvailable)) +} + +// SendHeartbeat mocks base method. +func (m *MockHeartbeatManager) SendHeartbeat(arg0 *telemetry.HeartbeatData) bool { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "SendHeartbeat", arg0) + ret0, _ := ret[0].(bool) + return ret0 +} + +// SendHeartbeat indicates an expected call of SendHeartbeat. +func (mr *MockHeartbeatManagerMockRecorder) SendHeartbeat(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SendHeartbeat", reflect.TypeOf((*MockHeartbeatManager)(nil).SendHeartbeat), arg0) +} + +// SetLastHeartbeatSent mocks base method. +func (m *MockHeartbeatManager) SetLastHeartbeatSent(arg0 time.Time) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "SetLastHeartbeatSent", arg0) + ret0, _ := ret[0].(error) + return ret0 +} + +// SetLastHeartbeatSent indicates an expected call of SetLastHeartbeatSent. +func (mr *MockHeartbeatManagerMockRecorder) SetLastHeartbeatSent(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetLastHeartbeatSent", reflect.TypeOf((*MockHeartbeatManager)(nil).SetLastHeartbeatSent), arg0) +} diff --git a/internal/bridge/settings.go b/internal/bridge/settings.go index 8c262cc9..dd727316 100644 --- a/internal/bridge/settings.go +++ b/internal/bridge/settings.go @@ -46,6 +46,8 @@ func (bridge *Bridge) SetKeychainApp(helper string) error { return err } + bridge.heartbeat.SetKeyChainPref(helper) + return vault.SetHelper(vaultDir, helper) } @@ -62,6 +64,8 @@ func (bridge *Bridge) SetIMAPPort(newPort int) error { return err } + bridge.heartbeat.SetIMAPPort(newPort) + return bridge.restartIMAP() } @@ -78,6 +82,8 @@ func (bridge *Bridge) SetIMAPSSL(newSSL bool) error { return err } + bridge.heartbeat.SetIMAPConnectionMode(newSSL) + return bridge.restartIMAP() } @@ -94,6 +100,8 @@ func (bridge *Bridge) SetSMTPPort(newPort int) error { return err } + bridge.heartbeat.SetSMTPPort(newPort) + return bridge.restartSMTP() } @@ -110,6 +118,8 @@ func (bridge *Bridge) SetSMTPSSL(newSSL bool) error { return err } + bridge.heartbeat.SetSMTPConnectionMode(newSSL) + return bridge.restartSMTP() } @@ -141,6 +151,8 @@ func (bridge *Bridge) SetGluonDir(ctx context.Context, newGluonDir string) error } } + bridge.heartbeat.SetCacheLocation(newGluonDir) + gluonDataDir, err := bridge.GetGluonDataDir() if err != nil { return fmt.Errorf("failed to get Gluon Database directory: %w", err) @@ -207,6 +219,8 @@ func (bridge *Bridge) SetProxyAllowed(allowed bool) error { bridge.proxyCtl.DisallowProxy() } + bridge.heartbeat.SetDoh(allowed) + return bridge.vault.SetProxyAllowed(allowed) } @@ -220,6 +234,8 @@ func (bridge *Bridge) SetShowAllMail(show bool) error { user.SetShowAllMail(show) } + bridge.heartbeat.SetShowAllMail(show) + return bridge.vault.SetShowAllMail(show) }, bridge.usersLock) } @@ -233,6 +249,8 @@ func (bridge *Bridge) SetAutostart(autostart bool) error { if err := bridge.vault.SetAutostart(autostart); err != nil { return err } + + bridge.heartbeat.SetAutoStart(autostart) } var err error @@ -253,6 +271,10 @@ func (bridge *Bridge) SetAutostart(autostart bool) error { return err } +func (bridge *Bridge) GetUpdateRollout() float64 { + return bridge.vault.GetUpdateRollout() +} + func (bridge *Bridge) GetAutoUpdate() bool { return bridge.vault.GetAutoUpdate() } @@ -266,11 +288,28 @@ func (bridge *Bridge) SetAutoUpdate(autoUpdate bool) error { return err } + bridge.heartbeat.SetAutoUpdate(autoUpdate) + bridge.goUpdate() return nil } +func (bridge *Bridge) GetTelemetryDisabled() bool { + return bridge.vault.GetTelemetryDisabled() +} + +func (bridge *Bridge) SetTelemetryDisabled(isDisabled bool) error { + if err := bridge.vault.SetTelemetryDisabled(isDisabled); err != nil { + return err + } + // If telemetry is re-enabled locally, try to send the heartbeat. + if !isDisabled { + defer bridge.goHeartbeat() + } + return nil +} + func (bridge *Bridge) GetUpdateChannel() updater.Channel { return bridge.vault.GetUpdateChannel() } @@ -284,6 +323,8 @@ func (bridge *Bridge) SetUpdateChannel(channel updater.Channel) error { return err } + bridge.heartbeat.SetBeta(channel) + bridge.goUpdate() return nil diff --git a/internal/bridge/smtp.go b/internal/bridge/smtp.go index b6d95158..9b88b811 100644 --- a/internal/bridge/smtp.go +++ b/internal/bridge/smtp.go @@ -33,7 +33,10 @@ import ( func (bridge *Bridge) serveSMTP() error { port, err := func() (int, error) { - logrus.Info("Starting SMTP server") + logrus.WithFields(logrus.Fields{ + "port": bridge.vault.GetSMTPPort(), + "ssl": bridge.vault.GetSMTPSSL(), + }).Info("Starting SMTP server") smtpListener, err := newListener(bridge.vault.GetSMTPPort(), bridge.vault.GetSMTPSSL(), bridge.tlsConfig) if err != nil { diff --git a/internal/bridge/smtp_backend.go b/internal/bridge/smtp_backend.go index f5db750f..d48f3923 100644 --- a/internal/bridge/smtp_backend.go +++ b/internal/bridge/smtp_backend.go @@ -23,6 +23,7 @@ import ( "github.com/ProtonMail/proton-bridge/v3/internal/safe" "github.com/emersion/go-smtp" + "github.com/sirupsen/logrus" ) type smtpBackend struct { @@ -85,7 +86,7 @@ func (s *smtpSession) Rcpt(to string) error { } func (s *smtpSession) Data(r io.Reader) error { - return safe.RLockRet(func() error { + err := safe.RLockRet(func() error { user, ok := s.users[s.userID] if !ok { return ErrNoSuchUser @@ -93,4 +94,10 @@ func (s *smtpSession) Data(r io.Reader) error { return user.SendMail(s.authID, s.from, s.to, r) }, s.usersLock) + + if err != nil { + logrus.WithField("pkg", "smtp").WithError(err).Error("Send mail failed.") + } + + return err } diff --git a/internal/bridge/types.go b/internal/bridge/types.go index 3e779817..958f19a3 100644 --- a/internal/bridge/types.go +++ b/internal/bridge/types.go @@ -38,6 +38,8 @@ type Identifier interface { HasClient() bool SetClient(name, version string) SetPlatform(platform string) + SetClientString(client string) + GetClientString() string } type ProxyController interface { diff --git a/internal/bridge/user.go b/internal/bridge/user.go index 5f2a2f1e..526850b1 100644 --- a/internal/bridge/user.go +++ b/internal/bridge/user.go @@ -295,6 +295,15 @@ func (bridge *Bridge) SetAddressMode(ctx context.Context, userID string, mode va AddressMode: mode, }) + var splitMode = false + for _, user := range bridge.users { + if user.GetAddressMode() == vault.SplitMode { + splitMode = true + break + } + } + bridge.heartbeat.SetSplitMode(splitMode) + return nil }, bridge.usersLock) } @@ -399,7 +408,7 @@ func (bridge *Bridge) loadUsers(ctx context.Context) error { return nil } - log.Info("Loading connected user") + log.WithField("mode", user.AddressMode()).Info("Loading connected user") bridge.publish(events.UserLoading{ UserID: user.UserID(), @@ -550,7 +559,7 @@ func (bridge *Bridge) addUserWithVault( // As such, if we find this ID in the context, we should use it to update our user agent. client.AddPreRequestHook(func(_ *resty.Client, r *resty.Request) error { if imapID, ok := imap.GetIMAPIDFromContext(r.Context()); ok { - bridge.identifier.SetClient(imapID.Name, imapID.Version) + bridge.setUserAgent(imapID.Name, imapID.Version) } return nil @@ -559,8 +568,12 @@ func (bridge *Bridge) addUserWithVault( // Finally, save the user in the bridge. safe.Lock(func() { bridge.users[apiUser.ID] = user + bridge.heartbeat.SetNbAccount(len(bridge.users)) }, bridge.usersLock) + // As we need at least one user to send heartbeat, try to send it. + defer bridge.goHeartbeat() + return nil } @@ -614,6 +627,8 @@ func (bridge *Bridge) logoutUser(ctx context.Context, user *user.User, withAPI, logrus.WithError(err).Error("Failed to logout user") } + bridge.heartbeat.SetNbAccount(len(bridge.users)) + user.Close() } diff --git a/internal/bridge/user_event_test.go b/internal/bridge/user_event_test.go index 2cc777d2..fa69ea1f 100644 --- a/internal/bridge/user_event_test.go +++ b/internal/bridge/user_event_test.go @@ -451,6 +451,65 @@ func TestBridge_User_DropConn_NoBadEvent(t *testing.T) { }, server.WithListener(dropListener)) } +func TestBridge_User_UpdateDraft(t *testing.T) { + withEnv(t, func(ctx context.Context, s *server.Server, netCtl *proton.NetCtl, locator bridge.Locator, storeKey []byte) { + // Create a bridge user. + _, _, err := s.CreateUser("user", password) + require.NoError(t, err) + + // Initially sync the user. + withBridge(ctx, t, s.GetHostURL(), netCtl, locator, storeKey, func(bridge *bridge.Bridge, mocks *bridge.Mocks) { + userLoginAndSync(ctx, t, bridge, "user", password) + }) + + withClient(ctx, t, s, "user", password, func(ctx context.Context, c *proton.Client) { + user, err := c.GetUser(ctx) + require.NoError(t, err) + + addrs, err := c.GetAddresses(ctx) + require.NoError(t, err) + + salts, err := c.GetSalts(ctx) + require.NoError(t, err) + + keyPass, err := salts.SaltForKey(password, user.Keys.Primary().ID) + require.NoError(t, err) + + _, addrKRs, err := proton.Unlock(user, addrs, keyPass, async.NoopPanicHandler{}) + require.NoError(t, err) + + // Create a draft (generating a "create draft message" event). + draft, err := c.CreateDraft(ctx, addrKRs[addrs[0].ID], proton.CreateDraftReq{ + Message: proton.DraftTemplate{ + Subject: "subject", + Sender: &mail.Address{Name: "sender", Address: addrs[0].Email}, + Body: "body", + MIMEType: rfc822.TextPlain, + }, + }) + require.NoError(t, err) + require.Empty(t, draft.ReplyTos) + + // Process those events + withBridge(ctx, t, s.GetHostURL(), netCtl, locator, storeKey, func(bridge *bridge.Bridge, mocks *bridge.Mocks) { + userContinueEventProcess(ctx, t, s, bridge) + }) + + // Update the draft (generating an "update draft message" event). + draft2, err := c.UpdateDraft(ctx, draft.ID, addrKRs[addrs[0].ID], proton.UpdateDraftReq{ + Message: proton.DraftTemplate{ + Subject: "subject 2", + Sender: &mail.Address{Name: "sender", Address: addrs[0].Email}, + Body: "body 2", + MIMEType: rfc822.TextPlain, + }, + }) + require.NoError(t, err) + require.Empty(t, draft2.ReplyTos) + }) + }) +} + func TestBridge_User_UpdateDraftAndCreateOtherMessage(t *testing.T) { withEnv(t, func(ctx context.Context, s *server.Server, netCtl *proton.NetCtl, locator bridge.Locator, storeKey []byte) { // Create a bridge user. @@ -784,6 +843,48 @@ func TestBridge_User_HandleParentLabelRename(t *testing.T) { }) } +// TBD: GODT-2527. +func _TestBridge503DuringEventDoesNotCauseBadEvent(t *testing.T) { //nolint:unused,deadcode + withEnv(t, func(ctx context.Context, s *server.Server, netCtl *proton.NetCtl, locator bridge.Locator, storeKey []byte) { + // Create a user. + userID, addrID, err := s.CreateUser("user", password) + require.NoError(t, err) + + labelID, err := s.CreateLabel(userID, "folder", "", proton.LabelTypeFolder) + require.NoError(t, err) + + // Create 10 messages for the user. + withClient(ctx, t, s, "user", password, func(ctx context.Context, c *proton.Client) { + createNumMessages(ctx, t, c, addrID, labelID, 10) + }) + + withBridge(ctx, t, s.GetHostURL(), netCtl, locator, storeKey, func(bridge *bridge.Bridge, mocks *bridge.Mocks) { + userLoginAndSync(ctx, t, bridge, "user", password) + + var messageIDs []string + + // Create 10 more messages for the user, generating events. + withClient(ctx, t, s, "user", password, func(ctx context.Context, c *proton.Client) { + messageIDs = createNumMessages(ctx, t, c, addrID, labelID, 10) + }) + + mocks.Reporter.EXPECT().ReportMessageWithContext(gomock.Any(), gomock.Any()).MinTimes(1) + + s.AddStatusHook(func(req *http.Request) (int, bool) { + if xslices.Index(xslices.Map(messageIDs[0:5], func(messageID string) string { + return "/mail/v4/messages/" + messageID + }), req.URL.Path) < 0 { + return 0, false + } + + return http.StatusServiceUnavailable, true + }) + + userContinueEventProcess(ctx, t, s, bridge) + }) + }) +} + // userLoginAndSync logs in user and waits until user is fully synced. func userLoginAndSync( ctx context.Context, diff --git a/internal/certs/cert_store_darwin.go b/internal/certs/cert_store_darwin.go index c034adec..8e1f9570 100644 --- a/internal/certs/cert_store_darwin.go +++ b/internal/certs/cert_store_darwin.go @@ -17,69 +17,141 @@ package certs -import ( - "os" +/* +#cgo CFLAGS: -x objective-c +#cgo LDFLAGS: -framework Foundation -framework Security +#import +#import - "golang.org/x/sys/execabs" + +int installTrustedCert(char const *bytes, unsigned long long length) { + if (length == 0) { + return errSecInvalidData; + } + + NSData *der = [NSData dataWithBytes:bytes length:length]; + + // Step 1. Import the certificate in the keychain. + SecCertificateRef cert = SecCertificateCreateWithData(NULL, (CFDataRef) der); + NSDictionary* addQuery = @{ + (id)kSecValueRef: (__bridge id) cert, + (id)kSecClass: (id)kSecClassCertificate, + }; + + OSStatus status = SecItemAdd((__bridge CFDictionaryRef) addQuery, NULL); + if ((errSecSuccess != status) && (errSecDuplicateItem != status)) { + CFRelease(cert); + return status; + } + + // Step 2. Set the trust for the certificate. + SecPolicyRef policy = SecPolicyCreateSSL(true, NULL); // we limit our trust to SSL + NSDictionary *trustSettings = @{ + (id)kSecTrustSettingsResult: [NSNumber numberWithInt:kSecTrustSettingsResultTrustRoot], + (id)kSecTrustSettingsPolicy: (__bridge id) policy, + }; + status = SecTrustSettingsSetTrustSettings(cert, kSecTrustSettingsDomainAdmin, (__bridge CFTypeRef)(trustSettings)); + CFRelease(policy); + CFRelease(cert); + + return status; +} + + +int removeTrustedCert(char const *bytes, unsigned long long length) { + if (0 == length) { + return errSecInvalidData; + } + + NSData *der = [NSData dataWithBytes: bytes length: length]; + SecCertificateRef cert = SecCertificateCreateWithData(NULL, (CFDataRef) der); + + // Step 1. Unset the trust for the certificate. + SecPolicyRef policy = SecPolicyCreateSSL(true, NULL); + NSDictionary * trustSettings = @{ + (id)kSecTrustSettingsResult: [NSNumber numberWithInt:kSecTrustSettingsResultUnspecified], + (id)kSecTrustSettingsPolicy: (__bridge id) policy, + }; + OSStatus status = SecTrustSettingsSetTrustSettings(cert, kSecTrustSettingsDomainAdmin, (__bridge CFTypeRef)(trustSettings)); + CFRelease(policy); + if (errSecSuccess != status) { + CFRelease(cert); + return status; + } + + // Step 2. Remove the certificate from the keychain. + NSDictionary *query = @{ (id)kSecClass: (id)kSecClassCertificate, + (id)kSecMatchItemList: @[(__bridge id)cert], + (id)kSecMatchLimit: (id)kSecMatchLimitOne, + }; + status = SecItemDelete((__bridge CFDictionaryRef) query); + + CFRelease(cert); + return status; +} +*/ +import "C" + +import ( + "encoding/pem" + "errors" + "fmt" + "unsafe" ) +// some of the error codes returned by Apple's Security framework. +const ( + errSecSuccess = 0 + errAuthorizationCanceled = -60006 +) + +// certPEMToDER converts a certificate in PEM format to DER format, which is the format required by Apple's Security framework. +func certPEMToDER(certPEM []byte) ([]byte, error) { + + block, left := pem.Decode(certPEM) + if block == nil { + return []byte{}, errors.New("invalid PEM certificate") + } + + if len(left) > 0 { + return []byte{}, errors.New("trailing data found at the end of a PEM certificate") + } + + return block.Bytes, nil +} + func installCert(certPEM []byte) error { - name, err := writeToTempFile(certPEM) + certDER, err := certPEMToDER(certPEM) if err != nil { return err } - return addTrustedCert(name) + p := C.CBytes(certDER) + defer C.free(unsafe.Pointer(p)) + + errCode := C.installTrustedCert((*C.char)(p), (C.ulonglong)(len(certDER))) + switch errCode { + case errSecSuccess: + return nil + case errAuthorizationCanceled: + return fmt.Errorf("the user cancelled the authorization dialog") + default: + return fmt.Errorf("could not install certification into keychain (error %v)", errCode) + } } func uninstallCert(certPEM []byte) error { - name, err := writeToTempFile(certPEM) + certDER, err := certPEMToDER(certPEM) if err != nil { return err } - return removeTrustedCert(name) -} + p := C.CBytes(certDER) + defer C.free(unsafe.Pointer(p)) -func addTrustedCert(certPath string) error { - return execabs.Command( //nolint:gosec - "/usr/bin/security", - "execute-with-privileges", - "/usr/bin/security", - "add-trusted-cert", - "-d", - "-r", "trustRoot", - "-p", "ssl", - "-k", "/Library/Keychains/System.keychain", - certPath, - ).Run() -} - -func removeTrustedCert(certPath string) error { - return execabs.Command( //nolint:gosec - "/usr/bin/security", - "execute-with-privileges", - "/usr/bin/security", - "remove-trusted-cert", - "-d", - certPath, - ).Run() -} - -// writeToTempFile writes the given data to a temporary file and returns the path. -func writeToTempFile(data []byte) (string, error) { - f, err := os.CreateTemp("", "tls") - if err != nil { - return "", err + if errCode := C.removeTrustedCert((*C.char)(p), (C.ulonglong)(len(certDER))); errCode != 0 { + return fmt.Errorf("could not install certificate from keychain (error %v)", errCode) } - if _, err := f.Write(data); err != nil { - return "", err - } - - if err := f.Close(); err != nil { - return "", err - } - - return f.Name(), nil + return nil } diff --git a/internal/certs/cert_store_darwin_test.go b/internal/certs/cert_store_darwin_test.go new file mode 100644 index 00000000..9ac9c698 --- /dev/null +++ b/internal/certs/cert_store_darwin_test.go @@ -0,0 +1,44 @@ +// Copyright (c) 2023 Proton AG +// +// This file is part of Proton Mail Bridge. +// +// Proton Mail Bridge is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Proton Mail Bridge is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Proton Mail Bridge. If not, see . + +//go:build darwin + +package certs + +import ( + "testing" + + "github.com/stretchr/testify/require" +) + +// This test implies human interactions to enter password and is disabled by default. +func _TestTrustedCertsDarwin(t *testing.T) { + template, err := NewTLSTemplate() + require.NoError(t, err) + + certPEM, _, err := GenerateCert(template) + require.NoError(t, err) + + require.Error(t, installCert([]byte{0})) // Cannot install an invalid cert. + require.Error(t, uninstallCert(certPEM)) // Cannot uninstall a cert that is not installed. + require.NoError(t, installCert(certPEM)) // Can install a valid cert. + require.NoError(t, installCert(certPEM)) // Can install an already installed cert. + require.NoError(t, uninstallCert(certPEM)) // Can uninstall an installed cert. + require.Error(t, uninstallCert(certPEM)) // Cannot uninstall an already uninstalled cert. + require.NoError(t, installCert(certPEM)) // Can reinstall an uninstalled cert. + require.NoError(t, uninstallCert(certPEM)) // Can uninstall a reinstalled cert. +} diff --git a/internal/frontend/bridge-gui/bridge-gui-tester/GRPCQtProxy.cpp b/internal/frontend/bridge-gui/bridge-gui-tester/GRPCQtProxy.cpp index ecd8e38d..205e0bbd 100644 --- a/internal/frontend/bridge-gui/bridge-gui-tester/GRPCQtProxy.cpp +++ b/internal/frontend/bridge-gui/bridge-gui-tester/GRPCQtProxy.cpp @@ -39,6 +39,7 @@ void GRPCQtProxy::connectSignals() { connect(this, &GRPCQtProxy::setIsAutostartOnReceived, &settingsTab, &SettingsTab::setIsAutostartOn); connect(this, &GRPCQtProxy::setIsBetaEnabledReceived, &settingsTab, &SettingsTab::setIsBetaEnabled); connect(this, &GRPCQtProxy::setIsAllMailVisibleReceived, &settingsTab, &SettingsTab::setIsAllMailVisible); + connect(this, &GRPCQtProxy::setIsTelemetryDisabledReceived, &settingsTab, &SettingsTab::setIsTelemetryDisabled); connect(this, &GRPCQtProxy::setColorSchemeNameReceived, &settingsTab, &SettingsTab::setColorSchemeName); connect(this, &GRPCQtProxy::reportBugReceived, &settingsTab, &SettingsTab::setBugReport); connect(this, &GRPCQtProxy::exportTLSCertificatesReceived, &settingsTab, &SettingsTab::exportTLSCertificates); @@ -89,6 +90,13 @@ void GRPCQtProxy::setIsAllMailVisible(bool visible) { } +//**************************************************************************************************************************************************** +/// \param[in] isDisabled Is telemetry disabled? +//**************************************************************************************************************************************************** +void GRPCQtProxy::setIsTelemetryDisabled(bool isDisabled) { + emit setIsTelemetryDisabledReceived(isDisabled); +} + //**************************************************************************************************************************************************** /// \param[in] name The color scheme. //**************************************************************************************************************************************************** diff --git a/internal/frontend/bridge-gui/bridge-gui-tester/GRPCQtProxy.h b/internal/frontend/bridge-gui/bridge-gui-tester/GRPCQtProxy.h index 783cee0b..2f799eae 100644 --- a/internal/frontend/bridge-gui/bridge-gui-tester/GRPCQtProxy.h +++ b/internal/frontend/bridge-gui/bridge-gui-tester/GRPCQtProxy.h @@ -41,6 +41,7 @@ public: // member functions. void setIsAutostartOn(bool on); ///< Forwards a SetIsAutostartOn call via a Qt signal. void setIsBetaEnabled(bool enabled); ///< Forwards a SetIsBetaEnabled call via a Qt signal. void setIsAllMailVisible(bool visible); ///< Forwards a SetIsAllMailVisible call via a Qt signal. + void setIsTelemetryDisabled(bool isDisabled); ///< Forwards a SetIsTelemetryDisabled call via a Qt signal. void setColorSchemeName(QString const &name); ///< Forward a SetColorSchemeName call via a Qt Signal void reportBug(QString const &osType, QString const &osVersion, QString const &emailClient, QString const &address, QString const &description, bool includeLogs); ///< Forwards a ReportBug call via a Qt signal. @@ -62,6 +63,7 @@ signals: void setIsAutostartOnReceived(bool on); ///< Forwards a SetIsAutostartOn call via a Qt signal. void setIsBetaEnabledReceived(bool enabled); ///< Forwards a SetIsBetaEnabled call via a Qt signal. void setIsAllMailVisibleReceived(bool enabled); ///< Forwards a SetIsBetaEnabled call via a Qt signal. + void setIsTelemetryDisabledReceived(bool isDisabled); ///< Forwards a SetIsTelemetryDisabled call via a Qt signal. void setColorSchemeNameReceived(QString const &name); ///< Forward a SetColorScheme call via a Qt Signal void reportBugReceived(QString const &osType, QString const &osVersion, QString const &emailClient, QString const &address, QString const &description, bool includeLogs); ///< Signal for the ReportBug gRPC call diff --git a/internal/frontend/bridge-gui/bridge-gui-tester/GRPCService.cpp b/internal/frontend/bridge-gui/bridge-gui-tester/GRPCService.cpp index 74682adf..a0833b4c 100644 --- a/internal/frontend/bridge-gui/bridge-gui-tester/GRPCService.cpp +++ b/internal/frontend/bridge-gui/bridge-gui-tester/GRPCService.cpp @@ -192,6 +192,28 @@ Status GRPCService::IsAllMailVisible(ServerContext *, Empty const *request, Bool } +//**************************************************************************************************************************************************** +/// \param[in] request The request. +/// \return The status for the call. +//**************************************************************************************************************************************************** +grpc::Status GRPCService::SetIsTelemetryDisabled(::grpc::ServerContext *, ::google::protobuf::BoolValue const *request, ::google::protobuf::Empty *) { + app().log().debug(__FUNCTION__); + qtProxy_.setIsTelemetryDisabledReceived(request->value()); + return Status::OK; +} + + +//**************************************************************************************************************************************************** +/// \param[out] response The response. +/// \return The status for the call. +//**************************************************************************************************************************************************** +grpc::Status GRPCService::IsTelemetryDisabled(::grpc::ServerContext *, ::google::protobuf::Empty const *, ::google::protobuf::BoolValue *response) { + app().log().debug(__FUNCTION__); + response->set_value(app().mainWindow().settingsTab().isTelemetryDisabled()); + return Status::OK; +} + + //**************************************************************************************************************************************************** /// \return The status for the call. //**************************************************************************************************************************************************** @@ -820,3 +842,4 @@ void GRPCService::finishLogin() { qtProxy_.sendDelayedEvent(newLoginFinishedEvent(user->id(), alreadyExist)); } + diff --git a/internal/frontend/bridge-gui/bridge-gui-tester/GRPCService.h b/internal/frontend/bridge-gui/bridge-gui-tester/GRPCService.h index 0c03809b..da5aa6c2 100644 --- a/internal/frontend/bridge-gui/bridge-gui-tester/GRPCService.h +++ b/internal/frontend/bridge-gui/bridge-gui-tester/GRPCService.h @@ -51,6 +51,8 @@ public: // member functions. grpc::Status IsBetaEnabled(::grpc::ServerContext *, ::google::protobuf::Empty const *, ::google::protobuf::BoolValue *response) override; grpc::Status SetIsAllMailVisible(::grpc::ServerContext *context, ::google::protobuf::BoolValue const *request, ::google::protobuf::Empty *response) override; grpc::Status IsAllMailVisible(::grpc::ServerContext *context, ::google::protobuf::Empty const *request, ::google::protobuf::BoolValue *response) override; + grpc::Status SetIsTelemetryDisabled(::grpc::ServerContext *, ::google::protobuf::BoolValue const *request, ::google::protobuf::Empty *response) override; + grpc::Status IsTelemetryDisabled(::grpc::ServerContext *, ::google::protobuf::Empty const *request, ::google::protobuf::BoolValue *response) override; grpc::Status TriggerReset(::grpc::ServerContext *, ::google::protobuf::Empty const *, ::google::protobuf::Empty *) override; grpc::Status Version(::grpc::ServerContext *, ::google::protobuf::Empty const *, ::google::protobuf::StringValue *response) override; grpc::Status LogsPath(::grpc::ServerContext *, ::google::protobuf::Empty const *, ::google::protobuf::StringValue *response) override; diff --git a/internal/frontend/bridge-gui/bridge-gui-tester/Tabs/SettingsTab.cpp b/internal/frontend/bridge-gui/bridge-gui-tester/Tabs/SettingsTab.cpp index e22d1055..a3d56a5a 100644 --- a/internal/frontend/bridge-gui/bridge-gui-tester/Tabs/SettingsTab.cpp +++ b/internal/frontend/bridge-gui/bridge-gui-tester/Tabs/SettingsTab.cpp @@ -202,6 +202,22 @@ void SettingsTab::setIsAllMailVisible(bool visible) { } +//**************************************************************************************************************************************************** +/// \return the value for the 'Disabled Telemetry' check. +//**************************************************************************************************************************************************** +bool SettingsTab::isTelemetryDisabled() const { + return ui_.checkIsTelemetryDisabled->isChecked(); +} + + +//**************************************************************************************************************************************************** +/// \param[in] isDisabled The new value for the 'Disable Telemetry' check box. +//**************************************************************************************************************************************************** +void SettingsTab::setIsTelemetryDisabled(bool isDisabled) { + ui_.checkIsTelemetryDisabled->setChecked(isDisabled); +} + + //**************************************************************************************************************************************************** /// \return The delay to apply before sending automatically generated events. //**************************************************************************************************************************************************** diff --git a/internal/frontend/bridge-gui/bridge-gui-tester/Tabs/SettingsTab.h b/internal/frontend/bridge-gui/bridge-gui-tester/Tabs/SettingsTab.h index 6dc4074d..2d082fc8 100644 --- a/internal/frontend/bridge-gui/bridge-gui-tester/Tabs/SettingsTab.h +++ b/internal/frontend/bridge-gui/bridge-gui-tester/Tabs/SettingsTab.h @@ -45,6 +45,7 @@ public: // member functions. bool isAutostartOn() const; ///< Get the value for the 'Autostart' check. bool isBetaEnabled() const; ///< Get the value for the 'Beta Enabled' check. bool isAllMailVisible() const; ///< Get the value for the 'All Mail Visible' check. + bool isTelemetryDisabled() const; ///< Get the value for the 'Disable Telemetry' check box. QString colorSchemeName() const; ///< Get the value of the 'Use Dark Theme' checkbox. qint32 eventDelayMs() const; ///< Get the delay for sending automatically generated events. QString logsPath() const; ///< Get the content of the 'Logs Path' edit. @@ -74,6 +75,7 @@ public slots: void setIsAutostartOn(bool on); ///< Set the value for the 'Autostart' check box. void setIsBetaEnabled(bool enabled); ///< Set the value for the 'Beta Enabled' check box. void setIsAllMailVisible(bool visible); ///< Set the value for the 'All Mail Visible' check box. + void setIsTelemetryDisabled(bool isDisabled); ///< Set the value for the 'Disable Telemetry' check box. void setColorSchemeName(QString const &name); ///< Set the value for the 'Use Dark Theme' check box. void setBugReport(QString const &osType, QString const &osVersion, QString const &emailClient, QString const &address, QString const &description, bool includeLogs); ///< Set the content of the bug report box. diff --git a/internal/frontend/bridge-gui/bridge-gui-tester/Tabs/SettingsTab.ui b/internal/frontend/bridge-gui/bridge-gui-tester/Tabs/SettingsTab.ui index c83bc278..7fb5b74e 100644 --- a/internal/frontend/bridge-gui/bridge-gui-tester/Tabs/SettingsTab.ui +++ b/internal/frontend/bridge-gui/bridge-gui-tester/Tabs/SettingsTab.ui @@ -170,6 +170,13 @@ + + + + Disable Telemetry + + + diff --git a/internal/frontend/bridge-gui/bridge-gui/CMakeLists.txt b/internal/frontend/bridge-gui/bridge-gui/CMakeLists.txt index e491356f..77f06e49 100644 --- a/internal/frontend/bridge-gui/bridge-gui/CMakeLists.txt +++ b/internal/frontend/bridge-gui/bridge-gui/CMakeLists.txt @@ -114,6 +114,7 @@ add_executable(bridge-gui EventStreamWorker.cpp EventStreamWorker.h LogUtils.cpp LogUtils.h main.cpp + TrayIcon.cpp TrayIcon.h Pch.h QMLBackend.cpp QMLBackend.h UserList.cpp UserList.h diff --git a/internal/frontend/bridge-gui/bridge-gui/QMLBackend.cpp b/internal/frontend/bridge-gui/bridge-gui/QMLBackend.cpp index 5671245a..2435426c 100644 --- a/internal/frontend/bridge-gui/bridge-gui/QMLBackend.cpp +++ b/internal/frontend/bridge-gui/bridge-gui/QMLBackend.cpp @@ -24,7 +24,6 @@ #include #include #include -#include #define HANDLE_EXCEPTION(x) try { x } \ @@ -50,6 +49,9 @@ QMLBackend::QMLBackend() /// \param[in] serviceConfig //**************************************************************************************************************************************************** void QMLBackend::init(GRPCConfig const &serviceConfig) { + trayIcon_.reset(new TrayIcon()); + this->setNormalTrayIcon(); + connect(this, &QMLBackend::fatalError, &app(), &AppController::onFatalError); users_ = new UserList(this); @@ -100,6 +102,14 @@ bool QMLBackend::waitForEventStreamReaderToFinish(qint32 timeoutMs) { } +//**************************************************************************************************************************************************** +/// \return The list of users +//**************************************************************************************************************************************************** +UserList const &QMLBackend::users() const { + return *users_; +} + + //**************************************************************************************************************************************************** /// \return The build year as a string (e.g. 2023) //**************************************************************************************************************************************************** @@ -335,6 +345,18 @@ bool QMLBackend::isAllMailVisible() const { } +//**************************************************************************************************************************************************** +/// \return The value for the 'isAllMailVisible' property. +//**************************************************************************************************************************************************** +bool QMLBackend::isTelemetryDisabled() const { + HANDLE_EXCEPTION_RETURN_BOOL( + bool v; + app().grpc().isTelemetryDisabled(v); + return v; + ) +} + + //**************************************************************************************************************************************************** /// \return The value for the 'colorSchemeName' property. //**************************************************************************************************************************************************** @@ -569,6 +591,17 @@ void QMLBackend::changeIsAllMailVisible(bool isVisible) { } +//**************************************************************************************************************************************************** +/// \param[in] isDisabled The new state of the 'Is telemetry disabled property'. +//**************************************************************************************************************************************************** +void QMLBackend::toggleIsTelemetryDisabled(bool isDisabled) { + HANDLE_EXCEPTION( + app().grpc().setIsTelemetryDisabled(isDisabled); + emit isTelemetryDisabledChanged(isDisabled); + ) +} + + //**************************************************************************************************************************************************** /// \param[in] scheme the scheme name //**************************************************************************************************************************************************** @@ -838,6 +871,49 @@ void QMLBackend::sendBadEventUserFeedback(QString const &userID, bool doResync) } +//**************************************************************************************************************************************************** +// +//**************************************************************************************************************************************************** +void QMLBackend::setNormalTrayIcon() { + if (trayIcon_) { + trayIcon_->setState(TrayIcon::State::Normal, tr("Connected"), ":/qml/icons/ic-connected.svg"); + } +} + + +//**************************************************************************************************************************************************** +/// \param[in] stateString A string describing the state. +/// \param[in] statusIcon The path of the status icon. +//**************************************************************************************************************************************************** +void QMLBackend::setErrorTrayIcon(QString const &stateString, QString const &statusIcon) { + if (trayIcon_) { + trayIcon_->setState(TrayIcon::State::Error, stateString, statusIcon); + } +} + + +//**************************************************************************************************************************************************** +/// \param[in] stateString A string describing the state. +/// \param[in] statusIcon The path of the status icon. +//**************************************************************************************************************************************************** +void QMLBackend::setWarnTrayIcon(QString const &stateString, QString const &statusIcon) { + if (trayIcon_) { + trayIcon_->setState(TrayIcon::State::Warn, stateString, statusIcon); + } +} + + +//**************************************************************************************************************************************************** +/// \param[in] stateString A string describing the state. +/// \param[in] statusIcon The path of the status icon. +//**************************************************************************************************************************************************** +void QMLBackend::setUpdateTrayIcon(QString const &stateString, QString const &statusIcon) { + if (trayIcon_) { + trayIcon_->setState(TrayIcon::State::Update, stateString, statusIcon); + } +} + + //**************************************************************************************************************************************************** /// \param[in] imapPort The IMAP port. /// \param[in] smtpPort The SMTP port. @@ -892,7 +968,7 @@ void QMLBackend::onLoginAlreadyLoggedIn(QString const &userID) { //**************************************************************************************************************************************************** /// \param[in] userID The userID. //**************************************************************************************************************************************************** -void QMLBackend::onUserBadEvent(QString const &userID, QString const& ) { +void QMLBackend::onUserBadEvent(QString const &userID, QString const &) { HANDLE_EXCEPTION( if (badEventDisplayQueue_.contains(userID)) { app().log().error("Received 'bad event' for a user that is already in the queue."); @@ -921,8 +997,9 @@ void QMLBackend::onIMAPLoginFailed(QString const &username) { if ((!user) || (user->state() != UserState::SignedOut)) { // We want to pop-up only if a signed-out user has been detected return; } - if (user->isInIMAPLoginFailureCooldown()) + if (user->isInIMAPLoginFailureCooldown()) { return; + } user->startImapLoginFailureCooldown(60 * 60 * 1000); // 1 hour cooldown during which we will not display this notification to this user again. emit selectUser(user->id()); emit imapLoginWhileSignedOut(username); diff --git a/internal/frontend/bridge-gui/bridge-gui/QMLBackend.h b/internal/frontend/bridge-gui/bridge-gui/QMLBackend.h index 80754c6f..afde837e 100644 --- a/internal/frontend/bridge-gui/bridge-gui/QMLBackend.h +++ b/internal/frontend/bridge-gui/bridge-gui/QMLBackend.h @@ -22,6 +22,7 @@ #include "MacOS/DockIcon.h" #include "BuildConfig.h" +#include "TrayIcon.h" #include "UserList.h" #include #include @@ -43,6 +44,7 @@ public: // member functions. QMLBackend &operator=(QMLBackend &&) = delete; ///< Disabled move assignment operator. void init(GRPCConfig const &serviceConfig); ///< Initialize the backend. bool waitForEventStreamReaderToFinish(qint32 timeoutMs); ///< Wait for the event stream reader to finish. + UserList const& users() const; ///< Return the list of users // invokable methods can be called from QML. They generally return a value, which slots cannot do. Q_INVOKABLE static QString buildYear(); ///< Return the application build year. @@ -67,6 +69,7 @@ public: // Qt/QML properties. Note that the NOTIFY-er signal is required even fo Q_PROPERTY(bool isAutostartOn READ isAutostartOn NOTIFY isAutostartOnChanged) Q_PROPERTY(bool isBetaEnabled READ isBetaEnabled NOTIFY isBetaEnabledChanged) Q_PROPERTY(bool isAllMailVisible READ isAllMailVisible NOTIFY isAllMailVisibleChanged) + Q_PROPERTY(bool isTelemetryDisabled READ isTelemetryDisabled NOTIFY isTelemetryDisabledChanged) Q_PROPERTY(QString colorSchemeName READ colorSchemeName NOTIFY colorSchemeNameChanged) Q_PROPERTY(QUrl diskCachePath READ diskCachePath NOTIFY diskCachePathChanged) Q_PROPERTY(bool useSSLForIMAP READ useSSLForIMAP WRITE setUseSSLForIMAP NOTIFY useSSLForIMAPChanged) @@ -99,6 +102,7 @@ public: // Qt/QML properties. Note that the NOTIFY-er signal is required even fo bool isAutostartOn() const; ///< Getter for the 'isAutostartOn' property. bool isBetaEnabled() const; ///< Getter for the 'isBetaEnabled' property. bool isAllMailVisible() const; ///< Getter for the 'isAllMailVisible' property. + bool isTelemetryDisabled() const; ///< Getter for the 'isTelemetryDisabled' property. QString colorSchemeName() const; ///< Getter for the 'colorSchemeName' property. QUrl diskCachePath() const; ///< Getter for the 'diskCachePath' property. void setUseSSLForIMAP(bool value); ///< Setter for the 'useSSLForIMAP' property. @@ -129,6 +133,7 @@ signals: // Signal used by the Qt property system. Many of them are unused but r void isAutomaticUpdateOnChanged(bool value); /// To be forwarded to Bridge void toggleAutostart(bool active); ///< Slot for the autostart toggle. void toggleBeta(bool active); ///< Slot for the beta toggle. void changeIsAllMailVisible(bool isVisible); ///< Slot for the changing of 'All Mail' visibility. + void toggleIsTelemetryDisabled(bool isDisabled); ///< Slot for toggling telemetry on/off. void changeColorScheme(QString const &scheme); ///< Slot for the change of the theme. void setDiskCachePath(QUrl const &path) const; ///< Slot for the change of the disk cache path. void login(QString const &username, QString const &password) const; ///< Slot for the login button (initial login). @@ -174,6 +180,10 @@ public slots: // slot for signals received from QML -> To be forwarded to Bridge void onVersionChanged(); ///< Slot for the version change signal. void setMailServerSettings(int imapPort, int smtpPort, bool useSSLForIMAP, bool useSSLForSMTP) const; ///< Forwards a connection mode change request from QML to gRPC void sendBadEventUserFeedback(QString const &userID, bool doResync); ///< Slot the providing user feedback for a bad event. + void setNormalTrayIcon(); ///< Set the tray icon to normal. + void setErrorTrayIcon(QString const& stateString, QString const &statusIcon); ///< Set the tray icon to 'error' state. + void setWarnTrayIcon(QString const& stateString, QString const &statusIcon); ///< Set the tray icon to 'warn' state. + void setUpdateTrayIcon(QString const& stateString, QString const &statusIcon); ///< Set the tray icon to 'update' state. public slots: // slot for signals received from gRPC that need transformation instead of simple forwarding void onMailServerSettingsChanged(int imapPort, int smtpPort, bool useSSLForIMAP, bool useSSLForSMTP); ///< Slot for the ConnectionModeChanged gRPC event. @@ -233,8 +243,10 @@ signals: // Signals received from the Go backend, to be forwarded to QML void bugReportSendError(); ///< Signal for the 'bugReportSendError' gRPC stream event. void showMainWindow(); ///< Signal for the 'showMainWindow' gRPC stream event. void hideMainWindow(); ///< Signal for the 'hideMainWindow' gRPC stream event. + void showHelp(); ///< Signal for the 'showHelp' event (from the context menu). + void showSettings(); ///< Signal for the 'showHelp' event (from the context menu). + void selectUser(QString const& userID); ///< Signal emitted in order to selected a user with a given ID in the list. void genericError(QString const &title, QString const &description); ///< Signal for the 'genericError' gRPC stream event. - void selectUser(QString const); ///< Signal that request the given user account to be displayed. void imapLoginWhileSignedOut(QString const& username); ///< Signal for the notification of IMAP login attempt on a signed out account. // This signal is emitted when an exception is intercepted is calls triggered by QML. QML engine would intercept the exception otherwise. @@ -257,7 +269,7 @@ private: // data members bool useSSLForIMAP_ { false }; ///< The cached value for useSSLForIMAP. bool useSSLForSMTP_ { false }; ///< The cached value for useSSLForSMTP. QList badEventDisplayQueue_; ///< THe queue for displaying 'bad event feedback request dialog'. - + std::unique_ptr trayIcon_; friend class AppController; }; diff --git a/internal/frontend/bridge-gui/bridge-gui/Resources.qrc b/internal/frontend/bridge-gui/bridge-gui/Resources.qrc index 640fbbb7..f5a078f5 100644 --- a/internal/frontend/bridge-gui/bridge-gui/Resources.qrc +++ b/internal/frontend/bridge-gui/bridge-gui/Resources.qrc @@ -5,11 +5,7 @@ qml/AccountView.qml qml/Banner.qml qml/Bridge.qml - qml/Bridge_test.qml qml/bridgeqml.qmlproject - qml/BridgeTest/UserControl.qml - qml/BridgeTest/UserList.qml - qml/BridgeTest/UserModel.qml qml/BugReportView.qml qml/Configuration.qml qml/ConfigurationItem.qml @@ -28,6 +24,7 @@ qml/icons/ic-connected.svg qml/icons/ic-copy.svg qml/icons/ic-cross-close.svg + qml/icons/ic-dot.svg qml/icons/ic-drive.svg qml/icons/ic-exclamation-circle-filled.svg qml/icons/ic-external-link.svg @@ -104,17 +101,6 @@ qml/ConnectionModeSettings.qml qml/SplashScreen.qml qml/Status.qml - qml/StatusWindow.qml - qml/tests/Buttons.qml - qml/tests/ButtonsColumn.qml - qml/tests/CheckBoxes.qml - qml/tests/ComboBoxes.qml - qml/tests/RadioButtons.qml - qml/tests/Switches.qml - qml/tests/Test.qml - qml/tests/TestComponents.qml - qml/tests/TextAreas.qml - qml/tests/TextFields.qml qml/WelcomeGuide.qml diff --git a/internal/frontend/bridge-gui/bridge-gui/TrayIcon.cpp b/internal/frontend/bridge-gui/bridge-gui/TrayIcon.cpp new file mode 100644 index 00000000..2a16c740 --- /dev/null +++ b/internal/frontend/bridge-gui/bridge-gui/TrayIcon.cpp @@ -0,0 +1,250 @@ +// Copyright (c) 2023 Proton AG +// +// This file is part of Proton Mail Bridge. +// +// Proton Mail Bridge is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Proton Mail Bridge is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Proton Mail Bridge. If not, see . + + +#include "TrayIcon.h" +#include "QMLBackend.h" +#include +#include + + +using namespace bridgepp; + + +namespace { + + +QColor const normalColor(30, 168, 133); /// The normal state color. +QColor const errorColor(220, 50, 81); ///< The error state color. +QColor const warnColor(255, 153, 0); ///< The warn state color. +QColor const updateColor(35, 158, 206); ///< The warn state color. +QColor const greyColor(112, 109, 107); ///< The grey color. + + +//**************************************************************************************************************************************************** +/// \brief Create a single resolution icon from an image. Throw an exception in case of failure. +//**************************************************************************************************************************************************** +QIcon loadIconFromImage(QString const &path) { + QPixmap const pixmap(path); + if (pixmap.isNull()) { + throw Exception(QString("Could create icon from image '%1'.").arg(path)); + } + return QIcon(pixmap); +} + + +//**************************************************************************************************************************************************** +/// \brief Retrieve the color associated with a tray icon state. +/// +/// \param[in] state The state. +/// \return The color associated with a given tray icon state. +//**************************************************************************************************************************************************** +QColor stateColor(TrayIcon::State state) { + switch (state) { + case TrayIcon::State::Normal: + return normalColor; + case TrayIcon::State::Error: + return errorColor; + case TrayIcon::State::Warn: + return warnColor; + case TrayIcon::State::Update: + return updateColor; + default: + app().log().error(QString("Unknown tray icon state %1.").arg(static_cast(state))); + return normalColor; + } +} + + +//**************************************************************************************************************************************************** +/// \brief Return the text identifying a state in resource file names. +/// +/// \param[in] state The state. +/// \param[in] The text identifying the state in resource file names. +//**************************************************************************************************************************************************** +QString stateText(TrayIcon::State state) { + switch (state) { + case TrayIcon::State::Normal: + return "norm"; + case TrayIcon::State::Error: + return "error"; + case TrayIcon::State::Warn: + return "warn"; + case TrayIcon::State::Update: + return "update"; + default: + app().log().error(QString("Unknown tray icon state %1.").arg(static_cast(state))); + return "norm"; + } +} + + +} // anonymous namespace + + +//**************************************************************************************************************************************************** +// +//**************************************************************************************************************************************************** +TrayIcon::TrayIcon() + : QSystemTrayIcon() + , menu_(new QMenu) { + + this->generateDotIcons(); + this->setContextMenu(menu_.get()); + + connect(menu_.get(), &QMenu::aboutToShow, this, &TrayIcon::onMenuAboutToShow); + connect(this, &TrayIcon::selectUser, &app().backend(), &QMLBackend::selectUser); + connect(this, &TrayIcon::activated, this, &TrayIcon::onActivated); + + this->show(); + this->setState(State::Normal, QString(), QString()); +} + + +//**************************************************************************************************************************************************** +// +//**************************************************************************************************************************************************** +void TrayIcon::onMenuAboutToShow() { + this->refreshContextMenu(); +} + + +//**************************************************************************************************************************************************** +// +//**************************************************************************************************************************************************** +void TrayIcon::onUserClicked() { + try { + auto action = dynamic_cast(this->sender()); + if (!action) { + throw Exception("Could not retrieve context menu action."); + } + + QString const &userID = action->data().toString(); + if (userID.isNull()) { + throw Exception("Could not retrieve context menu's selected user."); + } + + emit selectUser(userID); + } catch (Exception const &e) { + app().log().error(e.qwhat()); + } +} + + +//**************************************************************************************************************************************************** +/// \param[in] reason The icon activation reason. +//**************************************************************************************************************************************************** +void TrayIcon::onActivated(QSystemTrayIcon::ActivationReason reason) { + if ((QSystemTrayIcon::Trigger == reason) && !onMacOS()) { + app().backend().showMainWindow(); + } +} + + +//**************************************************************************************************************************************************** +// +//**************************************************************************************************************************************************** +void TrayIcon::generateDotIcons() { + QPixmap dotSVG(":/qml/icons/ic-dot.svg"); + struct IconColor { + QIcon &icon; + QColor color; + }; + for (auto pair: QList {{ greenDot_, normalColor }, { greyDot_, greyColor }, { orangeDot_, warnColor }}) { + QPixmap p = dotSVG; + QPainter painter(&p); + painter.setCompositionMode(QPainter::CompositionMode_SourceIn); + painter.fillRect(p.rect(), pair.color); + painter.end(); + pair.icon = QIcon(p); + } +} + + +//**************************************************************************************************************************************************** +/// \param[in] state The state. +/// \param[in] stateString A string describing the state. +/// \param[in] statusIconPath The status icon path. +/// \param[in] statusIconColor The color for the status icon in hex. +//**************************************************************************************************************************************************** +void TrayIcon::setState(TrayIcon::State state, QString const &stateString, QString const &statusIconPath) { + stateString_ = stateString; + state_ = state; + QString const style = onMacOS() ? "mono" : "color"; + QString const text = stateText(state); + + + QIcon icon = loadIconFromImage(QString(":/qml/icons/systray-%1-%2.png").arg(style, text)); + icon.setIsMask(true); + this->setIcon(icon); + + this->generateStatusIcon(statusIconPath, stateColor(state)); +} + + +//**************************************************************************************************************************************************** +/// \param[in] svgPath The path of the SVG file for the icon. +/// \param[in] color The color to apply to the icon. +//**************************************************************************************************************************************************** +void TrayIcon::generateStatusIcon(QString const &svgPath, QColor const &color) { + // We use the SVG path as pixmap mask and fill it with the appropriate color + QString resourcePath = svgPath; + resourcePath.replace(QRegularExpression(R"(^\.\/)"), ":/qml/"); // QML resource path are a bit different from the Qt resources path. + QPixmap pixmap(resourcePath); + QPainter painter(&pixmap); + painter.setCompositionMode(QPainter::CompositionMode_SourceIn); + painter.fillRect(pixmap.rect(), color); + painter.end(); + statusIcon_ = QIcon(pixmap); +} + + +//********************************************************************************************************************** +// +//********************************************************************************************************************** +void TrayIcon::refreshContextMenu() { + if (!menu_) { + app().log().error("Native tray icon context menu is null."); + return; + } + + menu_->clear(); + menu_->addAction(statusIcon_, stateString_, &app().backend(), &QMLBackend::showMainWindow); + menu_->addSeparator(); + UserList const &users = app().backend().users(); + qint32 const userCount = users.count(); + for (qint32 i = 0; i < userCount; i++) { + User const &user = *users.get(i); + UserState const state = user.state(); + auto action = new QAction(user.primaryEmailOrUsername()); + action->setIcon((UserState::Connected == state) ? greenDot_ : (UserState::Locked == state ? orangeDot_ : greyDot_)); + action->setData(user.id()); + connect(action, &QAction::triggered, this, &TrayIcon::onUserClicked); + if (i < 10) { + action->setShortcut(QKeySequence(QString("Ctrl+%1").arg((i + 1) % 10))); + } + menu_->addAction(action); + } + if (userCount) { + menu_->addSeparator(); + } + menu_->addAction(tr("&Open Bridge"), QKeySequence("Ctrl+O"), &app().backend(), &QMLBackend::showMainWindow); + menu_->addAction(tr("&Help"), QKeySequence("Ctrl+F1"), &app().backend(), &QMLBackend::showHelp); + menu_->addAction(tr("&Settings"), QKeySequence("Ctrl+,"), &app().backend(), &QMLBackend::showSettings); + menu_->addSeparator(); + menu_->addAction(tr("&Quit Bridge"), QKeySequence("Ctrl+Q"), &app().backend(), &QMLBackend::quit); +} diff --git a/internal/frontend/bridge-gui/bridge-gui/TrayIcon.h b/internal/frontend/bridge-gui/bridge-gui/TrayIcon.h new file mode 100644 index 00000000..8517ec8f --- /dev/null +++ b/internal/frontend/bridge-gui/bridge-gui/TrayIcon.h @@ -0,0 +1,70 @@ +// Copyright (c) 2023 Proton AG +// +// This file is part of Proton Mail Bridge. +// +// Proton Mail Bridge is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Proton Mail Bridge is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Proton Mail Bridge. If not, see . + + +#ifndef BRIDGE_GUI_NATIVE_TRAY_ICON_H +#define BRIDGE_GUI_NATIVE_TRAY_ICON_H + + +//********************************************************************************************************************** +/// \brief A native tray icon. +//********************************************************************************************************************** +class TrayIcon: public QSystemTrayIcon { +Q_OBJECT +public: // typedef enum + enum class State { + Normal, + Error, + Warn, + Update, + }; ///< Enumeration for the state. + +public: // data members + TrayIcon(); ///< Default constructor. + ~TrayIcon() override = default; ///< Destructor. + TrayIcon(TrayIcon const&) = delete; ///< Disabled copy-constructor. + TrayIcon(TrayIcon&&) = delete; ///< Disabled assignment copy-constructor. + TrayIcon& operator=(TrayIcon const&) = delete; ///< Disabled assignment operator. + TrayIcon& operator=(TrayIcon&&) = delete; ///< Disabled move assignment operator. + void setState(State state, QString const& stateString, QString const &statusIconPath); ///< Set the state of the icon + +signals: + void selectUser(QString const& userID); ///< Signal for selecting a user with a given userID + +private slots: + void onMenuAboutToShow(); ///< Slot called before the context menu is shown. + void onUserClicked(); ///< Slot triggered when clicking on a user in the context menu. + static void onActivated(QSystemTrayIcon::ActivationReason reason); ///< Slot for the activation of the system tray icon. + +private: // member functions. + void generateDotIcons(); ///< generate the colored dot icons used for user status. + void generateStatusIcon(QString const &svgPath, QColor const& color); ///< Generate the status icon. + void refreshContextMenu(); ///< Refresh the context menu. + +private: // data members + State state_ { State::Normal }; ///< The state of the tray icon. + QString stateString_; ///< The current state string. + std::unique_ptr menu_; ///< The context menu for the tray icon. Not owned by the tray icon. + QIcon statusIcon_; ///< The path of the status icon displayed in the context menu. + QIcon greenDot_; ///< The green dot icon. + QIcon greyDot_; ///< The grey dot icon. + QIcon orangeDot_; ///< The orange dot icon. +}; + + + +#endif //BRIDGE_GUI_NATIVE_TRAY_ICON_H diff --git a/internal/frontend/bridge-gui/bridge-gui/qml/AccountView.qml b/internal/frontend/bridge-gui/bridge-gui/qml/AccountView.qml index 7466cbcd..fa9702a8 100644 --- a/internal/frontend/bridge-gui/bridge-gui/qml/AccountView.qml +++ b/internal/frontend/bridge-gui/bridge-gui/qml/AccountView.qml @@ -27,67 +27,55 @@ Item { property var notifications property var user - signal showSignIn() + signal showSignIn + signal showSetupGuide(var user, string address) - property int _leftMargin: 64 - property int _rightMargin: 64 + property int _contentWidth: 640 property int _topMargin: 32 - property int _detailsTopMargin: 25 - property int _bottomMargin: 12 + property int _detailsMargin: 25 property int _spacing: 20 - property int _lineWidth: 1 - - ScrollView { - id: scrollView - clip: true + property int _lineThickness: 1 + property bool _connected: root.user ? root.user.state === EUserState.Connected : false + Rectangle { anchors.fill: parent - Component.onCompleted: contentItem.boundsBehavior = Flickable.StopAtBounds // Disable the springy effect when scroll reaches top/bottom. + color: root.colorScheme.background_weak - Item { - // can't use parent here because parent is not ScrollView (Flickable inside contentItem inside ScrollView) - width: scrollView.availableWidth - height: scrollView.availableHeight - - implicitHeight: children[0].implicitHeight + children[0].anchors.topMargin + children[0].anchors.bottomMargin - // do not set implicitWidth because implicit width of ColumnLayout will be equal to maximum implicit width of - // internal items. And if one of internal items would be a Text or Label - implicit width of those is always - // equal to non-wrapped text (i.e. one line only). That will lead to enabling horizontal scroll when not needed - implicitWidth: width + ScrollView { + id: scrollView + anchors.fill: parent + Component.onCompleted: contentItem.boundsBehavior = Flickable.StopAtBounds ColumnLayout { + id: topLevelColumnLayout + anchors.fill: parent spacing: 0 - anchors.fill: parent - Rectangle { - id: topRectangle + id: topArea color: root.colorScheme.background_norm - - implicitHeight: children[0].implicitHeight + children[0].anchors.topMargin + children[0].anchors.bottomMargin - implicitWidth: children[0].implicitWidth + children[0].anchors.leftMargin + children[0].anchors.rightMargin - + clip: true Layout.fillWidth: true + implicitHeight: childrenRect.height ColumnLayout { - spacing: root._spacing + id: topLayout + width: _contentWidth + anchors.horizontalCenter: parent.horizontalCenter + spacing: _spacing - anchors.fill: parent - anchors.leftMargin: root._leftMargin - anchors.rightMargin: root._rightMargin - anchors.topMargin: root._topMargin - anchors.bottomMargin: root._bottomMargin - - RowLayout { // account delegate with action buttons + RowLayout { + // account delegate with action buttons Layout.fillWidth: true + Layout.topMargin: _topMargin AccountDelegate { Layout.fillWidth: true colorScheme: root.colorScheme user: root.user type: AccountDelegate.LargeView - enabled: root.user ? (root.user.state === EUserState.Connected) : false + enabled: _connected } Button { @@ -95,10 +83,11 @@ Item { colorScheme: root.colorScheme text: qsTr("Sign out") secondary: true - visible: root.user ? (root.user.state === EUserState.Connected) : false + visible: _connected onClicked: { - if (!root.user) return - root.user.logout() + if (!root.user) + return; + root.user.logout(); } } @@ -109,8 +98,9 @@ Item { secondary: true visible: root.user ? (root.user.state === EUserState.SignedOut) : false onClicked: { - if (!root.user) return - root.showSignIn() + if (!root.user) + return; + root.showSignIn(); } } @@ -120,8 +110,9 @@ Item { icon.source: "/qml/icons/ic-trash.svg" secondary: true onClicked: { - if (!root.user) return - root.notifications.askDeleteAccount(root.user) + if (!root.user) + return; + root.notifications.askDeleteAccount(root.user); } visible: root.user ? root.user.state !== EUserState.Locked : false } @@ -129,7 +120,7 @@ Item { Rectangle { Layout.fillWidth: true - height: root._lineWidth + height: root._lineThickness color: root.colorScheme.border_weak } @@ -139,12 +130,12 @@ Item { actionText: qsTr("Configure") description: qsTr("Using the mailbox details below (re)configure your client.") type: SettingsItem.Button - enabled: root.user ? root.user.state === EUserState.Connected : false - visible: root.user ? !root.user.splitMode || root.user.addresses.length==1 : false + visible: _connected && (!root.user.splitMode) || (root.user.addresses.length === 1) showSeparator: splitMode.visible onClicked: { - if (!root.user) return - root.showSetupGuide(root.user, user.addresses[0]) + if (!root.user) + return; + root.showSetupGuide(root.user, user.addresses[0]); } Layout.fillWidth: true @@ -157,15 +148,14 @@ Item { description: qsTr("Setup multiple email addresses individually.") type: SettingsItem.Toggle checked: root.user ? root.user.splitMode : false - visible: root.user ? root.user.addresses.length > 1 : false - enabled: root.user ? (root.user.state === EUserState.Connected) : false + visible: _connected && root.user.addresses.length > 1 showSeparator: addressSelector.visible onClicked: { - if (!splitMode.checked){ - root.notifications.askEnableSplitMode(user) + if (!splitMode.checked) { + root.notifications.askEnableSplitMode(user); } else { - addressSelector.currentIndex = 0 - root.user.toggleSplitMode(!splitMode.checked) + addressSelector.currentIndex = 0; + root.user.toggleSplitMode(!splitMode.checked); } } @@ -174,8 +164,8 @@ Item { RowLayout { Layout.fillWidth: true - enabled: root.user ? (root.user.state === EUserState.Connected) : false - visible: root.user ? root.user.splitMode : false + Layout.bottomMargin: _spacing + visible: _connected && root.user.splitMode ComboBox { id: addressSelector @@ -189,60 +179,68 @@ Item { text: qsTr("Configure") secondary: true onClicked: { - if (!root.user) return - root.showSetupGuide(root.user, addressSelector.displayText) + if (!root.user) + return; + root.showSetupGuide(root.user, addressSelector.displayText); } } } + + Rectangle { + height: 0 + } // just for some extra space before separator } } Rectangle { + id: bottomArea + Layout.fillWidth: true + implicitHeight: bottomLayout.implicitHeight color: root.colorScheme.background_weak - implicitHeight: children[0].implicitHeight + children[0].anchors.topMargin + children[0].anchors.bottomMargin - implicitWidth: children[0].implicitWidth + children[0].anchors.leftMargin + children[0].anchors.rightMargin - - Layout.fillWidth: true - ColumnLayout { - id: configuration - - anchors.fill: parent - anchors.leftMargin: root._leftMargin - anchors.rightMargin: root._rightMargin - anchors.topMargin: root._detailsTopMargin - anchors.bottomMargin: root._spacing - - spacing: root._spacing - visible: root.user ? (root.user.state === EUserState.Connected) : false - - property string currentAddress: addressSelector.displayText + id: bottomLayout + width: _contentWidth + anchors.horizontalCenter: parent.horizontalCenter + spacing: _spacing + visible: _connected Label { + Layout.topMargin: _detailsMargin colorScheme: root.colorScheme text: qsTr("Mailbox details") type: Label.Body_semibold } - Configuration { - colorScheme: root.colorScheme - title: qsTr("IMAP") - hostname: Backend.hostname - port: Backend.imapPort.toString() - username: configuration.currentAddress - password: root.user ? root.user.password : "" - security : Backend.useSSLForIMAP ? "SSL" : "STARTTLS" - } + RowLayout { + id: configuration + spacing: _spacing + Layout.fillWidth: true + Layout.fillHeight: true - Configuration { - colorScheme: root.colorScheme - title: qsTr("SMTP") - hostname : Backend.hostname - port : Backend.smtpPort.toString() - username : configuration.currentAddress - password : root.user ? root.user.password : "" - security : Backend.useSSLForSMTP ? "SSL" : "STARTTLS" + property string currentAddress: addressSelector.displayText + + Configuration { + Layout.fillWidth: true + colorScheme: root.colorScheme + title: qsTr("IMAP") + hostname: Backend.hostname + port: Backend.imapPort.toString() + username: configuration.currentAddress + password: root.user ? root.user.password : "" + security: Backend.useSSLForIMAP ? "SSL" : "STARTTLS" + } + + Configuration { + Layout.fillWidth: true + colorScheme: root.colorScheme + title: qsTr("SMTP") + hostname: Backend.hostname + port: Backend.smtpPort.toString() + username: configuration.currentAddress + password: root.user ? root.user.password : "" + security: Backend.useSSLForSMTP ? "SSL" : "STARTTLS" + } } } } diff --git a/internal/frontend/bridge-gui/bridge-gui/qml/Bridge.qml b/internal/frontend/bridge-gui/bridge-gui/qml/Bridge.qml index 8d116b3a..3e377ad7 100644 --- a/internal/frontend/bridge-gui/bridge-gui/qml/Bridge.qml +++ b/internal/frontend/bridge-gui/bridge-gui/qml/Bridge.qml @@ -26,11 +26,8 @@ import Notifications QtObject { id: root - function isInInterval(num, lower_limit, upper_limit) { - return lower_limit <= num && num <= upper_limit - } - function bound(num, lower_limit, upper_limit) { - return Math.max(lower_limit, Math.min(upper_limit, num)) + function bound(num, lowerLimit, upperLimit) { + return Math.max(lowerLimit, Math.min(upperLimit, num)) } property var title: Backend.appname @@ -38,10 +35,30 @@ QtObject { property Notifications _notifications: Notifications { id: notifications frontendMain: mainWindow - frontendStatus: statusWindow - frontendTray: trayIcon } + property NotificationFilter _trayNotificationFilter: NotificationFilter { + id: trayNotificationFilter + source: root._notifications ? root._notifications.all : undefined + onTopmostChanged: { + if (topmost) { + switch (topmost.type) { + case Notification.NotificationType.Danger: + Backend.setErrorTrayIcon(topmost.brief, topmost.icon) + return + case Notification.NotificationType.Warning: + Backend.setWarnTrayIcon(topmost.brief, topmost.icon) + return + case Notification.NotificationType.Info: + Backend.setUpdateTrayIcon(topmost.brief, topmost.icon) + return + } + } + Backend.setNormalTrayIcon() + } + } + + property MainWindow _mainWindow: MainWindow { id: mainWindow visible: false @@ -66,190 +83,6 @@ QtObject { } } - property StatusWindow _statusWindow: StatusWindow { - id: statusWindow - visible: false - - title: root.title - notifications: root._notifications - - onShowMainWindow: { - mainWindow.showAndRise() - } - - onShowHelp: { - mainWindow.showHelp() - mainWindow.showAndRise() - } - - onShowSettings: { - mainWindow.showSettings() - mainWindow.showAndRise() - } - - onSelectUser: function(userID) { - mainWindow.selectUser(userID) - mainWindow.showAndRise() - } - - onQuit: { - mainWindow.hide() - trayIcon.visible = false - Backend.quit() - } - - property rect screenRect - property rect iconRect - - // use binding from function with width and height as arguments so it will be recalculated every time width and height are changed - property point position: getPosition(width, height) - x: position.x - y: position.y - - function getPosition(_width, _height) { - if (screenRect.width === 0 || screenRect.height === 0) { - return Qt.point(0, 0) - } - - var _x = 0 - var _y = 0 - - // fit above - _y = iconRect.top - height - if (isInInterval(_y, screenRect.top, screenRect.bottom - height)) { - // position preferably in the horizontal center but bound to the screen rect - _x = bound(iconRect.left + (iconRect.width - width)/2, screenRect.left, screenRect.right - width) - return Qt.point(_x, _y) - } - - // fit below - _y = iconRect.bottom - if (isInInterval(_y, screenRect.top, screenRect.bottom - height)) { - // position preferably in the horizontal center but bound to the screen rect - _x = bound(iconRect.left + (iconRect.width - width)/2, screenRect.left, screenRect.right - width) - return Qt.point(_x, _y) - } - - // fit to the left - _x = iconRect.left - width - if (isInInterval(_x, screenRect.left, screenRect.right - width)) { - // position preferably in the vertical center but bound to the screen rect - _y = bound(iconRect.top + (iconRect.height - height)/2, screenRect.top, screenRect.bottom - height) - return Qt.point(_x, _y) - } - - // fit to the right - _x = iconRect.right - if (isInInterval(_x, screenRect.left, screenRect.right - width)) { - // position preferably in the vertical center but bound to the screen rect - _y = bound(iconRect.top + (iconRect.height - height)/2, screenRect.top, screenRect.bottom - height) - return Qt.point(_x, _y) - } - - // Fallback: position status window right above icon and let window manager decide. - console.warn("Can't position status window: screenRect =", screenRect, "iconRect =", iconRect) - _x = bound(iconRect.left + (iconRect.width - width)/2, screenRect.left, screenRect.right - width) - _y = bound(iconRect.top + (iconRect.height - height)/2, screenRect.top, screenRect.bottom - height) - return Qt.point(_x, _y) - } - } - - property SystemTrayIcon _trayIcon: SystemTrayIcon { - id: trayIcon - visible: true - icon.source: getTrayIconPath() - icon.mask: true // make sure that systems like macOS will use proper color - tooltip: `${root.title} v${Backend.version}` - onActivated: function(reason) { - function calcStatusWindowPosition() { - // On some platforms (X11 / Plasma) Qt does not provide icon position and geometry info. - // In this case we rely on cursor position - var iconRect = Qt.rect(geometry.x, geometry.y, geometry.width, geometry.height) - if (geometry.width == 0 && geometry.height == 0) { - var mousePos = Backend.getCursorPos() - iconRect.x = mousePos.x - iconRect.y = mousePos.y - iconRect.width = 0 - iconRect.height = 0 - } - - // Find screen - var screen - for (var i in Qt.application.screens) { - var _screen = Qt.application.screens[i] - if ( - isInInterval(iconRect.x, _screen.virtualX, _screen.virtualX + _screen.width) && - isInInterval(iconRect.y, _screen.virtualY, _screen.virtualY + _screen.height) - ) { - screen = _screen - break - } - } - if (!screen) { - // Fallback to primary screen - screen = Qt.application.screens[0] - } - - // In case we used mouse to detect icon position - we want to make a fake icon rectangle from a point - if (iconRect.width == 0 && iconRect.height == 0) { - iconRect.x = bound(iconRect.x - 16, screen.virtualX, screen.virtualX + screen.width - 32) - iconRect.y = bound(iconRect.y - 16, screen.virtualY, screen.virtualY + screen.height - 32) - iconRect.width = 32 - iconRect.height = 32 - } - - statusWindow.screenRect = Qt.rect(screen.virtualX, screen.virtualY, screen.width, screen.height) - statusWindow.iconRect = iconRect - } - - function toggleWindow(win) { - if (win.visible) { - win.close() - } else { - win.showAndRise() - } - } - - - switch (reason) { - case SystemTrayIcon.Unknown: - break; - case SystemTrayIcon.Context: - case SystemTrayIcon.Trigger: - case SystemTrayIcon.DoubleClick: - case SystemTrayIcon.MiddleClick: - calcStatusWindowPosition() - toggleWindow(statusWindow) - break; - default: - break; - } - } - - property NotificationFilter _systrayfilter: NotificationFilter { - source: root._notifications ? root._notifications.all : undefined - } - - function getTrayIconPath() { - var color = Backend.goos == "darwin" ? "mono" : "color" - - var level = "norm" - if (_systrayfilter.topmost) { - switch (_systrayfilter.topmost.type) { - case Notification.NotificationType.Danger: - level = "error" - break; - case Notification.NotificationType.Warning: - level = "warn" - break; - case Notification.NotificationType.Info: - level = "update" - break; - } - } - return `qrc:/qml/icons/systray-${color}-${level}.png` - } - } Component.onCompleted: { if (!Backend) { @@ -266,7 +99,7 @@ QtObject { var c = Backend.users.count var u = Backend.users.get(0) // DEBUG - if (c != 0) { + if (c !== 0) { console.log("users non zero", c) console.log("first user", u ) } @@ -290,7 +123,7 @@ QtObject { } function setColorScheme() { - if (Backend.colorSchemeName == "light") ProtonStyle.currentStyle = ProtonStyle.lightStyle - if (Backend.colorSchemeName == "dark") ProtonStyle.currentStyle = ProtonStyle.darkStyle + if (Backend.colorSchemeName === "light") ProtonStyle.currentStyle = ProtonStyle.lightStyle + if (Backend.colorSchemeName === "dark") ProtonStyle.currentStyle = ProtonStyle.darkStyle } } diff --git a/internal/frontend/bridge-gui/bridge-gui/qml/BridgeTest/UserControl.qml b/internal/frontend/bridge-gui/bridge-gui/qml/BridgeTest/UserControl.qml deleted file mode 100644 index 349087ae..00000000 --- a/internal/frontend/bridge-gui/bridge-gui/qml/BridgeTest/UserControl.qml +++ /dev/null @@ -1,315 +0,0 @@ -// Copyright (c) 2023 Proton AG -// -// This file is part of Proton Mail Bridge. -// -// Proton Mail Bridge is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// Proton Mail Bridge is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with Proton Mail Bridge. If not, see . - -import QtQml -import QtQuick -import QtQuick.Layouts -import QtQuick.Controls - -import Proton - -ColumnLayout { - id: root - - property var user - property var userIndex - - spacing : 5 - - Layout.fillHeight: true - //Layout.fillWidth: true - - property ColorScheme colorScheme - - TextField { - colorScheme: root.colorScheme - Layout.fillWidth: true - - text: user !== undefined ? user.username : "" - - onEditingFinished: { - user.username = text - } - } - - ColumnLayout { - Layout.fillWidth: true - - Switch { - id: userLoginSwitch - colorScheme: root.colorScheme - - text: "LoggedIn" - enabled: user !== undefined && user.username.length > 0 - - checked: user ? root.user.state == EUserState.Connected : false - - onCheckedChanged: { - if (!user) { - return - } - - if (checked) { - if (user === Backend.loginUser) { - var newUserObject = Backend.userComponent.createObject(Backend, {username: user.username, loggedIn: true, setupGuideSeen: user.setupGuideSeen}) - Backend.users.append( { object: newUserObject } ) - - user.username = "" - user.resetLoginRequests() - return - } - - user.state = EUserState.Connected - user.resetLoginRequests() - return - } else { - user.state = EUserState.SignedOut - user.resetLoginRequests() - } - } - } - - Switch { - colorScheme: root.colorScheme - - text: "Setup guide seen" - enabled: user !== undefined && user.username.length > 0 - - checked: user ? user.setupGuideSeen : false - - onCheckedChanged: { - if (!user) { - return - } - - user.setupGuideSeen = checked - } - } - } - - - RowLayout { - Layout.fillWidth: true - - Label { - colorScheme: root.colorScheme - id: loginLabel - text: "Login:" - - Layout.preferredWidth: Math.max(loginLabel.implicitWidth, faLabel.implicitWidth, passLabel.implicitWidth) - } - - Button { - colorScheme: root.colorScheme - text: "name/pass error" - enabled: user !== undefined //&& user.isLoginRequested && !user.isLogin2FARequested && !user.isLogin2PasswordProvided - - onClicked: { - Backend.loginUsernamePasswordError("") - user.resetLoginRequests() - } - } - - Button { - colorScheme: root.colorScheme - text: "free user error" - enabled: user !== undefined //&& user.isLoginRequested - onClicked: { - Backend.loginFreeUserError() - user.resetLoginRequests() - } - } - - Button { - colorScheme: root.colorScheme - text: "connection error" - enabled: user !== undefined //&& user.isLoginRequested - onClicked: { - Backend.loginConnectionError("") - user.resetLoginRequests() - } - } - } - - RowLayout { - Layout.fillWidth: true - - Label { - colorScheme: root.colorScheme - id: faLabel - text: "2FA:" - - Layout.preferredWidth: Math.max(loginLabel.implicitWidth, faLabel.implicitWidth, passLabel.implicitWidth) - } - - Button { - colorScheme: root.colorScheme - text: "request" - - enabled: user !== undefined //&& user.isLoginRequested && !user.isLogin2FARequested && !user.isLogin2PasswordRequested - onClicked: { - Backend.login2FARequested(user.username) - user.isLogin2FARequested = true - } - } - - Button { - colorScheme: root.colorScheme - text: "error" - - enabled: user !== undefined //&& user.isLogin2FAProvided && !(user.isLogin2PasswordRequested && !user.isLogin2PasswordProvided) - onClicked: { - Backend.login2FAError("") - user.isLogin2FAProvided = false - } - } - - Button { - colorScheme: root.colorScheme - text: "Abort" - - enabled: user !== undefined //&& user.isLogin2FAProvided && !(user.isLogin2PasswordRequested && !user.isLogin2PasswordProvided) - onClicked: { - Backend.login2FAErrorAbort("") - user.resetLoginRequests() - } - } - } - - RowLayout { - Layout.fillWidth: true - - Label { - colorScheme: root.colorScheme - id: passLabel - text: "2 Password:" - - Layout.preferredWidth: Math.max(loginLabel.implicitWidth, faLabel.implicitWidth, passLabel.implicitWidth) - } - - Button { - colorScheme: root.colorScheme - text: "request" - - enabled: user !== undefined //&& user.isLoginRequested && !user.isLogin2PasswordRequested && !(user.isLogin2FARequested && !user.isLogin2FAProvided) - onClicked: { - Backend.login2PasswordRequested("") - user.isLogin2PasswordRequested = true - } - } - - Button { - colorScheme: root.colorScheme - text: "error" - - enabled: user !== undefined //&& user.isLogin2PasswordProvided && !(user.isLogin2FARequested && !user.isLogin2FAProvided) - onClicked: { - Backend.login2PasswordError("") - - user.isLogin2PasswordProvided = false - } - } - - Button { - colorScheme: root.colorScheme - text: "Abort" - - enabled: user !== undefined //&& user.isLogin2PasswordProvided && !(user.isLogin2FARequested && !user.isLogin2FAProvided) - onClicked: { - Backend.login2PasswordErrorAbort("") - user.resetLoginRequests() - } - } - } - - RowLayout { - Button { - colorScheme: root.colorScheme - text: "Login Finished" - - onClicked: { - Backend.loginFinished(0+loginFinishedIndex.text) - user.resetLoginRequests() - } - } - TextField { - id: loginFinishedIndex - colorScheme: root.colorScheme - label: "Index:" - text: root.userIndex - } - } - - RowLayout { - Button { - colorScheme: root.colorScheme - text: "Already logged in" - - onClicked: { - Backend.loginAlreadyLoggedIn(0+loginAlreadyLoggedInIndex.text) - user.resetLoginRequests() - } - } - TextField { - id: loginAlreadyLoggedInIndex - colorScheme: root.colorScheme - label: "Index:" - text: root.userIndex - } - } - - RowLayout { - TextField { - colorScheme: root.colorScheme - label: "used:" - text: user && user.usedBytes ? user.usedBytes : 0 - onEditingFinished: { - user.usedBytes = parseFloat(text) - } - implicitWidth: 200 - } - TextField { - colorScheme: root.colorScheme - label: "total:" - text: user && user.totalBytes ? user.totalBytes : 0 - onEditingFinished: { - user.totalBytes = parseFloat(text) - } - implicitWidth: 200 - } - } - - RowLayout { - Label {colorScheme: root.colorScheme; text: "Split mode"} - Toggle { colorScheme: root.colorScheme; checked: user ? user.splitMode : false; onClicked: {user.splitMode = !user.splitMode}} - Button { colorScheme: root.colorScheme; text: "Toggle Finished"; onClicked: {user.toggleSplitModeFinished()}} - } - - TextArea { // TODO: this is causing binding loop on implicitWidth - colorScheme: root.colorScheme - text: user && user.addresses ? user.addresses.join("\n") : "user@protonmail.com" - Layout.fillWidth: true - - onEditingFinished: { - user.addresses = text.split("\n") - } - } - - Item { - Layout.fillHeight: true - } -} diff --git a/internal/frontend/bridge-gui/bridge-gui/qml/BridgeTest/UserList.qml b/internal/frontend/bridge-gui/bridge-gui/qml/BridgeTest/UserList.qml deleted file mode 100644 index 92b50335..00000000 --- a/internal/frontend/bridge-gui/bridge-gui/qml/BridgeTest/UserList.qml +++ /dev/null @@ -1,101 +0,0 @@ -// Copyright (c) 2023 Proton AG -// -// This file is part of Proton Mail Bridge. -// -// Proton Mail Bridge is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// Proton Mail Bridge is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with Proton Mail Bridge. If not, see . - -import QtQuick -import QtQuick.Layouts -import QtQuick.Controls - -import Proton - -ColumnLayout { - id: root - - property ColorScheme colorScheme - - property alias currentIndex: usersListView.currentIndex - ListView { - id: usersListView - Layout.fillHeight: true - Layout.preferredWidth: 200 - - model: Backend.usersTest - highlightFollowsCurrentItem: true - - delegate: Item { - - implicitHeight: children[0].implicitHeight + anchors.topMargin + anchors.bottomMargin - implicitWidth: children[0].implicitWidth + anchors.leftMargin + anchors.rightMargin - - width: usersListView.width - - anchors.margins: 10 - - Label { - colorScheme: root.colorScheme - text: modelData.username - anchors.margins: 10 - anchors.fill: parent - - MouseArea { - anchors.fill: parent - onClicked: { - usersListView.currentIndex = index - } - } - } - } - - highlight: Rectangle { - color: root.colorScheme.interaction_default_active - } - } - - RowLayout { - Layout.fillWidth: true - - Button { - colorScheme: root.colorScheme - - text: "+" - - onClicked: { - var newUserObject = Backend.userComponent.createObject(Backend) - newUserObject.username = Backend.loginUser.username.length > 0 ? Backend.loginUser.username : "test@protonmail.com" - newUserObject.state = EUserState.Connected - newUserObject.setupGuideSeen = true // Backend.loginUser.setupGuideSeen - - Backend.loginUser.username = "" - Backend.loginUser.state = EUserState.SignedOut - Backend.loginUser.setupGuideSeen = false - - Backend.users.append( { object: newUserObject } ) - } - } - Button { - colorScheme: root.colorScheme - text: "-" - - enabled: usersListView.currentIndex != 0 - - onClicked: { - // var userObject = Backend.users.get(usersListView.currentIndex - 1) - Backend.users.remove(usersListView.currentIndex - 1) - // userObject.deleteLater() - } - } - } -} diff --git a/internal/frontend/bridge-gui/bridge-gui/qml/Bridge_test.qml b/internal/frontend/bridge-gui/bridge-gui/qml/Bridge_test.qml deleted file mode 100644 index 8ca4e750..00000000 --- a/internal/frontend/bridge-gui/bridge-gui/qml/Bridge_test.qml +++ /dev/null @@ -1,982 +0,0 @@ -// Copyright (c) 2023 Proton AG -// -// This file is part of Proton Mail Bridge. -// -// Proton Mail Bridge is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// Proton Mail Bridge is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with Proton Mail Bridge. If not, see . - -import QtQml -import QtQuick -import QtQuick.Window -import QtQuick.Layouts -import QtQuick.Controls - -import QtQml.Models - -import Qt.labs.platform - -import Proton - -import "./BridgeTest" -import BridgePreview - -import Notifications - -Window { - id: root - - x: 10 - y: 10 - width: 800 - height: 800 - - property ColorScheme colorScheme: ProtonStyle.darkStyle - - flags : Qt.Window | Qt.Dialog - visible : true - title : "Bridge Test GUI" - - // This is needed because on MacOS if first window shown is not transparent - - // all other windows of application will not have transparent background (black - // instead of transparency). In our case that mean that if BridgeTest will be - // shown before StatusWindow - StatusWindow will not have transparent corners. - color: "transparent" - - function getCursorPos() { - return BridgePreview.getCursorPos() - } - - function restart() { - root.quit() - console.log("Restarting....") - root.openBridge() - } - - function openBridge() { - bridge = bridgeComponent.createObject() - var showSetupGuide = false - if (showSetupGuide) { - var newUserObject = root.userComponent.createObject(root) - newUserObject.username = "LerooooyJenkins@protonmail.com" - newUserObject.state = EUserState.Connected - newUserObject.setupGuideSeen = false - root.users.append( { object: newUserObject } ) - } - } - - - function quit() { - if (bridge !== undefined && bridge !== null) { - bridge.destroy() - } - } - - function guiReady() { - console.log("Gui Ready") - } - - function _log(msg, color) { - logTextArea.text += "

" + msg + "

" - logTextArea.text += "\n" - } - - function log(msg) { - console.log(msg) - _log(msg, root.colorScheme.signal_info) - } - - function error(msg) { - console.error(msg) - _log(msg, root.colorScheme.signal_danger) - } - - // No user object should be put in this list until a successful login - property var users: UserModel { - id: _users - - onRowsInserted: { - for (var i = first; i <= last; i++) { - _usersTest.insert(i + 1, { object: get(i) } ) - } - } - - onRowsRemoved: { - _usersTest.remove(first + 1, first - last + 1) - } - - onRowsMoved: { - _usersTest.move(start + 1, row + 1, end - start + 1) - } - - onDataChanged: { - for (var i = topLeft.row; i <= bottomRight.row; i++) { - _usersTest.set(i + 1, { object: get(i) } ) - } - } - } - - // this list is used on test gui: it contains same users list as users above + fake user to represent login request of new user on pos 0 - property var usersTest: UserModel { - id: _usersTest - } - - property var userComponent: Component { - id: _userComponent - - QtObject { - property string username: "" - property bool loggedIn: false - property bool splitMode: false - - property bool setupGuideSeen: true - - property var usedBytes: 5350*1024*1024 - property var totalBytes: 20*1024*1024*1024 - property string avatarText: "jd" - - property string password: "SMj975NnEYYsqu55GGmlpv" - property var addresses: [ - "jaanedoe@protonmail.com", - "jane@pm.me", - "jdoe@pm.me" - ] - - signal loginUsernamePasswordError() - signal loginFreeUserError() - signal loginConnectionError() - signal login2FARequested() - signal login2FAError() - signal login2FAErrorAbort() - signal login2PasswordRequested() - signal login2PasswordError() - signal login2PasswordErrorAbort() - - // Test purpose only: - property bool isFakeUser: this === root.loginUser - - function userSignal(msg) { - if (isFakeUser) { - return - } - - root.log("<- User (" + username + "): " + msg) - } - - function toggleSplitMode(makeActive) { - userSignal("toggle split mode "+makeActive) - } - signal toggleSplitModeFinished() - - function configureAppleMail(address){ - userSignal("configure apple mail "+address) - } - - function logout(){ - userSignal("logout") - loggedIn = false - } - function remove(){ - console.log("remove this", users.count) - for (var i=0; i usersListView.currentIndex) && usersListView.currentIndex != -1) ? root.usersTest.get(usersListView.currentIndex) : undefined - userIndex: usersListView.currentIndex - 1 // -1 because 0 index is fake user - } - } - - RowLayout { - id: notificationsTab - spacing: 5 - - ColumnLayout { - spacing: 5 - - Switch { - text: "Internet connection" - colorScheme: root.colorScheme - checked: true - onCheckedChanged: { - checked ? root.internetOn() : root.internetOff() - } - } - - Button { - text: "Update manual ready" - colorScheme: root.colorScheme - onClicked: { - root.updateManualReady("3.14.1592") - } - } - - Button { - text: "Update manual done" - colorScheme: root.colorScheme - onClicked: { - root.updateManualRestartNeeded() - } - } - - Button { - text: "Update manual error" - colorScheme: root.colorScheme - onClicked: { - root.updateManualError() - } - } - - Button { - text: "Update force" - colorScheme: root.colorScheme - onClicked: { - root.updateForce("3.14.1592") - } - } - - Button { - text: "Update force error" - colorScheme: root.colorScheme - onClicked: { - root.updateForceError() - } - } - - Button { - text: "Update silent done" - colorScheme: root.colorScheme - onClicked: { - root.updateSilentRestartNeeded() - } - } - - Button { - text: "Update silent error" - colorScheme: root.colorScheme - onClicked: { - root.updateSilentError() - } - } - - Button { - text: "Update is latest version" - colorScheme: root.colorScheme - onClicked: { - root.updateIsLatestVersion() - } - } - - Button { - text: "Bug report send OK" - colorScheme: root.colorScheme - onClicked: { - root.reportBugFinished() - root.bugReportSendSuccess() - } - - } - } - - ColumnLayout { - spacing: 5 - - Button { - text: "Bug report send error" - colorScheme: root.colorScheme - onClicked: { - root.reportBugFinished() - root.bugReportSendError() - } - } - - Button { - text: "Cache anavailable" - colorScheme: root.colorScheme - onClicked: { - root.cacheUnavailable() - } - } - - Button { - text: "Cache can't move" - colorScheme: root.colorScheme - onClicked: { - root.cacheCantMove() - } - } - - Button { - text: "Cache location change success" - onClicked: { - root.cacheLocationChangeSuccess() - } - colorScheme: root.colorScheme - } - - Button { - text: "Disk full" - colorScheme: root.colorScheme - onClicked: { - root.diskFull() - } - } - - Button { - text: "No keychain" - colorScheme: root.colorScheme - onClicked: { - root.notifyHasNoKeychain() - } - } - - Button { - text: "Rebuild keychain" - colorScheme: root.colorScheme - onClicked: { - root.notifyRebuildKeychain() - } - } - - Button { - text: "Address changed" - colorScheme: root.colorScheme - onClicked: { - root.addressChanged("p@v.el") - } - } - - Button { - text: "Address changed + Logout" - colorScheme: root.colorScheme - onClicked: { - root.addressChangedLogout("p@v.el") - } - } - } - } - - TextArea { - id: logTextArea - colorScheme: root.colorScheme - Layout.fillHeight: true - Layout.fillWidth: true - - Layout.preferredWidth: 400 - Layout.preferredHeight: 200 - - textFormat: TextEdit.RichText - //readOnly: true - } - - ScrollView { - id: settingsTab - ColumnLayout { - RowLayout { - Label {colorScheme : root.colorScheme ; text : "GOOS : "} - Button {colorScheme : root.colorScheme ; text : "Linux" ; onClicked : root.goos = "linux" ; enabled: root.goos != "linux"} - Button {colorScheme : root.colorScheme ; text : "Windows" ; onClicked : root.goos = "windows" ; enabled: root.goos != "windows"} - Button {colorScheme : root.colorScheme ; text : "macOS" ; onClicked : root.goos = "darwin" ; enabled: root.goos != "darwin"} - } - RowLayout { - Label {colorScheme: root.colorScheme; text: "Automatic updates:"} - Toggle {colorScheme: root.colorScheme; checked: root.isAutomaticUpdateOn; onClicked: root.isAutomaticUpdateOn = !root.isAutomaticUpdateOn} - } - RowLayout { - Label {colorScheme: root.colorScheme; text: "Autostart:"} - Toggle {colorScheme: root.colorScheme; checked: root.isAutostartOn; onClicked: root.isAutostartOn = !root.isAutostartOn} - Button {colorScheme: root.colorScheme; text: "Toggle finished"; onClicked: root.toggleAutostartFinished()} - } - RowLayout { - Label {colorScheme: root.colorScheme; text: "Beta:"} - Toggle {colorScheme: root.colorScheme; checked: root.isBetaEnabled; onClicked: root.isBetaEnabled = !root.isBetaEnabled} - } - RowLayout { - Label {colorScheme: root.colorScheme; text: "DoH:"} - Toggle {colorScheme: root.colorScheme; checked: root.isDoHEnabled; onClicked: root.isDoHEnabled = !root.isDoHEnabled} - } - RowLayout { - Label {colorScheme: root.colorScheme; text: "All Mail disabled:"} - Toggle {colorScheme: root.colorScheme; checked: root.isAllMailVisible; onClicked: root.isAllMailVisible = !root.isAllMailVisible} - } - RowLayout { - Label {colorScheme: root.colorScheme; text: "Ports:"} - TextField { - colorScheme:root.colorScheme - label: "IMAP" - text: root.portIMAP - onEditingFinished: root.portIMAP = this.text*1 - validator: IntValidator {bottom: 1; top: 65536} - } - TextField { - colorScheme:root.colorScheme - label: "SMTP" - text: root.portSMTP - onEditingFinished: root.portSMTP = this.text*1 - validator: IntValidator {bottom: 1; top: 65536} - } - Button {colorScheme: root.colorScheme; text: "Change finished"; onClicked: root.changePortFinished()} - } - RowLayout { - Label {colorScheme: root.colorScheme; text: "SMTP using SSL:"} - Toggle {colorScheme: root.colorScheme; checked: root.useSSLForSMTP; onClicked: root.useSSLForSMTP = !root.useSSLForSMTP} - } - RowLayout { - Label {colorScheme: root.colorScheme; text: "Local cache:"} - Toggle {colorScheme: root.colorScheme; checked: root.isDiskCacheEnabled; onClicked: root.isDiskCacheEnabled = !root.isDiskCacheEnabled} - TextField { - colorScheme:root.colorScheme - label: "Path" - text: root.diskCachePath.toString().replace("file://", "") - implicitWidth: 160 - onEditingFinished: { - root.diskCachePath = Qt.resolvedUrl("file://"+text) - } - } - Button {colorScheme: root.colorScheme; text: "Change finished"; onClicked: root.changeLocalCacheFinished()} - } - RowLayout { - Label {colorScheme: root.colorScheme; text: "Reset:"} - Button {colorScheme: root.colorScheme; text: "Finished"; onClicked: root.resetFinished()} - } - RowLayout { - Label {colorScheme: root.colorScheme; text: "Check update:"} - Button {colorScheme: root.colorScheme; text: "Finished"; onClicked: root.checkUpdatesFinished()} - } - } - } - } - } - - property Bridge bridge - - property string goos: "darwin" - - property bool showOnStartup: true // this actually needs to be false, but since we use Bridge_test for testing purpose - lets default this to true just for convenience - property bool dockIconVisible: false - - // this signals are used only when trying to login with new user (i.e. not in users model) - signal loginUsernamePasswordError(string errorMsg) - signal loginFreeUserError() - signal loginConnectionError(string errorMsg) - signal login2FARequested(string username) - signal login2FAError(string errorMsg) - signal login2FAErrorAbort(string errorMsg) - signal login2PasswordRequested() - signal login2PasswordError(string errorMsg) - signal login2PasswordErrorAbort(string errorMsg) - signal loginFinished(int index) - signal loginAlreadyLoggedIn(int index) - - signal internetOff() - signal internetOn() - - signal updateManualReady(var version) - signal updateManualRestartNeeded() - signal updateManualError() - signal updateForce(var version) - signal updateForceError() - signal updateSilentRestartNeeded() - signal updateSilentError() - signal updateIsLatestVersion() - function checkUpdates(){ - console.log("check updates") - } - signal checkUpdatesFinished() - function installUpdate() { - console.log("manuall install update triggered") - } - - - property bool isDiskCacheEnabled: true - // Qt.resolvedUrl("file:///C:/Users/user/AppData/Roaming/protonmail/bridge-v3/cache/c11/messages") - property url diskCachePath: StandardPaths.standardLocations(StandardPaths.HomeLocation)[0] - signal cacheUnavailable() - signal cacheCantMove() - signal cacheLocationChangeSuccess() - signal diskFull() - function changeLocalCache(enableDiskCache, diskCachePath) { - console.debug("-> disk cache", enableDiskCache, diskCachePath) - } - signal changeLocalCacheFinished() - - - // Settings - property bool isAutomaticUpdateOn : true - function toggleAutomaticUpdate(makeItActive) { - console.debug("-> silent updates", makeItActive, root.isAutomaticUpdateOn) - var callback = function () { - root.isAutomaticUpdateOn = makeItActive; - console.debug("-> CHANGED silent updates", makeItActive, root.isAutomaticUpdateOn) - } - atimer.onTriggered.connect(callback) - atimer.restart() - } - - Timer { - id: atimer - interval: 2000 - running: false - repeat: false - } - - property bool isAutostartOn : true // Example of settings with loading state - function toggleAutostart(makeItActive) { - console.debug("-> autostart", makeItActive, root.isAutostartOn) - } - signal toggleAutostartFinished() - - property bool isBetaEnabled : false - function toggleBeta(makeItActive){ - console.debug("-> beta", makeItActive, root.isBetaEnabled) - root.isBetaEnabled = makeItActive - } - - property bool isDoHEnabled : true - function toggleDoH(makeItActive){ - console.debug("-> DoH", makeItActive, root.isDoHEnabled) - root.isDoHEnabled = makeItActive - } - - property bool isAllMailVisible : true - function changeIsAllMailVisible(isVisible){ - console.debug("-> All Mail Visible", isVisible, root.isAllMailVisible) - root.isAllMailVisible = isVisible - } - - - property bool useSSLForSMTP: false - function toggleUseSSLForSMTP(makeItActive){ - console.debug("-> SMTP SSL", makeItActive, root.useSSLForSMTP) - } - signal toggleUseSSLFinished() - - property string hostname: "127.0.0.1" - property int portIMAP: 1143 - property int portSMTP: 1025 - function changePorts(imapPort, smtpPort){ - console.debug("-> ports", imapPort, smtpPort) - } - function isPortFree(port){ - if (port == portIMAP) return false - if (port == portSMTP) return false - if (port == 12345) return false - return true - } - signal changePortFinished() - signal imapPortStartupError() - signal smtpPortStartupError() - - function triggerReset() { - console.debug("-> trigger reset") - } - signal resetFinished() - - property string version: "2.0.X-BridePreview" - property url logsPath: StandardPaths.standardLocations(StandardPaths.HomeLocation)[0] - property url licensePath: StandardPaths.standardLocations(StandardPaths.HomeLocation)[0] - property url releaseNotesLink: Qt.resolvedUrl("https://proton.me/download/bridge/early_releases.html") - property url dependencyLicensesLink: Qt.resolvedUrl("https://github.com/ProtonMail/proton-bridge/v3/blob/master/COPYING_NOTES.md#dependencies") - property url landingPageLink: Qt.resolvedUrl("https://proton.me/mail/bridge#download") - - property string colorSchemeName: "light" - function changeColorScheme(newScheme){ - root.colorSchemeName = newScheme - } - - - property string currentEmailClient: "" // "Apple Mail 14.0" - function updateCurrentMailClient(){ - currentEmailClient = "Apple Mail 14.0" - } - - function reportBug(description,address,emailClient,includeLogs){ - console.log("report bug") - console.log(" description",description) - console.log(" address",address) - console.log(" emailClient",emailClient) - console.log(" includeLogs",includeLogs) - } - signal reportBugFinished() - signal bugReportSendSuccess() - signal bugReportSendError() - - property var availableKeychain: ["gnome-keyring", "pass", "macos-keychain", "windows-credentials"] - property string currentKeychain: availableKeychain[0] - function changeKeychain(wantedKeychain){ - console.log("Changing keychain from", root.currentKeychain, "to", wantedKeychain) - root.currentKeychain = wantedKeychain - root.changeKeychainFinished() - } - signal changeKeychainFinished() - signal notifyHasNoKeychain() - signal notifyRebuildKeychain() - - signal noActiveKeyForRecipient(string email) - signal showMainWindow() - - signal addressChanged(string address) - signal addressChangedLogout(string address) - signal userDisconnected(string username) - signal apiCertIssue() - - property bool showSplashScreen: false - - - function login(username, password) { - root.log("-> login(" + username + ", " + password + ")") - - loginUser.username = username - loginUser.isLoginRequested = true - } - - function login2FA(username, code) { - root.log("-> login2FA(" + username + ", " + code + ")") - - loginUser.isLogin2FAProvided = true - } - - function login2Password(username, password) { - root.log("-> login2FA(" + username + ", " + password + ")") - - loginUser.isLogin2PasswordProvided = true - } - - function loginAbort(username) { - root.log("-> loginAbort(" + username + ")") - - loginUser.resetLoginRequests() - } - - - onLoginUsernamePasswordError: { - console.debug("<- loginUsernamePasswordError") - } - onLoginFreeUserError: { - console.debug("<- loginFreeUserError") - } - onLoginConnectionError: { - console.debug("<- loginConnectionError") - } - onLogin2FARequested: { - console.debug("<- login2FARequested", username) - } - onLogin2FAError: { - console.debug("<- login2FAError") - } - onLogin2FAErrorAbort: { - console.debug("<- login2FAErrorAbort") - } - onLogin2PasswordRequested: { - console.debug("<- login2PasswordRequested") - } - onLogin2PasswordError: { - console.debug("<- login2PasswordError") - } - onLogin2PasswordErrorAbort: { - console.debug("<- login2PasswordErrorAbort") - } - onLoginFinished: { - console.debug("<- loginFinished", index) - } - onLoginAlreadyLoggedIn: { - console.debug("<- loginAlreadyLoggedIn", index) - } - - onInternetOff: { - console.debug("<- internetOff") - } - onInternetOn: { - console.debug("<- internetOn") - } - - Component { - id: bridgeComponent - - Bridge { - backend: root - - } - } - - onClosing: { - Qt.quit() - } -} diff --git a/internal/frontend/bridge-gui/bridge-gui/qml/Configuration.qml b/internal/frontend/bridge-gui/bridge-gui/qml/Configuration.qml index 1ba9ebe4..84121e81 100644 --- a/internal/frontend/bridge-gui/bridge-gui/qml/Configuration.qml +++ b/internal/frontend/bridge-gui/bridge-gui/qml/Configuration.qml @@ -61,8 +61,6 @@ Rectangle { type: Label.Body_semibold } - Item{} - ConfigurationItem{ colorScheme: root.colorScheme; label: qsTr("Hostname") ; value: root.hostname } ConfigurationItem{ colorScheme: root.colorScheme; label: qsTr("Port") ; value: root.port } ConfigurationItem{ colorScheme: root.colorScheme; label: qsTr("Username") ; value: root.username } diff --git a/internal/frontend/bridge-gui/bridge-gui/qml/GeneralSettings.qml b/internal/frontend/bridge-gui/bridge-gui/qml/GeneralSettings.qml index 86b75e72..7d6860da 100644 --- a/internal/frontend/bridge-gui/bridge-gui/qml/GeneralSettings.qml +++ b/internal/frontend/bridge-gui/bridge-gui/qml/GeneralSettings.qml @@ -169,6 +169,19 @@ SettingsView { Layout.fillWidth: true } + SettingsItem { + id: telemetry + Layout.fillWidth: true + checked: !Backend.isTelemetryDisabled + colorScheme: root.colorScheme + description: qsTr("Help us improve Proton services by sending anonymous usage statistics.") + text: qsTr("Collect usage diagnostics") + type: SettingsItem.Toggle + visible: root._isAdvancedShown + + onClicked: Backend.toggleIsTelemetryDisabled(telemetry.checked) + } + SettingsItem { id: ports visible: root._isAdvancedShown diff --git a/internal/frontend/bridge-gui/bridge-gui/qml/HelpView.qml b/internal/frontend/bridge-gui/bridge-gui/qml/HelpView.qml index 432c48af..d4ad546a 100644 --- a/internal/frontend/bridge-gui/bridge-gui/qml/HelpView.qml +++ b/internal/frontend/bridge-gui/bridge-gui/qml/HelpView.qml @@ -41,7 +41,7 @@ SettingsView { actionIcon: "/qml/icons/ic-external-link.svg" description: qsTr("Get help setting up your client with our instructions and FAQs.") type: SettingsItem.PrimaryButton - onClicked: {Qt.openUrlExternally("https://proton.me/support/mail")} + onClicked: {Qt.openUrlExternally("https://proton.me/support/bridge")} Layout.fillWidth: true } diff --git a/internal/frontend/bridge-gui/bridge-gui/qml/MainWindow.qml b/internal/frontend/bridge-gui/bridge-gui/qml/MainWindow.qml index 491206ad..9295d7f5 100644 --- a/internal/frontend/bridge-gui/bridge-gui/qml/MainWindow.qml +++ b/internal/frontend/bridge-gui/bridge-gui/qml/MainWindow.qml @@ -24,29 +24,20 @@ import QtQuick.Controls import Proton import Notifications -import "tests" - ApplicationWindow { id: root - - width: 960 - height: 576 - + colorScheme: ProtonStyle.currentStyle visible: true - minimumHeight: contentLayout.implicitHeight - minimumWidth: contentLayout.implicitWidth - colorScheme: ProtonStyle.currentStyle + property int _defaultWidth: 1080 + property int _defaultHeight: 780 + width: _defaultWidth + height: _defaultHeight + minimumWidth: _defaultWidth property var notifications - // This is needed because on MacOS if first window shown is not transparent - - // all other windows of application will not have transparent background (black - // instead of transparency). In our case that mean that if MainWindow will be - // shown before StatusWindow - StatusWindow will not have transparent corners. - color: "transparent" - // show Setup Guide on every new user Connections { target: Backend.users @@ -86,10 +77,6 @@ ApplicationWindow { root.showAndRise() } - function onSelectUser(userID) { - root.selectUser(userID) - } - function onLoginFinished(index, wasSignedOut) { var user = Backend.users.get(index) if (user && !wasSignedOut) { @@ -97,6 +84,21 @@ ApplicationWindow { } console.debug("Login finished", index) } + + function onShowHelp() { + root.showHelp() + root.showAndRise() + } + + function onShowSettings() { + root.showSettings() + root.showAndRise() + } + + function onSelectUser(userID) { + contentWrapper.selectUser(userID) + root.showAndRise() + } } StackLayout { diff --git a/internal/frontend/bridge-gui/bridge-gui/qml/Notifications/Notifications.qml b/internal/frontend/bridge-gui/bridge-gui/qml/Notifications/Notifications.qml index 36886073..1431aa36 100644 --- a/internal/frontend/bridge-gui/bridge-gui/qml/Notifications/Notifications.qml +++ b/internal/frontend/bridge-gui/bridge-gui/qml/Notifications/Notifications.qml @@ -24,8 +24,6 @@ QtObject { id: root property MainWindow frontendMain - property StatusWindow frontendStatus - property SystemTrayIcon frontendTray signal askEnableBeta() signal askEnableSplitMode(var user) @@ -140,7 +138,7 @@ QtObject { property Notification imapPortChangeError: Notification { description: qsTr("The IMAP port could not be changed.") - brief: qsTr("IMAP port change error") + brief: qsTr("IMAP port error") icon: "./icons/ic-alert.svg" type: Notification.NotificationType.Danger group: Notifications.Group.Connection @@ -156,7 +154,7 @@ QtObject { property Notification smtpPortChangeError: Notification { description: qsTr("The SMTP port could not be changed.") - brief: qsTr("SMTP port change error") + brief: qsTr("SMTP port error") icon: "./icons/ic-alert.svg" type: Notification.NotificationType.Danger group: Notifications.Group.Connection @@ -172,7 +170,7 @@ QtObject { property Notification imapConnectionModeChangeError: Notification { description: qsTr("The IMAP connection mode could not be changed.") - brief: qsTr("IMAP Connection mode change error") + brief: qsTr("IMAP Connection mode error") icon: "./icons/ic-alert.svg" type: Notification.NotificationType.Danger group: Notifications.Group.Connection @@ -196,7 +194,7 @@ QtObject { property Notification smtpConnectionModeChangeError: Notification { description: qsTr("The SMTP connection mode could not be changed.") - brief: qsTr("SMTP Connection mode change error") + brief: qsTr("SMTP Connection mode error") icon: "./icons/ic-alert.svg" type: Notification.NotificationType.Danger group: Notifications.Group.Connection @@ -227,7 +225,7 @@ QtObject { var link = Backend.releaseNotesLink return `${descr} ${text}` } - brief: qsTr("Update available.") + brief: qsTr("Update available") icon: "./icons/ic-info-circle-filled.svg" type: Notification.NotificationType.Info group: Notifications.Group.Update | Notifications.Group.Dialogs @@ -514,7 +512,7 @@ QtObject { // login property Notification loginConnectionError: Notification { description: qsTr("Bridge is not able to contact the server, please check your internet connection.") - brief: description + brief: qsTr("Connection error") icon: "./icons/ic-exclamation-circle-filled.svg" type: Notification.NotificationType.Danger group: Notifications.Group.Configuration @@ -538,7 +536,7 @@ QtObject { property Notification onlyPaidUsers: Notification { description: qsTr("Bridge is exclusive to our paid plans. Upgrade your account to use Bridge.") - brief: description + brief: qsTr("Upgrade your account") icon: "./icons/ic-exclamation-circle-filled.svg" type: Notification.NotificationType.Danger group: Notifications.Group.Configuration @@ -562,7 +560,7 @@ QtObject { property Notification alreadyLoggedIn: Notification { description: qsTr("This account is already signed in.") - brief: description + brief: qsTr("Already signed in") icon: "./icons/ic-exclamation-circle-filled.svg" type: Notification.NotificationType.Info group: Notifications.Group.Configuration @@ -587,7 +585,7 @@ QtObject { // Bug reports property Notification bugReportSendSuccess: Notification { description: qsTr("Thank you for the report. We'll get back to you as soon as we can.") - brief: description + brief: qsTr("Report sent") icon: "./icons/ic-info-circle-filled.svg" type: Notification.NotificationType.Success group: Notifications.Group.Configuration @@ -611,7 +609,7 @@ QtObject { property Notification bugReportSendError: Notification { description: qsTr("Report could not be sent. Try again or email us directly.") - brief: description + brief: qsTr("Error sending report") icon: "./icons/ic-exclamation-circle-filled.svg" type: Notification.NotificationType.Danger group: Notifications.Group.Configuration @@ -634,8 +632,8 @@ QtObject { // Cache property Notification cacheUnavailable: Notification { title: qsTr("Cache location is unavailable") - description: qsTr("Check the directory or change it in your settings.") - brief: qsTr("The current cache location is unavailable. Check the directory or change it in your settings.") + description: qsTr("The current cache location is unavailable. Check the directory or change it in your settings.") + brief: title icon: "./icons/ic-exclamation-circle-filled.svg" type: Notification.NotificationType.Warning group: Notifications.Group.Configuration | Notifications.Group.Dialogs @@ -725,7 +723,7 @@ QtObject { // Other property Notification accountChanged: Notification { description: qsTr("The address list for .... account has changed. You need to reconfigure your email client.") - brief: qsTr("The address list for your account has changed. Reconfigure your email client.") + brief: qsTr("Address list changed") icon: "./icons/ic-exclamation-circle-filled.svg" type: Notification.NotificationType.Danger group: Notifications.Group.Configuration @@ -742,7 +740,7 @@ QtObject { property Notification diskFull: Notification { title: qsTr("Your disk is almost full") description: qsTr("Quit Bridge and free disk space or disable the local cache (not recommended).") - brief: qsTr("Your disk is almost full. Free disk space or disable the local cache.") + brief: title icon: "./icons/ic-exclamation-circle-filled.svg" type: Notification.NotificationType.Warning group: Notifications.Group.Configuration | Notifications.Group.Dialogs @@ -948,8 +946,8 @@ QtObject { property Notification noKeychain: Notification { title: qsTr("No keychain available") - description: qsTr("Bridge is not able to detect a supported password manager (pass or secret-service). Please install and setup supported password manager and restart the application.") brief: title + description: qsTr("Bridge is not able to detect a supported password manager (pass or secret-service). Please install and setup supported password manager and restart the application.") icon: "./icons/ic-exclamation-circle-filled.svg" type: Notification.NotificationType.Danger group: Notifications.Group.Dialogs | Notifications.Group.Configuration @@ -982,13 +980,13 @@ QtObject { property Notification rebuildKeychain: Notification { title: qsTr("Your macOS keychain might be corrupted") - description: qsTr("Bridge is not able to access your macOS keychain. Please consult the instructions on our support page.") brief: title + description: qsTr("Bridge is not able to access your macOS keychain. Please consult the instructions on our support page.") icon: "./icons/ic-exclamation-circle-filled.svg" type: Notification.NotificationType.Danger group: Notifications.Group.Dialogs | Notifications.Group.Configuration - property var supportLink: "https://proton.me/support/mail" + property var supportLink: "https://proton.me/support/bridge" Connections { @@ -1014,8 +1012,8 @@ QtObject { property Notification addressChanged: Notification { title: qsTr("Address list changes") + brief: title description: qsTr("The address list for your account has changed. You might need to reconfigure your email client.") - brief: description icon: "./icons/ic-exclamation-circle-filled.svg" type: Notification.NotificationType.Warning group: Notifications.Group.Configuration @@ -1047,11 +1045,11 @@ QtObject { property Notification apiCertIssue: Notification { title: qsTr("Unable to establish a \nsecure connection to \nProton servers") + brief: qsTr("Cannot establish secure connection") description: qsTr("Bridge cannot verify the authenticity of Proton servers on your current network due to a TLS certificate error. " + "Start Bridge again after ensuring your connection is secure and/or connecting to a VPN. Learn more about TLS pinning " + "here.") - brief: title icon: "./icons/ic-exclamation-circle-filled.svg" type: Notification.NotificationType.Danger group: Notifications.Group.Dialogs | Notifications.Group.Connection @@ -1078,6 +1076,7 @@ QtObject { property Notification noActiveKeyForRecipient: Notification { title: qsTr("Unable to send \nencrypted message") + brief: title description: "#PlaceholderText#" icon: "./icons/ic-exclamation-circle-filled.svg" type: Notification.NotificationType.Danger @@ -1174,8 +1173,9 @@ QtObject { } property Notification genericError: Notification { - title: "#PlaceholderText#" - description: "#PlaceholderText#" + title: "" + brief: title + description: "" icon: "./icons/ic-exclamation-circle-filled.svg" type: Notification.NotificationType.Danger group: Notifications.Group.Dialogs @@ -1201,7 +1201,7 @@ QtObject { property Notification genericQuestion: Notification { title: "" - brief: "" + brief: title description: "" type: Notification.NotificationType.Warning group: Notifications.Group.Dialogs diff --git a/internal/frontend/bridge-gui/bridge-gui/qml/StatusWindow.qml b/internal/frontend/bridge-gui/bridge-gui/qml/StatusWindow.qml deleted file mode 100644 index 2269acaa..00000000 --- a/internal/frontend/bridge-gui/bridge-gui/qml/StatusWindow.qml +++ /dev/null @@ -1,352 +0,0 @@ -// Copyright (c) 2023 Proton AG -// -// This file is part of Proton Mail Bridge. -// -// Proton Mail Bridge is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// Proton Mail Bridge is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with Proton Mail Bridge. If not, see . - -import QtQml -import QtQuick -import QtQuick.Window -import QtQuick.Layouts -import QtQuick.Controls - -import Proton -import Notifications - -Window { - id: root - - height: contentLayout.implicitHeight - width: contentLayout.implicitWidth - - flags: (Qt.platform.os === "linux" ? Qt.Tool : 0) | Qt.FramelessWindowHint | Qt.NoDropShadowWindowHint | Qt.WindowStaysOnTopHint | Qt.WA_TranslucentBackground - color: "transparent" - - property ColorScheme colorScheme: ProtonStyle.currentStyle - - property var notifications - - signal showMainWindow() - signal showHelp() - signal showSettings() - signal selectUser(string userID) - signal quit() - - MouseArea { - id: mouseArea - anchors.fill: parent - hoverEnabled: true - } - - function enableHoverOnOpenBridgeButton() { - openBridgeButton.hoverEnabled = true - mouseArea.positionChanged.disconnect(enableHoverOnOpenBridgeButton) - } - - onVisibleChanged: { - if (visible) { // GODT-1479 To avoid a visual glitch where the 'Open bridge button' would appear hovered when the status windows opens, - // we've disabled hover on it when it was last closed. Re-enabling hover here will not work on all platforms. so we temporarily connect - // mouse move event over the window's mouseArea to a function that will re-enable hover on the open bridge button. - openBridgeButton.focus = false - mouseArea.positionChanged.connect(enableHoverOnOpenBridgeButton) - } else { - menu.close() - } - } - - ColumnLayout { - id: contentLayout - - Layout.minimumHeight: 201 - - anchors.fill: parent - spacing: 0 - - ColumnLayout { - Layout.minimumWidth: 448 - Layout.fillWidth: true - spacing: 0 - - Item { - implicitHeight: 12 - Layout.fillWidth: true - clip: true - Rectangle { - anchors.top: parent.top - anchors.left: parent.left - anchors.right: parent.right - height: parent.height * 2 - radius: ProtonStyle.dialog_radius - - color: { - if (!statusItem.activeNotification) { - return root.colorScheme.signal_success - } - - switch (statusItem.activeNotification.type) { - case Notification.NotificationType.Danger: - return root.colorScheme.signal_danger - case Notification.NotificationType.Warning: - return root.colorScheme.signal_warning - case Notification.NotificationType.Success: - return root.colorScheme.signal_success - case Notification.NotificationType.Info: - return root.colorScheme.signal_info - } - } - } - } - - Rectangle { - Layout.fillWidth: true - - implicitHeight: children[0].implicitHeight + children[0].anchors.topMargin + children[0].anchors.bottomMargin - implicitWidth: children[0].implicitWidth + children[0].anchors.leftMargin + children[0].anchors.rightMargin - - color: colorScheme.background_norm - - RowLayout { - anchors.fill: parent - - anchors.topMargin: 8 - anchors.bottomMargin: 8 - anchors.leftMargin: 24 - anchors.rightMargin: 24 - - spacing: 8 - - Status { - id: statusItem - - Layout.fillWidth: true - - Layout.topMargin: 12 - Layout.bottomMargin: 12 - - colorScheme: root.colorScheme - notifications: root.notifications - - notificationWhitelist: Notifications.Group.Connection | Notifications.Group.Update | Notifications.Group.Configuration - } - - Button { - colorScheme: root.colorScheme - secondary: true - - Layout.topMargin: 12 - Layout.bottomMargin: 12 - - visible: statusItem.activeNotification && statusItem.activeNotification.action.length > 0 - action: statusItem.activeNotification && statusItem.activeNotification.action.length > 0 ? statusItem.activeNotification.action[0] : null - } - } - } - - Rectangle { - Layout.fillWidth: true - height: 1 - color: root.colorScheme.background_norm - - Rectangle { - anchors.fill: parent - anchors.leftMargin: 24 - anchors.rightMargin: 24 - color: root.colorScheme.border_norm - } - } - } - - Rectangle { - Layout.fillWidth: true - Layout.fillHeight: true - - Layout.maximumHeight: accountListView.count ? - accountListView.contentHeight / accountListView.count * 3 + accountListView.anchors.topMargin + accountListView.anchors.bottomMargin : - Number.POSITIVE_INFINITY - - color: root.colorScheme.background_norm - clip: true - - implicitHeight: children[0].contentHeight + children[0].anchors.topMargin + children[0].anchors.bottomMargin - implicitWidth: children[0].contentWidth + children[0].anchors.leftMargin + children[0].anchors.rightMargin - - ListView { - id: accountListView - - model: Backend.users - anchors.fill: parent - - anchors.topMargin: 8 - anchors.bottomMargin: 8 - anchors.leftMargin: 24 - anchors.rightMargin: 24 - - interactive: contentHeight > parent.height - snapMode: ListView.SnapToItem - boundsBehavior: Flickable.StopAtBounds - - spacing: 4 - - delegate: Item { - id: viewItem - width: ListView.view.width - - implicitHeight: children[0].implicitHeight - implicitWidth: children[0].implicitWidth - - property var user: Backend.users.get(index) - - RowLayout { - spacing: 0 - anchors.fill: parent - - AccountDelegate { - Layout.fillWidth: true - - Layout.topMargin: 12 - Layout.bottomMargin: 12 - - user: viewItem.user - colorScheme: root.colorScheme - } - - Button { - Layout.topMargin: 12 - Layout.bottomMargin: 12 - - colorScheme: root.colorScheme - visible: viewItem.user ? (viewItem.user.state === EUserState.SignedOut) : false - text: qsTr("Sign in") - onClicked: { - root.selectUser(viewItem.user.id) // selectUser will show login screen if user is in SignedOut state. - root.close() - } - } - } - } - } - } - - Item { - Layout.fillWidth: true - - implicitHeight: children[1].implicitHeight + children[1].anchors.topMargin + children[1].anchors.bottomMargin - implicitWidth: children[1].implicitWidth + children[1].anchors.leftMargin + children[1].anchors.rightMargin - - // background: - clip: true - Rectangle { - anchors.bottom: parent.bottom - anchors.left: parent.left - anchors.right: parent.right - height: parent.height * 2 - radius: ProtonStyle.dialog_radius - - color: root.colorScheme.background_weak - } - - RowLayout { - anchors.fill: parent - anchors.margins: 8 - spacing: 0 - - Button { - id: openBridgeButton - colorScheme: root.colorScheme - secondary: true - text: qsTr("Open Bridge") - - borderless: true - labelType: Label.LabelType.Caption_semibold - - onClicked: { - // GODT-1479: we disable hover for the button to avoid a visual glitch where the button is - // wrongly hovered when re-opening the status window after clicking - hoverEnabled = false; - root.showMainWindow() - root.close() - } - } - - Item { - Layout.fillWidth: true - } - - Button { - colorScheme: root.colorScheme - secondary: true - icon.source: "/qml/icons/ic-three-dots-vertical.svg" - borderless: true - checkable: true - - onClicked: { - menu.open() - } - - Menu { - id: menu - colorScheme: root.colorScheme - modal: true - - y: 0 - height - - MenuItem { - colorScheme: root.colorScheme - text: qsTr("Help") - onClicked: { - root.showHelp() - root.close() - } - } - MenuItem { - colorScheme: root.colorScheme - text: qsTr("Settings") - onClicked: { - root.showSettings() - root.close() - } - } - MenuItem { - colorScheme: root.colorScheme - text: qsTr("Quit Bridge") - onClicked: { - root.close() - root.quit() - } - } - - onClosed: { - parent.checked = false - } - onOpened: { - parent.checked = true - } - } - } - } - } - } - - onActiveChanged: { - if (!active) root.close() - } - - function showAndRise() { - root.show() - root.raise() - if (!root.active) { - root.requestActivate() - } - } -} diff --git a/internal/frontend/bridge-gui/bridge-gui/qml/icons/ic-dot.svg b/internal/frontend/bridge-gui/bridge-gui/qml/icons/ic-dot.svg new file mode 100644 index 00000000..d025c3ef --- /dev/null +++ b/internal/frontend/bridge-gui/bridge-gui/qml/icons/ic-dot.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/internal/frontend/bridge-gui/bridgepp/CMakeLists.txt b/internal/frontend/bridge-gui/bridgepp/CMakeLists.txt index af03519a..fafd1c25 100644 --- a/internal/frontend/bridge-gui/bridgepp/CMakeLists.txt +++ b/internal/frontend/bridge-gui/bridgepp/CMakeLists.txt @@ -160,3 +160,41 @@ target_link_libraries(bridgepp ) target_precompile_headers(bridgepp PRIVATE Pch.h) + +#***************************************************************************************************************************************************** +# GoogleTest +#***************************************************************************************************************************************************** + +if (CMAKE_VERSION VERSION_GREATER_EQUAL "3.24.0") + cmake_policy(SET CMP0135 NEW) # avoid warning DOWNLOAD_EXTRACT_TIMESTAMP +endif() + +include(FetchContent) +FetchContent_Declare( + googletest + URL https://github.com/google/googletest/archive/b796f7d44681514f58a683a3a71ff17c94edb0c1.zip +) + +# For Windows: Prevent overriding the parent project's compiler/linker settings +set(gtest_force_shared_crt ON CACHE BOOL "" FORCE) + +FetchContent_MakeAvailable(googletest) + +enable_testing() + +#***************************************************************************************************************************************************** +# Tests +#***************************************************************************************************************************************************** +add_executable(bridgepp-test + Test/TestBridgeUtils.cpp + Test/TestException.cpp + Test/TestWorker.cpp Test/TestWorker.h) +add_dependencies(bridgepp-test bridgepp) +target_precompile_headers(bridgepp-test PRIVATE Pch.h) +target_link_libraries(bridgepp-test + GTest::gtest_main + bridgepp + ) + +include(GoogleTest) +gtest_discover_tests(bridgepp-test) diff --git a/internal/frontend/bridge-gui/bridgepp/Test/TestBridgeUtils.cpp b/internal/frontend/bridge-gui/bridgepp/Test/TestBridgeUtils.cpp new file mode 100644 index 00000000..a990eb66 --- /dev/null +++ b/internal/frontend/bridge-gui/bridgepp/Test/TestBridgeUtils.cpp @@ -0,0 +1,111 @@ +// Copyright (c) 2023 Proton AG +// +// This file is part of Proton Mail Bridge. +// +// Proton Mail Bridge is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Proton Mail Bridge is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Proton Mail Bridge. If not, see . + + +#include +#include + + +using namespace bridgepp; + + +//**************************************************************************************************************************************************** +// +//**************************************************************************************************************************************************** +TEST(BridgeUtils, OS) { +#ifdef Q_OS_MACOS + EXPECT_EQ(os(), OS::MacOS); + EXPECT_FALSE(onLinux()); + EXPECT_TRUE(onMacOS()); + EXPECT_FALSE(onWindows()); + EXPECT_EQ(goos(), "darwin"); + return; +#endif + +#ifdef Q_OS_WIN + EXPECT_EQ(os(), OS::Windows); + EXPECT_FALSE(onLinux()); + EXPECT_FALSE(onMacOS()); + EXPECT_TRUE(onWindows()); + EXPECT_EQ(goos(), "windows"); + return; +#endif + +#ifdef Q_OS_LINUX + EXPECT_EQ(os(), OS::Linux); + EXPECT_TRUE(onLinux()); + EXPECT_FALSE(onMacOS()); + EXPECT_FALSE(onWindows()); + EXPECT_EQ(goos(), "linux"); + return; +#endif + + EXPECT_TRUE(false); // should be unreachable. +} + +//**************************************************************************************************************************************************** +// +//**************************************************************************************************************************************************** +TEST(BridgeUtils, UserFolders) { + typedef QString (*dirFunction)(); + QList functions = { userConfigDir, userCacheDir, userDataDir, sentryCacheDir }; + QString path; + for (dirFunction f: functions) { + EXPECT_NO_THROW(path = f()); + EXPECT_FALSE(path.isEmpty()); + EXPECT_TRUE(QDir(path).exists()); + } +} + + +//**************************************************************************************************************************************************** +// +//**************************************************************************************************************************************************** +TEST(BridgeUtils, Random) { + qint32 repeatCount = 1000; + qint32 const maxValue = 5; + for (qint32 i = 0; i < repeatCount; ++i) { + qint64 n = 0; + EXPECT_NO_THROW(n = randN(maxValue)); + EXPECT_TRUE((n >= 0) && (n < maxValue)); + QString name; + EXPECT_NO_THROW(name = randomFirstName()); + EXPECT_FALSE(name.isEmpty()); + EXPECT_NO_THROW(name = randomLastName()); + EXPECT_FALSE(name.isEmpty()); + EXPECT_NO_THROW(randomUser()); + } +} + + +//**************************************************************************************************************************************************** +// +//**************************************************************************************************************************************************** +TEST(BridgeUtils, ElideLongString) { + std::function const test = [](QString const &input, qint32 maxLength, QString const &expected) -> bool { + QString output; + EXPECT_NO_THROW(output = elideLongString(input, maxLength)); + return output == expected; + }; + + EXPECT_TRUE(test( "", 0, "")); + EXPECT_TRUE(test("1234", 4, "1234")); + EXPECT_TRUE(test("123", 2, "...")); + EXPECT_TRUE(test("1234567890", 8, "12...90")); + EXPECT_TRUE(test("1234567890", 10, "1234567890")); + EXPECT_TRUE(test("1234567890", 100, "1234567890")); +} diff --git a/internal/frontend/bridge-gui/bridgepp/Test/TestException.cpp b/internal/frontend/bridge-gui/bridgepp/Test/TestException.cpp new file mode 100644 index 00000000..9c006f56 --- /dev/null +++ b/internal/frontend/bridge-gui/bridgepp/Test/TestException.cpp @@ -0,0 +1,95 @@ +// Copyright (c) 2023 Proton AG +// +// This file is part of Proton Mail Bridge. +// +// Proton Mail Bridge is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Proton Mail Bridge is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Proton Mail Bridge. If not, see . + +#include +#include + + +using namespace bridgepp; + + +namespace { + QString const testQWhat = "What"; + QString const testDetails = "Some details"; + QString const testFunction = "function"; + QByteArray const testAttachment = QString("Some data").toLocal8Bit(); + Exception const testException(testQWhat, testDetails, testFunction, testAttachment); +} + + +//**************************************************************************************************************************************************** +// +//**************************************************************************************************************************************************** +TEST(Exceptions, ExceptionConstructor) { + // Default exception + Exception const emptyException; + EXPECT_TRUE(emptyException.qwhat().isEmpty()); + EXPECT_EQ(strlen(emptyException.what()), 0); + EXPECT_EQ(emptyException.attachment().size(), 0); + EXPECT_TRUE(emptyException.details().isEmpty()); + EXPECT_TRUE(emptyException.detailedWhat().isEmpty()); + + // Fully detailed exception + EXPECT_EQ(testException.qwhat(), testQWhat); + EXPECT_EQ(QString::fromLocal8Bit(testException.what()), testQWhat); + EXPECT_EQ(testException.details(), testDetails); + EXPECT_EQ(testException.attachment(), testAttachment); + QString const detailed = testException.detailedWhat(); + EXPECT_TRUE(detailed.contains(testQWhat)); + EXPECT_TRUE(detailed.contains(testFunction)); + EXPECT_TRUE(detailed.contains(testDetails)); +} + + +//**************************************************************************************************************************************************** +// +//**************************************************************************************************************************************************** +TEST(Exceptions, ExceptionCopyMoveConstructors) { + Exception const e(testQWhat, testDetails, testFunction, testAttachment); + + // Check copy-constructor + Exception eCopied(e); + EXPECT_EQ(eCopied.qwhat(), testQWhat); + EXPECT_EQ(eCopied.details(), testDetails); + EXPECT_EQ(eCopied.function(), testFunction); + EXPECT_EQ(eCopied.attachment(), testAttachment); + + // Check move-constructor + Exception eMoved(std::move(eCopied)); + EXPECT_EQ(eMoved.qwhat(), testQWhat); + EXPECT_EQ(eMoved.details(), testDetails); + EXPECT_EQ(eMoved.function(), testFunction); + EXPECT_EQ(eMoved.attachment(), testAttachment); +} + + +//**************************************************************************************************************************************************** +// +//**************************************************************************************************************************************************** +TEST(Exceptions, ExceptionThrow) { + std::function t = []() { throw testException; }; + EXPECT_THROW(t(), Exception); + EXPECT_THROW(t(), std::exception); + bool caught = false; + try { + t(); + } catch (Exception const &e) { + caught = true; + EXPECT_EQ(e.detailedWhat(), testException.detailedWhat()); + } + EXPECT_TRUE(caught); +} diff --git a/internal/frontend/bridge-gui/bridgepp/Test/TestWorker.cpp b/internal/frontend/bridge-gui/bridgepp/Test/TestWorker.cpp new file mode 100644 index 00000000..6f6eb5bb --- /dev/null +++ b/internal/frontend/bridge-gui/bridgepp/Test/TestWorker.cpp @@ -0,0 +1,215 @@ +// Copyright (c) 2023 Proton AG +// +// This file is part of Proton Mail Bridge. +// +// Proton Mail Bridge is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Proton Mail Bridge is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Proton Mail Bridge. If not, see . + +// clazy:excludeall=lambda-in-connect + +#include "TestWorker.h" +#include +#include + + +using namespace bridgepp; + + +namespace { + + +qint32 dummyArgc = 1; ///< A dummy int value because QCoreApplication constructor requires a reference to it. + + +} + + +//**************************************************************************************************************************************************** +// +//**************************************************************************************************************************************************** +Workers::Workers() + : testing::Test() + , app_(dummyArgc, nullptr) { +} + + +//**************************************************************************************************************************************************** +// +//**************************************************************************************************************************************************** +void Workers::SetUp() { + Test::SetUp(); + + EXPECT_NO_THROW(worker_ = new TestWorker); + + QObject::connect(worker_, &TestWorker::started, [&]() { results_.started = true; }); + QObject::connect(worker_, &TestWorker::finished, [&]() { results_.finished = true; }); + QObject::connect(worker_, &TestWorker::finished, &loop_, &QEventLoop::quit); + QObject::connect(worker_, &TestWorker::error, [&] { results_.error = true; }); + QObject::connect(worker_, &TestWorker::error, &loop_, &QEventLoop::quit); + QObject::connect(worker_, &TestWorker::error, [&] { results_.error = true; }); + QObject::connect(worker_, &TestWorker::error, &loop_, &QEventLoop::quit); + QObject::connect(worker_, &TestWorker::cancelled, [&] { results_.cancelled = true; }); + QObject::connect(worker_, &TestWorker::cancelled, &loop_, &QEventLoop::quit); + + overseer_ = std::make_unique(worker_, nullptr); +} + + +//**************************************************************************************************************************************************** +// +//**************************************************************************************************************************************************** +void Workers::TearDown() { + EXPECT_NO_FATAL_FAILURE(overseer_.reset()); + Test::TearDown(); +} + + +//**************************************************************************************************************************************************** +/// \param[in] lifetimeMs The lifetime of the worker in milliseconds. +/// \param[in] willSucceed Will the worker succeed (emit finished) or fail (emit error). +//**************************************************************************************************************************************************** +TestWorker::TestWorker() + : Worker(nullptr) { +} + + +//**************************************************************************************************************************************************** +/// \param[in] lifetimeMs The lifetime of the worker in milliseconds. +//**************************************************************************************************************************************************** +void TestWorker::setLifetime(qint64 lifetimeMs) { + lifetimeMs_ = lifetimeMs; +} + + +//**************************************************************************************************************************************************** +/// \param[in] willSucceed Will the worker succeed? +//**************************************************************************************************************************************************** +void TestWorker::setWillSucceed(bool willSucceed) { + willSucceed_ = willSucceed; +} + + +//**************************************************************************************************************************************************** +// +//**************************************************************************************************************************************************** +void TestWorker::run() { + emit started(); + + QElapsedTimer timer; + timer.start(); + while (true) { + if (cancelled_.loadRelaxed()) { + emit cancelled(); + return; + } + if (timer.elapsed() >= lifetimeMs_) { + break; + } + } + + if (willSucceed_) { + emit finished(); + } else { + emit error(QString()); + } +} + + +//**************************************************************************************************************************************************** +// +//**************************************************************************************************************************************************** +void TestWorker::cancel() { + cancelled_.storeRelaxed(1); +} + + +//**************************************************************************************************************************************************** +// +//**************************************************************************************************************************************************** +TEST_F(Workers, SuccessfulWorker) { + worker_->setLifetime(10); + worker_->setWillSucceed(true); + + EXPECT_NO_THROW(overseer_->startWorker(false)); + EXPECT_NO_THROW(loop_.exec()); + + EXPECT_TRUE(results_.started); + EXPECT_TRUE(results_.finished); + EXPECT_FALSE(results_.error); + EXPECT_FALSE(results_.cancelled); + + EXPECT_TRUE(overseer_->worker() != nullptr); // overseer started without autorelease. +} + + +//**************************************************************************************************************************************************** +// +//**************************************************************************************************************************************************** +TEST_F(Workers, ErrorWorker) { + worker_->setLifetime(10); + worker_->setWillSucceed(false); + + EXPECT_NO_THROW(overseer_->startWorker(true)); + EXPECT_NO_THROW(loop_.exec()); + + EXPECT_TRUE(results_.started); + EXPECT_FALSE(results_.finished); + EXPECT_TRUE(results_.error); + EXPECT_FALSE(results_.cancelled); + + EXPECT_TRUE(overseer_->worker() == nullptr); // overseer started with autorelease. +} + +//**************************************************************************************************************************************************** +// +//**************************************************************************************************************************************************** +TEST_F(Workers, CancelledWorker) { + worker_->setLifetime(10000); + worker_->setWillSucceed(true); + EXPECT_NO_THROW(overseer_->startWorker(false)); + EXPECT_NO_THROW(QTimer::singleShot(10, [&]() { worker_->cancel(); })); + + EXPECT_NO_THROW(loop_.exec()); + + EXPECT_TRUE(results_.started); + EXPECT_FALSE(results_.finished); + EXPECT_FALSE(results_.error); + EXPECT_TRUE(results_.cancelled); +} + + +//**************************************************************************************************************************************************** +// +//**************************************************************************************************************************************************** +TEST_F(Workers, Wait) { + worker_->setLifetime(10000); + worker_->setWillSucceed(true); + overseer_->startWorker(true); + + bool isFinished = false; + EXPECT_NO_THROW(isFinished = overseer_->isFinished()); + EXPECT_FALSE(isFinished); + + EXPECT_NO_THROW(isFinished = overseer_->wait(10)); + EXPECT_FALSE(isFinished); + + worker_->cancel(); + + EXPECT_NO_THROW(isFinished = overseer_->wait(10000)); + EXPECT_TRUE(isFinished); + + EXPECT_NO_THROW(isFinished = overseer_->isFinished()); + EXPECT_TRUE(isFinished); +} + + diff --git a/internal/frontend/bridge-gui/bridgepp/Test/TestWorker.h b/internal/frontend/bridge-gui/bridgepp/Test/TestWorker.h new file mode 100644 index 00000000..abfde90c --- /dev/null +++ b/internal/frontend/bridge-gui/bridgepp/Test/TestWorker.h @@ -0,0 +1,88 @@ +// Copyright (c) 2023 Proton AG +// +// This file is part of Proton Mail Bridge. +// +// Proton Mail Bridge is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Proton Mail Bridge is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Proton Mail Bridge. If not, see . + + +#ifndef BRIDGE_GUI_TEST_WORKER_H +#define BRIDGE_GUI_TEST_WORKER_H + + +#include +#include + + +//**************************************************************************************************************************************************** +/// \brief Test worker class. +/// +/// This worker simply waits: +/// - For a specified amount of time and will succeed (emit finished()) or fail (emit error()) based on its parameters. +/// - to be cancelled (and will emit cancelled in that case). +//**************************************************************************************************************************************************** +class TestWorker : public bridgepp::Worker { +Q_OBJECT +public: // member functions. + TestWorker(); ///< Default constructor. + TestWorker(TestWorker const &) = delete; ///< Disabled copy-constructor. + TestWorker(TestWorker &&) = delete; ///< Disabled assignment copy-constructor. + ~TestWorker() override = default; ///< Destructor. + TestWorker &operator=(TestWorker const &) = delete; ///< Disabled assignment operator. + TestWorker &operator=(TestWorker &&) = delete; ///< Disabled move assignment operator. + void setLifetime(qint64 lifetimeMs); ///< Set the lifetime of the worker. + void setWillSucceed(bool willSucceed); ///< Set if the worker will succeed. + void run() override; ///< Run the worker. + void cancel(); ///< Cancel the worker. + +private: // data members + qint64 lifetimeMs_ { 10 }; ///< The lifetime of the worker in milliseconds. + bool willSucceed_ { true }; ///< Will the worker succeed? + QAtomicInteger cancelled_; ///< Has the worker been cancelled. +}; + + +//**************************************************************************************************************************************************** +/// \brief Fixture class for worker tests. +//**************************************************************************************************************************************************** +class Workers : public testing::Test { +public: // member functions. + Workers(); ///< Default constructor. + Workers(Workers const &) = delete; ///< Disabled copy-constructor. + Workers(Workers &&) = delete; ///< Disabled assignment copy-constructor. + ~Workers() = default; ///< Destructor. + Workers &operator=(Workers const &) = delete; ///< Disabled assignment operator. + Workers &operator=(Workers &&) = delete; ///< Disabled move assignment operator. + +protected: // member functions. + void SetUp() override; ///< Setup the fixture. + void TearDown() override; ///< Tear down the fixture. + +protected: // data type + struct Results { + bool started { false }; + bool finished { false }; + bool error { false }; + bool cancelled { false }; + }; ///< Test results data type + +protected: // data members + QCoreApplication app_; ///< The Qt application required for event loop. + bridgepp::UPOverseer overseer_; ///< The overseer for the worker. + TestWorker *worker_ { nullptr }; ///< The worker. + QEventLoop loop_; ///< The event loop. + Results results_; ///< The test results. +}; + + +#endif //BRIDGE_GUI_TEST_WORKER_H diff --git a/internal/frontend/bridge-gui/bridgepp/bridgepp/BridgeUtils.h b/internal/frontend/bridge-gui/bridgepp/bridgepp/BridgeUtils.h index 280a0de9..1ca92901 100644 --- a/internal/frontend/bridge-gui/bridgepp/bridgepp/BridgeUtils.h +++ b/internal/frontend/bridge-gui/bridgepp/bridgepp/BridgeUtils.h @@ -20,7 +20,7 @@ #define BRIDGE_PP_TESTER_BRIDGE_UTILS_H -#include +#include "User/User.h" namespace bridgepp { diff --git a/internal/frontend/bridge-gui/bridgepp/bridgepp/Exception/Exception.cpp b/internal/frontend/bridge-gui/bridgepp/bridgepp/Exception/Exception.cpp index dc614b88..db43cac0 100644 --- a/internal/frontend/bridge-gui/bridgepp/bridgepp/Exception/Exception.cpp +++ b/internal/frontend/bridge-gui/bridgepp/bridgepp/Exception/Exception.cpp @@ -87,6 +87,14 @@ QString Exception::details() const noexcept { } +//**************************************************************************************************************************************************** +/// \return The function that threw the exception. +//**************************************************************************************************************************************************** +QString Exception::function() const noexcept { + return function_; +} + + //**************************************************************************************************************************************************** /// \return The attachment for the exception. //**************************************************************************************************************************************************** @@ -109,4 +117,5 @@ QString Exception::detailedWhat() const { return result; } + } // namespace bridgepp diff --git a/internal/frontend/bridge-gui/bridgepp/bridgepp/Exception/Exception.h b/internal/frontend/bridge-gui/bridgepp/bridgepp/Exception/Exception.h index 21a1689d..3b78821f 100644 --- a/internal/frontend/bridge-gui/bridgepp/bridgepp/Exception/Exception.h +++ b/internal/frontend/bridge-gui/bridgepp/bridgepp/Exception/Exception.h @@ -42,6 +42,7 @@ public: // member functions QString qwhat() const noexcept; ///< Return the description of the exception as a QString const char *what() const noexcept override; ///< Return the description of the exception as C style string QString details() const noexcept; ///< Return the details for the exception + QString function() const noexcept; ///< Return the function that threw the exception. QByteArray attachment() const noexcept; ///< Return the attachment for the exception. QString detailedWhat() const; ///< Return the detailed description of the message (i.e. including the function name and the details). diff --git a/internal/frontend/bridge-gui/bridgepp/bridgepp/GRPC/GRPCClient.cpp b/internal/frontend/bridge-gui/bridgepp/bridgepp/GRPC/GRPCClient.cpp index 350b78bd..34038c49 100644 --- a/internal/frontend/bridge-gui/bridgepp/bridgepp/GRPC/GRPCClient.cpp +++ b/internal/frontend/bridge-gui/bridgepp/bridgepp/GRPC/GRPCClient.cpp @@ -19,7 +19,6 @@ #include "GRPCClient.h" #include "GRPCUtils.h" #include "GRPCErrors.h" -#include "../BridgeUtils.h" #include "../Exception/Exception.h" #include "../ProcessMonitor.h" #include "../Log/LogUtils.h" @@ -295,6 +294,24 @@ grpc::Status GRPCClient::isAllMailVisible(bool &outIsVisible) { } +//**************************************************************************************************************************************************** +/// \param[out] outIsDisabled The value for the property +/// \return The status for the gRPC call. +//**************************************************************************************************************************************************** +grpc::Status GRPCClient::isTelemetryDisabled(bool &outIsDisabled) { + return this->logGRPCCallStatus(this->getBool(&Bridge::Stub::IsTelemetryDisabled, outIsDisabled), __FUNCTION__); +} + + +//**************************************************************************************************************************************************** +/// \param[out] isDisabled The new value for the property +/// \return The status for the gRPC call. +//**************************************************************************************************************************************************** +grpc::Status GRPCClient::setIsTelemetryDisabled(bool isDisabled) { + return this->logGRPCCallStatus(this->setBool(&Bridge::Stub::SetIsTelemetryDisabled, isDisabled), __FUNCTION__); +} + + //**************************************************************************************************************************************************** /// \param[in] isVisible The new value for the property. /// \return The status for the gRPC call. diff --git a/internal/frontend/bridge-gui/bridgepp/bridgepp/GRPC/GRPCClient.h b/internal/frontend/bridge-gui/bridgepp/bridgepp/GRPC/GRPCClient.h index 6a8a1a21..6485ce80 100644 --- a/internal/frontend/bridge-gui/bridgepp/bridgepp/GRPC/GRPCClient.h +++ b/internal/frontend/bridge-gui/bridgepp/bridgepp/GRPC/GRPCClient.h @@ -71,6 +71,8 @@ public: // member functions. grpc::Status setIsBetaEnabled(bool enabled); ///< Performs the 'setIsBetaEnabled' gRPC call. grpc::Status isAllMailVisible(bool &outIsVisible); ///< Performs the "isAllMailVisible" gRPC call. grpc::Status setIsAllMailVisible(bool isVisible); ///< Performs the 'setIsAllMailVisible' gRPC call. + grpc::Status isTelemetryDisabled(bool &outIsDisabled); ///< Performs the 'setIsTelemetryDisabled' gRPC call. + grpc::Status setIsTelemetryDisabled(bool isDisabled); ///< Performs the 'isTelemetryDisabled' gRPC call. grpc::Status colorSchemeName(QString &outName); ///< Performs the "colorSchemeName' gRPC call. grpc::Status setColorSchemeName(QString const &name); ///< Performs the "setColorSchemeName' gRPC call. grpc::Status currentEmailClient(QString &outName); ///< Performs the 'currentEmailClient' gRPC call. diff --git a/internal/frontend/bridge-gui/bridgepp/bridgepp/GRPC/bridge.grpc.pb.cc b/internal/frontend/bridge-gui/bridgepp/bridgepp/GRPC/bridge.grpc.pb.cc index b8270a02..53beac31 100644 --- a/internal/frontend/bridge-gui/bridgepp/bridgepp/GRPC/bridge.grpc.pb.cc +++ b/internal/frontend/bridge-gui/bridgepp/bridgepp/GRPC/bridge.grpc.pb.cc @@ -34,6 +34,8 @@ static const char* Bridge_method_names[] = { "/grpc.Bridge/IsBetaEnabled", "/grpc.Bridge/SetIsAllMailVisible", "/grpc.Bridge/IsAllMailVisible", + "/grpc.Bridge/SetIsTelemetryDisabled", + "/grpc.Bridge/IsTelemetryDisabled", "/grpc.Bridge/GoOs", "/grpc.Bridge/TriggerReset", "/grpc.Bridge/Version", @@ -98,49 +100,51 @@ Bridge::Stub::Stub(const std::shared_ptr< ::grpc::ChannelInterface>& channel, co , rpcmethod_IsBetaEnabled_(Bridge_method_names[9], options.suffix_for_stats(),::grpc::internal::RpcMethod::NORMAL_RPC, channel) , rpcmethod_SetIsAllMailVisible_(Bridge_method_names[10], options.suffix_for_stats(),::grpc::internal::RpcMethod::NORMAL_RPC, channel) , rpcmethod_IsAllMailVisible_(Bridge_method_names[11], options.suffix_for_stats(),::grpc::internal::RpcMethod::NORMAL_RPC, channel) - , rpcmethod_GoOs_(Bridge_method_names[12], options.suffix_for_stats(),::grpc::internal::RpcMethod::NORMAL_RPC, channel) - , rpcmethod_TriggerReset_(Bridge_method_names[13], options.suffix_for_stats(),::grpc::internal::RpcMethod::NORMAL_RPC, channel) - , rpcmethod_Version_(Bridge_method_names[14], options.suffix_for_stats(),::grpc::internal::RpcMethod::NORMAL_RPC, channel) - , rpcmethod_LogsPath_(Bridge_method_names[15], options.suffix_for_stats(),::grpc::internal::RpcMethod::NORMAL_RPC, channel) - , rpcmethod_LicensePath_(Bridge_method_names[16], options.suffix_for_stats(),::grpc::internal::RpcMethod::NORMAL_RPC, channel) - , rpcmethod_ReleaseNotesPageLink_(Bridge_method_names[17], options.suffix_for_stats(),::grpc::internal::RpcMethod::NORMAL_RPC, channel) - , rpcmethod_DependencyLicensesLink_(Bridge_method_names[18], options.suffix_for_stats(),::grpc::internal::RpcMethod::NORMAL_RPC, channel) - , rpcmethod_LandingPageLink_(Bridge_method_names[19], options.suffix_for_stats(),::grpc::internal::RpcMethod::NORMAL_RPC, channel) - , rpcmethod_SetColorSchemeName_(Bridge_method_names[20], options.suffix_for_stats(),::grpc::internal::RpcMethod::NORMAL_RPC, channel) - , rpcmethod_ColorSchemeName_(Bridge_method_names[21], options.suffix_for_stats(),::grpc::internal::RpcMethod::NORMAL_RPC, channel) - , rpcmethod_CurrentEmailClient_(Bridge_method_names[22], options.suffix_for_stats(),::grpc::internal::RpcMethod::NORMAL_RPC, channel) - , rpcmethod_ReportBug_(Bridge_method_names[23], options.suffix_for_stats(),::grpc::internal::RpcMethod::NORMAL_RPC, channel) - , rpcmethod_ExportTLSCertificates_(Bridge_method_names[24], options.suffix_for_stats(),::grpc::internal::RpcMethod::NORMAL_RPC, channel) - , rpcmethod_ForceLauncher_(Bridge_method_names[25], options.suffix_for_stats(),::grpc::internal::RpcMethod::NORMAL_RPC, channel) - , rpcmethod_SetMainExecutable_(Bridge_method_names[26], options.suffix_for_stats(),::grpc::internal::RpcMethod::NORMAL_RPC, channel) - , rpcmethod_Login_(Bridge_method_names[27], options.suffix_for_stats(),::grpc::internal::RpcMethod::NORMAL_RPC, channel) - , rpcmethod_Login2FA_(Bridge_method_names[28], options.suffix_for_stats(),::grpc::internal::RpcMethod::NORMAL_RPC, channel) - , rpcmethod_Login2Passwords_(Bridge_method_names[29], options.suffix_for_stats(),::grpc::internal::RpcMethod::NORMAL_RPC, channel) - , rpcmethod_LoginAbort_(Bridge_method_names[30], options.suffix_for_stats(),::grpc::internal::RpcMethod::NORMAL_RPC, channel) - , rpcmethod_CheckUpdate_(Bridge_method_names[31], options.suffix_for_stats(),::grpc::internal::RpcMethod::NORMAL_RPC, channel) - , rpcmethod_InstallUpdate_(Bridge_method_names[32], options.suffix_for_stats(),::grpc::internal::RpcMethod::NORMAL_RPC, channel) - , rpcmethod_SetIsAutomaticUpdateOn_(Bridge_method_names[33], options.suffix_for_stats(),::grpc::internal::RpcMethod::NORMAL_RPC, channel) - , rpcmethod_IsAutomaticUpdateOn_(Bridge_method_names[34], options.suffix_for_stats(),::grpc::internal::RpcMethod::NORMAL_RPC, channel) - , rpcmethod_DiskCachePath_(Bridge_method_names[35], options.suffix_for_stats(),::grpc::internal::RpcMethod::NORMAL_RPC, channel) - , rpcmethod_SetDiskCachePath_(Bridge_method_names[36], options.suffix_for_stats(),::grpc::internal::RpcMethod::NORMAL_RPC, channel) - , rpcmethod_SetIsDoHEnabled_(Bridge_method_names[37], options.suffix_for_stats(),::grpc::internal::RpcMethod::NORMAL_RPC, channel) - , rpcmethod_IsDoHEnabled_(Bridge_method_names[38], options.suffix_for_stats(),::grpc::internal::RpcMethod::NORMAL_RPC, channel) - , rpcmethod_MailServerSettings_(Bridge_method_names[39], options.suffix_for_stats(),::grpc::internal::RpcMethod::NORMAL_RPC, channel) - , rpcmethod_SetMailServerSettings_(Bridge_method_names[40], options.suffix_for_stats(),::grpc::internal::RpcMethod::NORMAL_RPC, channel) - , rpcmethod_Hostname_(Bridge_method_names[41], options.suffix_for_stats(),::grpc::internal::RpcMethod::NORMAL_RPC, channel) - , rpcmethod_IsPortFree_(Bridge_method_names[42], options.suffix_for_stats(),::grpc::internal::RpcMethod::NORMAL_RPC, channel) - , rpcmethod_AvailableKeychains_(Bridge_method_names[43], options.suffix_for_stats(),::grpc::internal::RpcMethod::NORMAL_RPC, channel) - , rpcmethod_SetCurrentKeychain_(Bridge_method_names[44], options.suffix_for_stats(),::grpc::internal::RpcMethod::NORMAL_RPC, channel) - , rpcmethod_CurrentKeychain_(Bridge_method_names[45], options.suffix_for_stats(),::grpc::internal::RpcMethod::NORMAL_RPC, channel) - , rpcmethod_GetUserList_(Bridge_method_names[46], options.suffix_for_stats(),::grpc::internal::RpcMethod::NORMAL_RPC, channel) - , rpcmethod_GetUser_(Bridge_method_names[47], options.suffix_for_stats(),::grpc::internal::RpcMethod::NORMAL_RPC, channel) - , rpcmethod_SetUserSplitMode_(Bridge_method_names[48], options.suffix_for_stats(),::grpc::internal::RpcMethod::NORMAL_RPC, channel) - , rpcmethod_SendBadEventUserFeedback_(Bridge_method_names[49], options.suffix_for_stats(),::grpc::internal::RpcMethod::NORMAL_RPC, channel) - , rpcmethod_LogoutUser_(Bridge_method_names[50], options.suffix_for_stats(),::grpc::internal::RpcMethod::NORMAL_RPC, channel) - , rpcmethod_RemoveUser_(Bridge_method_names[51], options.suffix_for_stats(),::grpc::internal::RpcMethod::NORMAL_RPC, channel) - , rpcmethod_ConfigureUserAppleMail_(Bridge_method_names[52], options.suffix_for_stats(),::grpc::internal::RpcMethod::NORMAL_RPC, channel) - , rpcmethod_RunEventStream_(Bridge_method_names[53], options.suffix_for_stats(),::grpc::internal::RpcMethod::SERVER_STREAMING, channel) - , rpcmethod_StopEventStream_(Bridge_method_names[54], options.suffix_for_stats(),::grpc::internal::RpcMethod::NORMAL_RPC, channel) + , rpcmethod_SetIsTelemetryDisabled_(Bridge_method_names[12], options.suffix_for_stats(),::grpc::internal::RpcMethod::NORMAL_RPC, channel) + , rpcmethod_IsTelemetryDisabled_(Bridge_method_names[13], options.suffix_for_stats(),::grpc::internal::RpcMethod::NORMAL_RPC, channel) + , rpcmethod_GoOs_(Bridge_method_names[14], options.suffix_for_stats(),::grpc::internal::RpcMethod::NORMAL_RPC, channel) + , rpcmethod_TriggerReset_(Bridge_method_names[15], options.suffix_for_stats(),::grpc::internal::RpcMethod::NORMAL_RPC, channel) + , rpcmethod_Version_(Bridge_method_names[16], options.suffix_for_stats(),::grpc::internal::RpcMethod::NORMAL_RPC, channel) + , rpcmethod_LogsPath_(Bridge_method_names[17], options.suffix_for_stats(),::grpc::internal::RpcMethod::NORMAL_RPC, channel) + , rpcmethod_LicensePath_(Bridge_method_names[18], options.suffix_for_stats(),::grpc::internal::RpcMethod::NORMAL_RPC, channel) + , rpcmethod_ReleaseNotesPageLink_(Bridge_method_names[19], options.suffix_for_stats(),::grpc::internal::RpcMethod::NORMAL_RPC, channel) + , rpcmethod_DependencyLicensesLink_(Bridge_method_names[20], options.suffix_for_stats(),::grpc::internal::RpcMethod::NORMAL_RPC, channel) + , rpcmethod_LandingPageLink_(Bridge_method_names[21], options.suffix_for_stats(),::grpc::internal::RpcMethod::NORMAL_RPC, channel) + , rpcmethod_SetColorSchemeName_(Bridge_method_names[22], options.suffix_for_stats(),::grpc::internal::RpcMethod::NORMAL_RPC, channel) + , rpcmethod_ColorSchemeName_(Bridge_method_names[23], options.suffix_for_stats(),::grpc::internal::RpcMethod::NORMAL_RPC, channel) + , rpcmethod_CurrentEmailClient_(Bridge_method_names[24], options.suffix_for_stats(),::grpc::internal::RpcMethod::NORMAL_RPC, channel) + , rpcmethod_ReportBug_(Bridge_method_names[25], options.suffix_for_stats(),::grpc::internal::RpcMethod::NORMAL_RPC, channel) + , rpcmethod_ExportTLSCertificates_(Bridge_method_names[26], options.suffix_for_stats(),::grpc::internal::RpcMethod::NORMAL_RPC, channel) + , rpcmethod_ForceLauncher_(Bridge_method_names[27], options.suffix_for_stats(),::grpc::internal::RpcMethod::NORMAL_RPC, channel) + , rpcmethod_SetMainExecutable_(Bridge_method_names[28], options.suffix_for_stats(),::grpc::internal::RpcMethod::NORMAL_RPC, channel) + , rpcmethod_Login_(Bridge_method_names[29], options.suffix_for_stats(),::grpc::internal::RpcMethod::NORMAL_RPC, channel) + , rpcmethod_Login2FA_(Bridge_method_names[30], options.suffix_for_stats(),::grpc::internal::RpcMethod::NORMAL_RPC, channel) + , rpcmethod_Login2Passwords_(Bridge_method_names[31], options.suffix_for_stats(),::grpc::internal::RpcMethod::NORMAL_RPC, channel) + , rpcmethod_LoginAbort_(Bridge_method_names[32], options.suffix_for_stats(),::grpc::internal::RpcMethod::NORMAL_RPC, channel) + , rpcmethod_CheckUpdate_(Bridge_method_names[33], options.suffix_for_stats(),::grpc::internal::RpcMethod::NORMAL_RPC, channel) + , rpcmethod_InstallUpdate_(Bridge_method_names[34], options.suffix_for_stats(),::grpc::internal::RpcMethod::NORMAL_RPC, channel) + , rpcmethod_SetIsAutomaticUpdateOn_(Bridge_method_names[35], options.suffix_for_stats(),::grpc::internal::RpcMethod::NORMAL_RPC, channel) + , rpcmethod_IsAutomaticUpdateOn_(Bridge_method_names[36], options.suffix_for_stats(),::grpc::internal::RpcMethod::NORMAL_RPC, channel) + , rpcmethod_DiskCachePath_(Bridge_method_names[37], options.suffix_for_stats(),::grpc::internal::RpcMethod::NORMAL_RPC, channel) + , rpcmethod_SetDiskCachePath_(Bridge_method_names[38], options.suffix_for_stats(),::grpc::internal::RpcMethod::NORMAL_RPC, channel) + , rpcmethod_SetIsDoHEnabled_(Bridge_method_names[39], options.suffix_for_stats(),::grpc::internal::RpcMethod::NORMAL_RPC, channel) + , rpcmethod_IsDoHEnabled_(Bridge_method_names[40], options.suffix_for_stats(),::grpc::internal::RpcMethod::NORMAL_RPC, channel) + , rpcmethod_MailServerSettings_(Bridge_method_names[41], options.suffix_for_stats(),::grpc::internal::RpcMethod::NORMAL_RPC, channel) + , rpcmethod_SetMailServerSettings_(Bridge_method_names[42], options.suffix_for_stats(),::grpc::internal::RpcMethod::NORMAL_RPC, channel) + , rpcmethod_Hostname_(Bridge_method_names[43], options.suffix_for_stats(),::grpc::internal::RpcMethod::NORMAL_RPC, channel) + , rpcmethod_IsPortFree_(Bridge_method_names[44], options.suffix_for_stats(),::grpc::internal::RpcMethod::NORMAL_RPC, channel) + , rpcmethod_AvailableKeychains_(Bridge_method_names[45], options.suffix_for_stats(),::grpc::internal::RpcMethod::NORMAL_RPC, channel) + , rpcmethod_SetCurrentKeychain_(Bridge_method_names[46], options.suffix_for_stats(),::grpc::internal::RpcMethod::NORMAL_RPC, channel) + , rpcmethod_CurrentKeychain_(Bridge_method_names[47], options.suffix_for_stats(),::grpc::internal::RpcMethod::NORMAL_RPC, channel) + , rpcmethod_GetUserList_(Bridge_method_names[48], options.suffix_for_stats(),::grpc::internal::RpcMethod::NORMAL_RPC, channel) + , rpcmethod_GetUser_(Bridge_method_names[49], options.suffix_for_stats(),::grpc::internal::RpcMethod::NORMAL_RPC, channel) + , rpcmethod_SetUserSplitMode_(Bridge_method_names[50], options.suffix_for_stats(),::grpc::internal::RpcMethod::NORMAL_RPC, channel) + , rpcmethod_SendBadEventUserFeedback_(Bridge_method_names[51], options.suffix_for_stats(),::grpc::internal::RpcMethod::NORMAL_RPC, channel) + , rpcmethod_LogoutUser_(Bridge_method_names[52], options.suffix_for_stats(),::grpc::internal::RpcMethod::NORMAL_RPC, channel) + , rpcmethod_RemoveUser_(Bridge_method_names[53], options.suffix_for_stats(),::grpc::internal::RpcMethod::NORMAL_RPC, channel) + , rpcmethod_ConfigureUserAppleMail_(Bridge_method_names[54], options.suffix_for_stats(),::grpc::internal::RpcMethod::NORMAL_RPC, channel) + , rpcmethod_RunEventStream_(Bridge_method_names[55], options.suffix_for_stats(),::grpc::internal::RpcMethod::SERVER_STREAMING, channel) + , rpcmethod_StopEventStream_(Bridge_method_names[56], options.suffix_for_stats(),::grpc::internal::RpcMethod::NORMAL_RPC, channel) {} ::grpc::Status Bridge::Stub::CheckTokens(::grpc::ClientContext* context, const ::google::protobuf::StringValue& request, ::google::protobuf::StringValue* response) { @@ -419,6 +423,52 @@ void Bridge::Stub::async::IsAllMailVisible(::grpc::ClientContext* context, const return result; } +::grpc::Status Bridge::Stub::SetIsTelemetryDisabled(::grpc::ClientContext* context, const ::google::protobuf::BoolValue& request, ::google::protobuf::Empty* response) { + return ::grpc::internal::BlockingUnaryCall< ::google::protobuf::BoolValue, ::google::protobuf::Empty, ::grpc::protobuf::MessageLite, ::grpc::protobuf::MessageLite>(channel_.get(), rpcmethod_SetIsTelemetryDisabled_, context, request, response); +} + +void Bridge::Stub::async::SetIsTelemetryDisabled(::grpc::ClientContext* context, const ::google::protobuf::BoolValue* request, ::google::protobuf::Empty* response, std::function f) { + ::grpc::internal::CallbackUnaryCall< ::google::protobuf::BoolValue, ::google::protobuf::Empty, ::grpc::protobuf::MessageLite, ::grpc::protobuf::MessageLite>(stub_->channel_.get(), stub_->rpcmethod_SetIsTelemetryDisabled_, context, request, response, std::move(f)); +} + +void Bridge::Stub::async::SetIsTelemetryDisabled(::grpc::ClientContext* context, const ::google::protobuf::BoolValue* request, ::google::protobuf::Empty* response, ::grpc::ClientUnaryReactor* reactor) { + ::grpc::internal::ClientCallbackUnaryFactory::Create< ::grpc::protobuf::MessageLite, ::grpc::protobuf::MessageLite>(stub_->channel_.get(), stub_->rpcmethod_SetIsTelemetryDisabled_, context, request, response, reactor); +} + +::grpc::ClientAsyncResponseReader< ::google::protobuf::Empty>* Bridge::Stub::PrepareAsyncSetIsTelemetryDisabledRaw(::grpc::ClientContext* context, const ::google::protobuf::BoolValue& request, ::grpc::CompletionQueue* cq) { + return ::grpc::internal::ClientAsyncResponseReaderHelper::Create< ::google::protobuf::Empty, ::google::protobuf::BoolValue, ::grpc::protobuf::MessageLite, ::grpc::protobuf::MessageLite>(channel_.get(), cq, rpcmethod_SetIsTelemetryDisabled_, context, request); +} + +::grpc::ClientAsyncResponseReader< ::google::protobuf::Empty>* Bridge::Stub::AsyncSetIsTelemetryDisabledRaw(::grpc::ClientContext* context, const ::google::protobuf::BoolValue& request, ::grpc::CompletionQueue* cq) { + auto* result = + this->PrepareAsyncSetIsTelemetryDisabledRaw(context, request, cq); + result->StartCall(); + return result; +} + +::grpc::Status Bridge::Stub::IsTelemetryDisabled(::grpc::ClientContext* context, const ::google::protobuf::Empty& request, ::google::protobuf::BoolValue* response) { + return ::grpc::internal::BlockingUnaryCall< ::google::protobuf::Empty, ::google::protobuf::BoolValue, ::grpc::protobuf::MessageLite, ::grpc::protobuf::MessageLite>(channel_.get(), rpcmethod_IsTelemetryDisabled_, context, request, response); +} + +void Bridge::Stub::async::IsTelemetryDisabled(::grpc::ClientContext* context, const ::google::protobuf::Empty* request, ::google::protobuf::BoolValue* response, std::function f) { + ::grpc::internal::CallbackUnaryCall< ::google::protobuf::Empty, ::google::protobuf::BoolValue, ::grpc::protobuf::MessageLite, ::grpc::protobuf::MessageLite>(stub_->channel_.get(), stub_->rpcmethod_IsTelemetryDisabled_, context, request, response, std::move(f)); +} + +void Bridge::Stub::async::IsTelemetryDisabled(::grpc::ClientContext* context, const ::google::protobuf::Empty* request, ::google::protobuf::BoolValue* response, ::grpc::ClientUnaryReactor* reactor) { + ::grpc::internal::ClientCallbackUnaryFactory::Create< ::grpc::protobuf::MessageLite, ::grpc::protobuf::MessageLite>(stub_->channel_.get(), stub_->rpcmethod_IsTelemetryDisabled_, context, request, response, reactor); +} + +::grpc::ClientAsyncResponseReader< ::google::protobuf::BoolValue>* Bridge::Stub::PrepareAsyncIsTelemetryDisabledRaw(::grpc::ClientContext* context, const ::google::protobuf::Empty& request, ::grpc::CompletionQueue* cq) { + return ::grpc::internal::ClientAsyncResponseReaderHelper::Create< ::google::protobuf::BoolValue, ::google::protobuf::Empty, ::grpc::protobuf::MessageLite, ::grpc::protobuf::MessageLite>(channel_.get(), cq, rpcmethod_IsTelemetryDisabled_, context, request); +} + +::grpc::ClientAsyncResponseReader< ::google::protobuf::BoolValue>* Bridge::Stub::AsyncIsTelemetryDisabledRaw(::grpc::ClientContext* context, const ::google::protobuf::Empty& request, ::grpc::CompletionQueue* cq) { + auto* result = + this->PrepareAsyncIsTelemetryDisabledRaw(context, request, cq); + result->StartCall(); + return result; +} + ::grpc::Status Bridge::Stub::GoOs(::grpc::ClientContext* context, const ::google::protobuf::Empty& request, ::google::protobuf::StringValue* response) { return ::grpc::internal::BlockingUnaryCall< ::google::protobuf::Empty, ::google::protobuf::StringValue, ::grpc::protobuf::MessageLite, ::grpc::protobuf::MessageLite>(channel_.get(), rpcmethod_GoOs_, context, request, response); } @@ -1525,22 +1575,22 @@ Bridge::Service::Service() { AddMethod(new ::grpc::internal::RpcServiceMethod( Bridge_method_names[12], ::grpc::internal::RpcMethod::NORMAL_RPC, - new ::grpc::internal::RpcMethodHandler< Bridge::Service, ::google::protobuf::Empty, ::google::protobuf::StringValue, ::grpc::protobuf::MessageLite, ::grpc::protobuf::MessageLite>( + new ::grpc::internal::RpcMethodHandler< Bridge::Service, ::google::protobuf::BoolValue, ::google::protobuf::Empty, ::grpc::protobuf::MessageLite, ::grpc::protobuf::MessageLite>( [](Bridge::Service* service, ::grpc::ServerContext* ctx, - const ::google::protobuf::Empty* req, - ::google::protobuf::StringValue* resp) { - return service->GoOs(ctx, req, resp); + const ::google::protobuf::BoolValue* req, + ::google::protobuf::Empty* resp) { + return service->SetIsTelemetryDisabled(ctx, req, resp); }, this))); AddMethod(new ::grpc::internal::RpcServiceMethod( Bridge_method_names[13], ::grpc::internal::RpcMethod::NORMAL_RPC, - new ::grpc::internal::RpcMethodHandler< Bridge::Service, ::google::protobuf::Empty, ::google::protobuf::Empty, ::grpc::protobuf::MessageLite, ::grpc::protobuf::MessageLite>( + new ::grpc::internal::RpcMethodHandler< Bridge::Service, ::google::protobuf::Empty, ::google::protobuf::BoolValue, ::grpc::protobuf::MessageLite, ::grpc::protobuf::MessageLite>( [](Bridge::Service* service, ::grpc::ServerContext* ctx, const ::google::protobuf::Empty* req, - ::google::protobuf::Empty* resp) { - return service->TriggerReset(ctx, req, resp); + ::google::protobuf::BoolValue* resp) { + return service->IsTelemetryDisabled(ctx, req, resp); }, this))); AddMethod(new ::grpc::internal::RpcServiceMethod( Bridge_method_names[14], @@ -1550,17 +1600,17 @@ Bridge::Service::Service() { ::grpc::ServerContext* ctx, const ::google::protobuf::Empty* req, ::google::protobuf::StringValue* resp) { - return service->Version(ctx, req, resp); + return service->GoOs(ctx, req, resp); }, this))); AddMethod(new ::grpc::internal::RpcServiceMethod( Bridge_method_names[15], ::grpc::internal::RpcMethod::NORMAL_RPC, - new ::grpc::internal::RpcMethodHandler< Bridge::Service, ::google::protobuf::Empty, ::google::protobuf::StringValue, ::grpc::protobuf::MessageLite, ::grpc::protobuf::MessageLite>( + new ::grpc::internal::RpcMethodHandler< Bridge::Service, ::google::protobuf::Empty, ::google::protobuf::Empty, ::grpc::protobuf::MessageLite, ::grpc::protobuf::MessageLite>( [](Bridge::Service* service, ::grpc::ServerContext* ctx, const ::google::protobuf::Empty* req, - ::google::protobuf::StringValue* resp) { - return service->LogsPath(ctx, req, resp); + ::google::protobuf::Empty* resp) { + return service->TriggerReset(ctx, req, resp); }, this))); AddMethod(new ::grpc::internal::RpcServiceMethod( Bridge_method_names[16], @@ -1570,7 +1620,7 @@ Bridge::Service::Service() { ::grpc::ServerContext* ctx, const ::google::protobuf::Empty* req, ::google::protobuf::StringValue* resp) { - return service->LicensePath(ctx, req, resp); + return service->Version(ctx, req, resp); }, this))); AddMethod(new ::grpc::internal::RpcServiceMethod( Bridge_method_names[17], @@ -1580,7 +1630,7 @@ Bridge::Service::Service() { ::grpc::ServerContext* ctx, const ::google::protobuf::Empty* req, ::google::protobuf::StringValue* resp) { - return service->ReleaseNotesPageLink(ctx, req, resp); + return service->LogsPath(ctx, req, resp); }, this))); AddMethod(new ::grpc::internal::RpcServiceMethod( Bridge_method_names[18], @@ -1590,7 +1640,7 @@ Bridge::Service::Service() { ::grpc::ServerContext* ctx, const ::google::protobuf::Empty* req, ::google::protobuf::StringValue* resp) { - return service->DependencyLicensesLink(ctx, req, resp); + return service->LicensePath(ctx, req, resp); }, this))); AddMethod(new ::grpc::internal::RpcServiceMethod( Bridge_method_names[19], @@ -1600,17 +1650,17 @@ Bridge::Service::Service() { ::grpc::ServerContext* ctx, const ::google::protobuf::Empty* req, ::google::protobuf::StringValue* resp) { - return service->LandingPageLink(ctx, req, resp); + return service->ReleaseNotesPageLink(ctx, req, resp); }, this))); AddMethod(new ::grpc::internal::RpcServiceMethod( Bridge_method_names[20], ::grpc::internal::RpcMethod::NORMAL_RPC, - new ::grpc::internal::RpcMethodHandler< Bridge::Service, ::google::protobuf::StringValue, ::google::protobuf::Empty, ::grpc::protobuf::MessageLite, ::grpc::protobuf::MessageLite>( + new ::grpc::internal::RpcMethodHandler< Bridge::Service, ::google::protobuf::Empty, ::google::protobuf::StringValue, ::grpc::protobuf::MessageLite, ::grpc::protobuf::MessageLite>( [](Bridge::Service* service, ::grpc::ServerContext* ctx, - const ::google::protobuf::StringValue* req, - ::google::protobuf::Empty* resp) { - return service->SetColorSchemeName(ctx, req, resp); + const ::google::protobuf::Empty* req, + ::google::protobuf::StringValue* resp) { + return service->DependencyLicensesLink(ctx, req, resp); }, this))); AddMethod(new ::grpc::internal::RpcServiceMethod( Bridge_method_names[21], @@ -1620,11 +1670,31 @@ Bridge::Service::Service() { ::grpc::ServerContext* ctx, const ::google::protobuf::Empty* req, ::google::protobuf::StringValue* resp) { - return service->ColorSchemeName(ctx, req, resp); + return service->LandingPageLink(ctx, req, resp); }, this))); AddMethod(new ::grpc::internal::RpcServiceMethod( Bridge_method_names[22], ::grpc::internal::RpcMethod::NORMAL_RPC, + new ::grpc::internal::RpcMethodHandler< Bridge::Service, ::google::protobuf::StringValue, ::google::protobuf::Empty, ::grpc::protobuf::MessageLite, ::grpc::protobuf::MessageLite>( + [](Bridge::Service* service, + ::grpc::ServerContext* ctx, + const ::google::protobuf::StringValue* req, + ::google::protobuf::Empty* resp) { + return service->SetColorSchemeName(ctx, req, resp); + }, this))); + AddMethod(new ::grpc::internal::RpcServiceMethod( + Bridge_method_names[23], + ::grpc::internal::RpcMethod::NORMAL_RPC, + new ::grpc::internal::RpcMethodHandler< Bridge::Service, ::google::protobuf::Empty, ::google::protobuf::StringValue, ::grpc::protobuf::MessageLite, ::grpc::protobuf::MessageLite>( + [](Bridge::Service* service, + ::grpc::ServerContext* ctx, + const ::google::protobuf::Empty* req, + ::google::protobuf::StringValue* resp) { + return service->ColorSchemeName(ctx, req, resp); + }, this))); + AddMethod(new ::grpc::internal::RpcServiceMethod( + Bridge_method_names[24], + ::grpc::internal::RpcMethod::NORMAL_RPC, new ::grpc::internal::RpcMethodHandler< Bridge::Service, ::google::protobuf::Empty, ::google::protobuf::StringValue, ::grpc::protobuf::MessageLite, ::grpc::protobuf::MessageLite>( [](Bridge::Service* service, ::grpc::ServerContext* ctx, @@ -1633,7 +1703,7 @@ Bridge::Service::Service() { return service->CurrentEmailClient(ctx, req, resp); }, this))); AddMethod(new ::grpc::internal::RpcServiceMethod( - Bridge_method_names[23], + Bridge_method_names[25], ::grpc::internal::RpcMethod::NORMAL_RPC, new ::grpc::internal::RpcMethodHandler< Bridge::Service, ::grpc::ReportBugRequest, ::google::protobuf::Empty, ::grpc::protobuf::MessageLite, ::grpc::protobuf::MessageLite>( [](Bridge::Service* service, @@ -1643,7 +1713,7 @@ Bridge::Service::Service() { return service->ReportBug(ctx, req, resp); }, this))); AddMethod(new ::grpc::internal::RpcServiceMethod( - Bridge_method_names[24], + Bridge_method_names[26], ::grpc::internal::RpcMethod::NORMAL_RPC, new ::grpc::internal::RpcMethodHandler< Bridge::Service, ::google::protobuf::StringValue, ::google::protobuf::Empty, ::grpc::protobuf::MessageLite, ::grpc::protobuf::MessageLite>( [](Bridge::Service* service, @@ -1653,7 +1723,7 @@ Bridge::Service::Service() { return service->ExportTLSCertificates(ctx, req, resp); }, this))); AddMethod(new ::grpc::internal::RpcServiceMethod( - Bridge_method_names[25], + Bridge_method_names[27], ::grpc::internal::RpcMethod::NORMAL_RPC, new ::grpc::internal::RpcMethodHandler< Bridge::Service, ::google::protobuf::StringValue, ::google::protobuf::Empty, ::grpc::protobuf::MessageLite, ::grpc::protobuf::MessageLite>( [](Bridge::Service* service, @@ -1663,7 +1733,7 @@ Bridge::Service::Service() { return service->ForceLauncher(ctx, req, resp); }, this))); AddMethod(new ::grpc::internal::RpcServiceMethod( - Bridge_method_names[26], + Bridge_method_names[28], ::grpc::internal::RpcMethod::NORMAL_RPC, new ::grpc::internal::RpcMethodHandler< Bridge::Service, ::google::protobuf::StringValue, ::google::protobuf::Empty, ::grpc::protobuf::MessageLite, ::grpc::protobuf::MessageLite>( [](Bridge::Service* service, @@ -1673,7 +1743,7 @@ Bridge::Service::Service() { return service->SetMainExecutable(ctx, req, resp); }, this))); AddMethod(new ::grpc::internal::RpcServiceMethod( - Bridge_method_names[27], + Bridge_method_names[29], ::grpc::internal::RpcMethod::NORMAL_RPC, new ::grpc::internal::RpcMethodHandler< Bridge::Service, ::grpc::LoginRequest, ::google::protobuf::Empty, ::grpc::protobuf::MessageLite, ::grpc::protobuf::MessageLite>( [](Bridge::Service* service, @@ -1683,7 +1753,7 @@ Bridge::Service::Service() { return service->Login(ctx, req, resp); }, this))); AddMethod(new ::grpc::internal::RpcServiceMethod( - Bridge_method_names[28], + Bridge_method_names[30], ::grpc::internal::RpcMethod::NORMAL_RPC, new ::grpc::internal::RpcMethodHandler< Bridge::Service, ::grpc::LoginRequest, ::google::protobuf::Empty, ::grpc::protobuf::MessageLite, ::grpc::protobuf::MessageLite>( [](Bridge::Service* service, @@ -1693,7 +1763,7 @@ Bridge::Service::Service() { return service->Login2FA(ctx, req, resp); }, this))); AddMethod(new ::grpc::internal::RpcServiceMethod( - Bridge_method_names[29], + Bridge_method_names[31], ::grpc::internal::RpcMethod::NORMAL_RPC, new ::grpc::internal::RpcMethodHandler< Bridge::Service, ::grpc::LoginRequest, ::google::protobuf::Empty, ::grpc::protobuf::MessageLite, ::grpc::protobuf::MessageLite>( [](Bridge::Service* service, @@ -1703,7 +1773,7 @@ Bridge::Service::Service() { return service->Login2Passwords(ctx, req, resp); }, this))); AddMethod(new ::grpc::internal::RpcServiceMethod( - Bridge_method_names[30], + Bridge_method_names[32], ::grpc::internal::RpcMethod::NORMAL_RPC, new ::grpc::internal::RpcMethodHandler< Bridge::Service, ::grpc::LoginAbortRequest, ::google::protobuf::Empty, ::grpc::protobuf::MessageLite, ::grpc::protobuf::MessageLite>( [](Bridge::Service* service, @@ -1713,7 +1783,7 @@ Bridge::Service::Service() { return service->LoginAbort(ctx, req, resp); }, this))); AddMethod(new ::grpc::internal::RpcServiceMethod( - Bridge_method_names[31], + Bridge_method_names[33], ::grpc::internal::RpcMethod::NORMAL_RPC, new ::grpc::internal::RpcMethodHandler< Bridge::Service, ::google::protobuf::Empty, ::google::protobuf::Empty, ::grpc::protobuf::MessageLite, ::grpc::protobuf::MessageLite>( [](Bridge::Service* service, @@ -1723,7 +1793,7 @@ Bridge::Service::Service() { return service->CheckUpdate(ctx, req, resp); }, this))); AddMethod(new ::grpc::internal::RpcServiceMethod( - Bridge_method_names[32], + Bridge_method_names[34], ::grpc::internal::RpcMethod::NORMAL_RPC, new ::grpc::internal::RpcMethodHandler< Bridge::Service, ::google::protobuf::Empty, ::google::protobuf::Empty, ::grpc::protobuf::MessageLite, ::grpc::protobuf::MessageLite>( [](Bridge::Service* service, @@ -1733,7 +1803,7 @@ Bridge::Service::Service() { return service->InstallUpdate(ctx, req, resp); }, this))); AddMethod(new ::grpc::internal::RpcServiceMethod( - Bridge_method_names[33], + Bridge_method_names[35], ::grpc::internal::RpcMethod::NORMAL_RPC, new ::grpc::internal::RpcMethodHandler< Bridge::Service, ::google::protobuf::BoolValue, ::google::protobuf::Empty, ::grpc::protobuf::MessageLite, ::grpc::protobuf::MessageLite>( [](Bridge::Service* service, @@ -1743,7 +1813,7 @@ Bridge::Service::Service() { return service->SetIsAutomaticUpdateOn(ctx, req, resp); }, this))); AddMethod(new ::grpc::internal::RpcServiceMethod( - Bridge_method_names[34], + Bridge_method_names[36], ::grpc::internal::RpcMethod::NORMAL_RPC, new ::grpc::internal::RpcMethodHandler< Bridge::Service, ::google::protobuf::Empty, ::google::protobuf::BoolValue, ::grpc::protobuf::MessageLite, ::grpc::protobuf::MessageLite>( [](Bridge::Service* service, @@ -1753,7 +1823,7 @@ Bridge::Service::Service() { return service->IsAutomaticUpdateOn(ctx, req, resp); }, this))); AddMethod(new ::grpc::internal::RpcServiceMethod( - Bridge_method_names[35], + Bridge_method_names[37], ::grpc::internal::RpcMethod::NORMAL_RPC, new ::grpc::internal::RpcMethodHandler< Bridge::Service, ::google::protobuf::Empty, ::google::protobuf::StringValue, ::grpc::protobuf::MessageLite, ::grpc::protobuf::MessageLite>( [](Bridge::Service* service, @@ -1763,7 +1833,7 @@ Bridge::Service::Service() { return service->DiskCachePath(ctx, req, resp); }, this))); AddMethod(new ::grpc::internal::RpcServiceMethod( - Bridge_method_names[36], + Bridge_method_names[38], ::grpc::internal::RpcMethod::NORMAL_RPC, new ::grpc::internal::RpcMethodHandler< Bridge::Service, ::google::protobuf::StringValue, ::google::protobuf::Empty, ::grpc::protobuf::MessageLite, ::grpc::protobuf::MessageLite>( [](Bridge::Service* service, @@ -1773,7 +1843,7 @@ Bridge::Service::Service() { return service->SetDiskCachePath(ctx, req, resp); }, this))); AddMethod(new ::grpc::internal::RpcServiceMethod( - Bridge_method_names[37], + Bridge_method_names[39], ::grpc::internal::RpcMethod::NORMAL_RPC, new ::grpc::internal::RpcMethodHandler< Bridge::Service, ::google::protobuf::BoolValue, ::google::protobuf::Empty, ::grpc::protobuf::MessageLite, ::grpc::protobuf::MessageLite>( [](Bridge::Service* service, @@ -1783,7 +1853,7 @@ Bridge::Service::Service() { return service->SetIsDoHEnabled(ctx, req, resp); }, this))); AddMethod(new ::grpc::internal::RpcServiceMethod( - Bridge_method_names[38], + Bridge_method_names[40], ::grpc::internal::RpcMethod::NORMAL_RPC, new ::grpc::internal::RpcMethodHandler< Bridge::Service, ::google::protobuf::Empty, ::google::protobuf::BoolValue, ::grpc::protobuf::MessageLite, ::grpc::protobuf::MessageLite>( [](Bridge::Service* service, @@ -1793,7 +1863,7 @@ Bridge::Service::Service() { return service->IsDoHEnabled(ctx, req, resp); }, this))); AddMethod(new ::grpc::internal::RpcServiceMethod( - Bridge_method_names[39], + Bridge_method_names[41], ::grpc::internal::RpcMethod::NORMAL_RPC, new ::grpc::internal::RpcMethodHandler< Bridge::Service, ::google::protobuf::Empty, ::grpc::ImapSmtpSettings, ::grpc::protobuf::MessageLite, ::grpc::protobuf::MessageLite>( [](Bridge::Service* service, @@ -1803,7 +1873,7 @@ Bridge::Service::Service() { return service->MailServerSettings(ctx, req, resp); }, this))); AddMethod(new ::grpc::internal::RpcServiceMethod( - Bridge_method_names[40], + Bridge_method_names[42], ::grpc::internal::RpcMethod::NORMAL_RPC, new ::grpc::internal::RpcMethodHandler< Bridge::Service, ::grpc::ImapSmtpSettings, ::google::protobuf::Empty, ::grpc::protobuf::MessageLite, ::grpc::protobuf::MessageLite>( [](Bridge::Service* service, @@ -1813,7 +1883,7 @@ Bridge::Service::Service() { return service->SetMailServerSettings(ctx, req, resp); }, this))); AddMethod(new ::grpc::internal::RpcServiceMethod( - Bridge_method_names[41], + Bridge_method_names[43], ::grpc::internal::RpcMethod::NORMAL_RPC, new ::grpc::internal::RpcMethodHandler< Bridge::Service, ::google::protobuf::Empty, ::google::protobuf::StringValue, ::grpc::protobuf::MessageLite, ::grpc::protobuf::MessageLite>( [](Bridge::Service* service, @@ -1823,7 +1893,7 @@ Bridge::Service::Service() { return service->Hostname(ctx, req, resp); }, this))); AddMethod(new ::grpc::internal::RpcServiceMethod( - Bridge_method_names[42], + Bridge_method_names[44], ::grpc::internal::RpcMethod::NORMAL_RPC, new ::grpc::internal::RpcMethodHandler< Bridge::Service, ::google::protobuf::Int32Value, ::google::protobuf::BoolValue, ::grpc::protobuf::MessageLite, ::grpc::protobuf::MessageLite>( [](Bridge::Service* service, @@ -1833,7 +1903,7 @@ Bridge::Service::Service() { return service->IsPortFree(ctx, req, resp); }, this))); AddMethod(new ::grpc::internal::RpcServiceMethod( - Bridge_method_names[43], + Bridge_method_names[45], ::grpc::internal::RpcMethod::NORMAL_RPC, new ::grpc::internal::RpcMethodHandler< Bridge::Service, ::google::protobuf::Empty, ::grpc::AvailableKeychainsResponse, ::grpc::protobuf::MessageLite, ::grpc::protobuf::MessageLite>( [](Bridge::Service* service, @@ -1843,7 +1913,7 @@ Bridge::Service::Service() { return service->AvailableKeychains(ctx, req, resp); }, this))); AddMethod(new ::grpc::internal::RpcServiceMethod( - Bridge_method_names[44], + Bridge_method_names[46], ::grpc::internal::RpcMethod::NORMAL_RPC, new ::grpc::internal::RpcMethodHandler< Bridge::Service, ::google::protobuf::StringValue, ::google::protobuf::Empty, ::grpc::protobuf::MessageLite, ::grpc::protobuf::MessageLite>( [](Bridge::Service* service, @@ -1853,7 +1923,7 @@ Bridge::Service::Service() { return service->SetCurrentKeychain(ctx, req, resp); }, this))); AddMethod(new ::grpc::internal::RpcServiceMethod( - Bridge_method_names[45], + Bridge_method_names[47], ::grpc::internal::RpcMethod::NORMAL_RPC, new ::grpc::internal::RpcMethodHandler< Bridge::Service, ::google::protobuf::Empty, ::google::protobuf::StringValue, ::grpc::protobuf::MessageLite, ::grpc::protobuf::MessageLite>( [](Bridge::Service* service, @@ -1863,7 +1933,7 @@ Bridge::Service::Service() { return service->CurrentKeychain(ctx, req, resp); }, this))); AddMethod(new ::grpc::internal::RpcServiceMethod( - Bridge_method_names[46], + Bridge_method_names[48], ::grpc::internal::RpcMethod::NORMAL_RPC, new ::grpc::internal::RpcMethodHandler< Bridge::Service, ::google::protobuf::Empty, ::grpc::UserListResponse, ::grpc::protobuf::MessageLite, ::grpc::protobuf::MessageLite>( [](Bridge::Service* service, @@ -1873,7 +1943,7 @@ Bridge::Service::Service() { return service->GetUserList(ctx, req, resp); }, this))); AddMethod(new ::grpc::internal::RpcServiceMethod( - Bridge_method_names[47], + Bridge_method_names[49], ::grpc::internal::RpcMethod::NORMAL_RPC, new ::grpc::internal::RpcMethodHandler< Bridge::Service, ::google::protobuf::StringValue, ::grpc::User, ::grpc::protobuf::MessageLite, ::grpc::protobuf::MessageLite>( [](Bridge::Service* service, @@ -1883,7 +1953,7 @@ Bridge::Service::Service() { return service->GetUser(ctx, req, resp); }, this))); AddMethod(new ::grpc::internal::RpcServiceMethod( - Bridge_method_names[48], + Bridge_method_names[50], ::grpc::internal::RpcMethod::NORMAL_RPC, new ::grpc::internal::RpcMethodHandler< Bridge::Service, ::grpc::UserSplitModeRequest, ::google::protobuf::Empty, ::grpc::protobuf::MessageLite, ::grpc::protobuf::MessageLite>( [](Bridge::Service* service, @@ -1893,7 +1963,7 @@ Bridge::Service::Service() { return service->SetUserSplitMode(ctx, req, resp); }, this))); AddMethod(new ::grpc::internal::RpcServiceMethod( - Bridge_method_names[49], + Bridge_method_names[51], ::grpc::internal::RpcMethod::NORMAL_RPC, new ::grpc::internal::RpcMethodHandler< Bridge::Service, ::grpc::UserBadEventFeedbackRequest, ::google::protobuf::Empty, ::grpc::protobuf::MessageLite, ::grpc::protobuf::MessageLite>( [](Bridge::Service* service, @@ -1903,7 +1973,7 @@ Bridge::Service::Service() { return service->SendBadEventUserFeedback(ctx, req, resp); }, this))); AddMethod(new ::grpc::internal::RpcServiceMethod( - Bridge_method_names[50], + Bridge_method_names[52], ::grpc::internal::RpcMethod::NORMAL_RPC, new ::grpc::internal::RpcMethodHandler< Bridge::Service, ::google::protobuf::StringValue, ::google::protobuf::Empty, ::grpc::protobuf::MessageLite, ::grpc::protobuf::MessageLite>( [](Bridge::Service* service, @@ -1913,7 +1983,7 @@ Bridge::Service::Service() { return service->LogoutUser(ctx, req, resp); }, this))); AddMethod(new ::grpc::internal::RpcServiceMethod( - Bridge_method_names[51], + Bridge_method_names[53], ::grpc::internal::RpcMethod::NORMAL_RPC, new ::grpc::internal::RpcMethodHandler< Bridge::Service, ::google::protobuf::StringValue, ::google::protobuf::Empty, ::grpc::protobuf::MessageLite, ::grpc::protobuf::MessageLite>( [](Bridge::Service* service, @@ -1923,7 +1993,7 @@ Bridge::Service::Service() { return service->RemoveUser(ctx, req, resp); }, this))); AddMethod(new ::grpc::internal::RpcServiceMethod( - Bridge_method_names[52], + Bridge_method_names[54], ::grpc::internal::RpcMethod::NORMAL_RPC, new ::grpc::internal::RpcMethodHandler< Bridge::Service, ::grpc::ConfigureAppleMailRequest, ::google::protobuf::Empty, ::grpc::protobuf::MessageLite, ::grpc::protobuf::MessageLite>( [](Bridge::Service* service, @@ -1933,7 +2003,7 @@ Bridge::Service::Service() { return service->ConfigureUserAppleMail(ctx, req, resp); }, this))); AddMethod(new ::grpc::internal::RpcServiceMethod( - Bridge_method_names[53], + Bridge_method_names[55], ::grpc::internal::RpcMethod::SERVER_STREAMING, new ::grpc::internal::ServerStreamingHandler< Bridge::Service, ::grpc::EventStreamRequest, ::grpc::StreamEvent>( [](Bridge::Service* service, @@ -1943,7 +2013,7 @@ Bridge::Service::Service() { return service->RunEventStream(ctx, req, writer); }, this))); AddMethod(new ::grpc::internal::RpcServiceMethod( - Bridge_method_names[54], + Bridge_method_names[56], ::grpc::internal::RpcMethod::NORMAL_RPC, new ::grpc::internal::RpcMethodHandler< Bridge::Service, ::google::protobuf::Empty, ::google::protobuf::Empty, ::grpc::protobuf::MessageLite, ::grpc::protobuf::MessageLite>( [](Bridge::Service* service, @@ -2041,6 +2111,20 @@ Bridge::Service::~Service() { return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); } +::grpc::Status Bridge::Service::SetIsTelemetryDisabled(::grpc::ServerContext* context, const ::google::protobuf::BoolValue* request, ::google::protobuf::Empty* response) { + (void) context; + (void) request; + (void) response; + return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); +} + +::grpc::Status Bridge::Service::IsTelemetryDisabled(::grpc::ServerContext* context, const ::google::protobuf::Empty* request, ::google::protobuf::BoolValue* response) { + (void) context; + (void) request; + (void) response; + return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); +} + ::grpc::Status Bridge::Service::GoOs(::grpc::ServerContext* context, const ::google::protobuf::Empty* request, ::google::protobuf::StringValue* response) { (void) context; (void) request; diff --git a/internal/frontend/bridge-gui/bridgepp/bridgepp/GRPC/bridge.grpc.pb.h b/internal/frontend/bridge-gui/bridgepp/bridgepp/GRPC/bridge.grpc.pb.h index 9d24b1b0..86387cc3 100644 --- a/internal/frontend/bridge-gui/bridgepp/bridgepp/GRPC/bridge.grpc.pb.h +++ b/internal/frontend/bridge-gui/bridgepp/bridgepp/GRPC/bridge.grpc.pb.h @@ -141,6 +141,20 @@ class Bridge final { std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::google::protobuf::BoolValue>> PrepareAsyncIsAllMailVisible(::grpc::ClientContext* context, const ::google::protobuf::Empty& request, ::grpc::CompletionQueue* cq) { return std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::google::protobuf::BoolValue>>(PrepareAsyncIsAllMailVisibleRaw(context, request, cq)); } + virtual ::grpc::Status SetIsTelemetryDisabled(::grpc::ClientContext* context, const ::google::protobuf::BoolValue& request, ::google::protobuf::Empty* response) = 0; + std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::google::protobuf::Empty>> AsyncSetIsTelemetryDisabled(::grpc::ClientContext* context, const ::google::protobuf::BoolValue& request, ::grpc::CompletionQueue* cq) { + return std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::google::protobuf::Empty>>(AsyncSetIsTelemetryDisabledRaw(context, request, cq)); + } + std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::google::protobuf::Empty>> PrepareAsyncSetIsTelemetryDisabled(::grpc::ClientContext* context, const ::google::protobuf::BoolValue& request, ::grpc::CompletionQueue* cq) { + return std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::google::protobuf::Empty>>(PrepareAsyncSetIsTelemetryDisabledRaw(context, request, cq)); + } + virtual ::grpc::Status IsTelemetryDisabled(::grpc::ClientContext* context, const ::google::protobuf::Empty& request, ::google::protobuf::BoolValue* response) = 0; + std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::google::protobuf::BoolValue>> AsyncIsTelemetryDisabled(::grpc::ClientContext* context, const ::google::protobuf::Empty& request, ::grpc::CompletionQueue* cq) { + return std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::google::protobuf::BoolValue>>(AsyncIsTelemetryDisabledRaw(context, request, cq)); + } + std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::google::protobuf::BoolValue>> PrepareAsyncIsTelemetryDisabled(::grpc::ClientContext* context, const ::google::protobuf::Empty& request, ::grpc::CompletionQueue* cq) { + return std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::google::protobuf::BoolValue>>(PrepareAsyncIsTelemetryDisabledRaw(context, request, cq)); + } virtual ::grpc::Status GoOs(::grpc::ClientContext* context, const ::google::protobuf::Empty& request, ::google::protobuf::StringValue* response) = 0; std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::google::protobuf::StringValue>> AsyncGoOs(::grpc::ClientContext* context, const ::google::protobuf::Empty& request, ::grpc::CompletionQueue* cq) { return std::unique_ptr< ::grpc::ClientAsyncResponseReaderInterface< ::google::protobuf::StringValue>>(AsyncGoOsRaw(context, request, cq)); @@ -481,6 +495,10 @@ class Bridge final { virtual void SetIsAllMailVisible(::grpc::ClientContext* context, const ::google::protobuf::BoolValue* request, ::google::protobuf::Empty* response, ::grpc::ClientUnaryReactor* reactor) = 0; virtual void IsAllMailVisible(::grpc::ClientContext* context, const ::google::protobuf::Empty* request, ::google::protobuf::BoolValue* response, std::function) = 0; virtual void IsAllMailVisible(::grpc::ClientContext* context, const ::google::protobuf::Empty* request, ::google::protobuf::BoolValue* response, ::grpc::ClientUnaryReactor* reactor) = 0; + virtual void SetIsTelemetryDisabled(::grpc::ClientContext* context, const ::google::protobuf::BoolValue* request, ::google::protobuf::Empty* response, std::function) = 0; + virtual void SetIsTelemetryDisabled(::grpc::ClientContext* context, const ::google::protobuf::BoolValue* request, ::google::protobuf::Empty* response, ::grpc::ClientUnaryReactor* reactor) = 0; + virtual void IsTelemetryDisabled(::grpc::ClientContext* context, const ::google::protobuf::Empty* request, ::google::protobuf::BoolValue* response, std::function) = 0; + virtual void IsTelemetryDisabled(::grpc::ClientContext* context, const ::google::protobuf::Empty* request, ::google::protobuf::BoolValue* response, ::grpc::ClientUnaryReactor* reactor) = 0; virtual void GoOs(::grpc::ClientContext* context, const ::google::protobuf::Empty* request, ::google::protobuf::StringValue* response, std::function) = 0; virtual void GoOs(::grpc::ClientContext* context, const ::google::protobuf::Empty* request, ::google::protobuf::StringValue* response, ::grpc::ClientUnaryReactor* reactor) = 0; virtual void TriggerReset(::grpc::ClientContext* context, const ::google::protobuf::Empty* request, ::google::protobuf::Empty* response, std::function) = 0; @@ -604,6 +622,10 @@ class Bridge final { virtual ::grpc::ClientAsyncResponseReaderInterface< ::google::protobuf::Empty>* PrepareAsyncSetIsAllMailVisibleRaw(::grpc::ClientContext* context, const ::google::protobuf::BoolValue& request, ::grpc::CompletionQueue* cq) = 0; virtual ::grpc::ClientAsyncResponseReaderInterface< ::google::protobuf::BoolValue>* AsyncIsAllMailVisibleRaw(::grpc::ClientContext* context, const ::google::protobuf::Empty& request, ::grpc::CompletionQueue* cq) = 0; virtual ::grpc::ClientAsyncResponseReaderInterface< ::google::protobuf::BoolValue>* PrepareAsyncIsAllMailVisibleRaw(::grpc::ClientContext* context, const ::google::protobuf::Empty& request, ::grpc::CompletionQueue* cq) = 0; + virtual ::grpc::ClientAsyncResponseReaderInterface< ::google::protobuf::Empty>* AsyncSetIsTelemetryDisabledRaw(::grpc::ClientContext* context, const ::google::protobuf::BoolValue& request, ::grpc::CompletionQueue* cq) = 0; + virtual ::grpc::ClientAsyncResponseReaderInterface< ::google::protobuf::Empty>* PrepareAsyncSetIsTelemetryDisabledRaw(::grpc::ClientContext* context, const ::google::protobuf::BoolValue& request, ::grpc::CompletionQueue* cq) = 0; + virtual ::grpc::ClientAsyncResponseReaderInterface< ::google::protobuf::BoolValue>* AsyncIsTelemetryDisabledRaw(::grpc::ClientContext* context, const ::google::protobuf::Empty& request, ::grpc::CompletionQueue* cq) = 0; + virtual ::grpc::ClientAsyncResponseReaderInterface< ::google::protobuf::BoolValue>* PrepareAsyncIsTelemetryDisabledRaw(::grpc::ClientContext* context, const ::google::protobuf::Empty& request, ::grpc::CompletionQueue* cq) = 0; virtual ::grpc::ClientAsyncResponseReaderInterface< ::google::protobuf::StringValue>* AsyncGoOsRaw(::grpc::ClientContext* context, const ::google::protobuf::Empty& request, ::grpc::CompletionQueue* cq) = 0; virtual ::grpc::ClientAsyncResponseReaderInterface< ::google::protobuf::StringValue>* PrepareAsyncGoOsRaw(::grpc::ClientContext* context, const ::google::protobuf::Empty& request, ::grpc::CompletionQueue* cq) = 0; virtual ::grpc::ClientAsyncResponseReaderInterface< ::google::protobuf::Empty>* AsyncTriggerResetRaw(::grpc::ClientContext* context, const ::google::protobuf::Empty& request, ::grpc::CompletionQueue* cq) = 0; @@ -779,6 +801,20 @@ class Bridge final { std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::google::protobuf::BoolValue>> PrepareAsyncIsAllMailVisible(::grpc::ClientContext* context, const ::google::protobuf::Empty& request, ::grpc::CompletionQueue* cq) { return std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::google::protobuf::BoolValue>>(PrepareAsyncIsAllMailVisibleRaw(context, request, cq)); } + ::grpc::Status SetIsTelemetryDisabled(::grpc::ClientContext* context, const ::google::protobuf::BoolValue& request, ::google::protobuf::Empty* response) override; + std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::google::protobuf::Empty>> AsyncSetIsTelemetryDisabled(::grpc::ClientContext* context, const ::google::protobuf::BoolValue& request, ::grpc::CompletionQueue* cq) { + return std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::google::protobuf::Empty>>(AsyncSetIsTelemetryDisabledRaw(context, request, cq)); + } + std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::google::protobuf::Empty>> PrepareAsyncSetIsTelemetryDisabled(::grpc::ClientContext* context, const ::google::protobuf::BoolValue& request, ::grpc::CompletionQueue* cq) { + return std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::google::protobuf::Empty>>(PrepareAsyncSetIsTelemetryDisabledRaw(context, request, cq)); + } + ::grpc::Status IsTelemetryDisabled(::grpc::ClientContext* context, const ::google::protobuf::Empty& request, ::google::protobuf::BoolValue* response) override; + std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::google::protobuf::BoolValue>> AsyncIsTelemetryDisabled(::grpc::ClientContext* context, const ::google::protobuf::Empty& request, ::grpc::CompletionQueue* cq) { + return std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::google::protobuf::BoolValue>>(AsyncIsTelemetryDisabledRaw(context, request, cq)); + } + std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::google::protobuf::BoolValue>> PrepareAsyncIsTelemetryDisabled(::grpc::ClientContext* context, const ::google::protobuf::Empty& request, ::grpc::CompletionQueue* cq) { + return std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::google::protobuf::BoolValue>>(PrepareAsyncIsTelemetryDisabledRaw(context, request, cq)); + } ::grpc::Status GoOs(::grpc::ClientContext* context, const ::google::protobuf::Empty& request, ::google::protobuf::StringValue* response) override; std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::google::protobuf::StringValue>> AsyncGoOs(::grpc::ClientContext* context, const ::google::protobuf::Empty& request, ::grpc::CompletionQueue* cq) { return std::unique_ptr< ::grpc::ClientAsyncResponseReader< ::google::protobuf::StringValue>>(AsyncGoOsRaw(context, request, cq)); @@ -1109,6 +1145,10 @@ class Bridge final { void SetIsAllMailVisible(::grpc::ClientContext* context, const ::google::protobuf::BoolValue* request, ::google::protobuf::Empty* response, ::grpc::ClientUnaryReactor* reactor) override; void IsAllMailVisible(::grpc::ClientContext* context, const ::google::protobuf::Empty* request, ::google::protobuf::BoolValue* response, std::function) override; void IsAllMailVisible(::grpc::ClientContext* context, const ::google::protobuf::Empty* request, ::google::protobuf::BoolValue* response, ::grpc::ClientUnaryReactor* reactor) override; + void SetIsTelemetryDisabled(::grpc::ClientContext* context, const ::google::protobuf::BoolValue* request, ::google::protobuf::Empty* response, std::function) override; + void SetIsTelemetryDisabled(::grpc::ClientContext* context, const ::google::protobuf::BoolValue* request, ::google::protobuf::Empty* response, ::grpc::ClientUnaryReactor* reactor) override; + void IsTelemetryDisabled(::grpc::ClientContext* context, const ::google::protobuf::Empty* request, ::google::protobuf::BoolValue* response, std::function) override; + void IsTelemetryDisabled(::grpc::ClientContext* context, const ::google::protobuf::Empty* request, ::google::protobuf::BoolValue* response, ::grpc::ClientUnaryReactor* reactor) override; void GoOs(::grpc::ClientContext* context, const ::google::protobuf::Empty* request, ::google::protobuf::StringValue* response, std::function) override; void GoOs(::grpc::ClientContext* context, const ::google::protobuf::Empty* request, ::google::protobuf::StringValue* response, ::grpc::ClientUnaryReactor* reactor) override; void TriggerReset(::grpc::ClientContext* context, const ::google::protobuf::Empty* request, ::google::protobuf::Empty* response, std::function) override; @@ -1229,6 +1269,10 @@ class Bridge final { ::grpc::ClientAsyncResponseReader< ::google::protobuf::Empty>* PrepareAsyncSetIsAllMailVisibleRaw(::grpc::ClientContext* context, const ::google::protobuf::BoolValue& request, ::grpc::CompletionQueue* cq) override; ::grpc::ClientAsyncResponseReader< ::google::protobuf::BoolValue>* AsyncIsAllMailVisibleRaw(::grpc::ClientContext* context, const ::google::protobuf::Empty& request, ::grpc::CompletionQueue* cq) override; ::grpc::ClientAsyncResponseReader< ::google::protobuf::BoolValue>* PrepareAsyncIsAllMailVisibleRaw(::grpc::ClientContext* context, const ::google::protobuf::Empty& request, ::grpc::CompletionQueue* cq) override; + ::grpc::ClientAsyncResponseReader< ::google::protobuf::Empty>* AsyncSetIsTelemetryDisabledRaw(::grpc::ClientContext* context, const ::google::protobuf::BoolValue& request, ::grpc::CompletionQueue* cq) override; + ::grpc::ClientAsyncResponseReader< ::google::protobuf::Empty>* PrepareAsyncSetIsTelemetryDisabledRaw(::grpc::ClientContext* context, const ::google::protobuf::BoolValue& request, ::grpc::CompletionQueue* cq) override; + ::grpc::ClientAsyncResponseReader< ::google::protobuf::BoolValue>* AsyncIsTelemetryDisabledRaw(::grpc::ClientContext* context, const ::google::protobuf::Empty& request, ::grpc::CompletionQueue* cq) override; + ::grpc::ClientAsyncResponseReader< ::google::protobuf::BoolValue>* PrepareAsyncIsTelemetryDisabledRaw(::grpc::ClientContext* context, const ::google::protobuf::Empty& request, ::grpc::CompletionQueue* cq) override; ::grpc::ClientAsyncResponseReader< ::google::protobuf::StringValue>* AsyncGoOsRaw(::grpc::ClientContext* context, const ::google::protobuf::Empty& request, ::grpc::CompletionQueue* cq) override; ::grpc::ClientAsyncResponseReader< ::google::protobuf::StringValue>* PrepareAsyncGoOsRaw(::grpc::ClientContext* context, const ::google::protobuf::Empty& request, ::grpc::CompletionQueue* cq) override; ::grpc::ClientAsyncResponseReader< ::google::protobuf::Empty>* AsyncTriggerResetRaw(::grpc::ClientContext* context, const ::google::protobuf::Empty& request, ::grpc::CompletionQueue* cq) override; @@ -1328,6 +1372,8 @@ class Bridge final { const ::grpc::internal::RpcMethod rpcmethod_IsBetaEnabled_; const ::grpc::internal::RpcMethod rpcmethod_SetIsAllMailVisible_; const ::grpc::internal::RpcMethod rpcmethod_IsAllMailVisible_; + const ::grpc::internal::RpcMethod rpcmethod_SetIsTelemetryDisabled_; + const ::grpc::internal::RpcMethod rpcmethod_IsTelemetryDisabled_; const ::grpc::internal::RpcMethod rpcmethod_GoOs_; const ::grpc::internal::RpcMethod rpcmethod_TriggerReset_; const ::grpc::internal::RpcMethod rpcmethod_Version_; @@ -1391,6 +1437,8 @@ class Bridge final { virtual ::grpc::Status IsBetaEnabled(::grpc::ServerContext* context, const ::google::protobuf::Empty* request, ::google::protobuf::BoolValue* response); virtual ::grpc::Status SetIsAllMailVisible(::grpc::ServerContext* context, const ::google::protobuf::BoolValue* request, ::google::protobuf::Empty* response); virtual ::grpc::Status IsAllMailVisible(::grpc::ServerContext* context, const ::google::protobuf::Empty* request, ::google::protobuf::BoolValue* response); + virtual ::grpc::Status SetIsTelemetryDisabled(::grpc::ServerContext* context, const ::google::protobuf::BoolValue* request, ::google::protobuf::Empty* response); + virtual ::grpc::Status IsTelemetryDisabled(::grpc::ServerContext* context, const ::google::protobuf::Empty* request, ::google::protobuf::BoolValue* response); virtual ::grpc::Status GoOs(::grpc::ServerContext* context, const ::google::protobuf::Empty* request, ::google::protobuf::StringValue* response); virtual ::grpc::Status TriggerReset(::grpc::ServerContext* context, const ::google::protobuf::Empty* request, ::google::protobuf::Empty* response); virtual ::grpc::Status Version(::grpc::ServerContext* context, const ::google::protobuf::Empty* request, ::google::protobuf::StringValue* response); @@ -1685,12 +1733,52 @@ class Bridge final { } }; template + class WithAsyncMethod_SetIsTelemetryDisabled : public BaseClass { + private: + void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} + public: + WithAsyncMethod_SetIsTelemetryDisabled() { + ::grpc::Service::MarkMethodAsync(12); + } + ~WithAsyncMethod_SetIsTelemetryDisabled() override { + BaseClassMustBeDerivedFromService(this); + } + // disable synchronous version of this method + ::grpc::Status SetIsTelemetryDisabled(::grpc::ServerContext* /*context*/, const ::google::protobuf::BoolValue* /*request*/, ::google::protobuf::Empty* /*response*/) override { + abort(); + return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); + } + void RequestSetIsTelemetryDisabled(::grpc::ServerContext* context, ::google::protobuf::BoolValue* request, ::grpc::ServerAsyncResponseWriter< ::google::protobuf::Empty>* response, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) { + ::grpc::Service::RequestAsyncUnary(12, context, request, response, new_call_cq, notification_cq, tag); + } + }; + template + class WithAsyncMethod_IsTelemetryDisabled : public BaseClass { + private: + void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} + public: + WithAsyncMethod_IsTelemetryDisabled() { + ::grpc::Service::MarkMethodAsync(13); + } + ~WithAsyncMethod_IsTelemetryDisabled() override { + BaseClassMustBeDerivedFromService(this); + } + // disable synchronous version of this method + ::grpc::Status IsTelemetryDisabled(::grpc::ServerContext* /*context*/, const ::google::protobuf::Empty* /*request*/, ::google::protobuf::BoolValue* /*response*/) override { + abort(); + return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); + } + void RequestIsTelemetryDisabled(::grpc::ServerContext* context, ::google::protobuf::Empty* request, ::grpc::ServerAsyncResponseWriter< ::google::protobuf::BoolValue>* response, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) { + ::grpc::Service::RequestAsyncUnary(13, context, request, response, new_call_cq, notification_cq, tag); + } + }; + template class WithAsyncMethod_GoOs : public BaseClass { private: void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithAsyncMethod_GoOs() { - ::grpc::Service::MarkMethodAsync(12); + ::grpc::Service::MarkMethodAsync(14); } ~WithAsyncMethod_GoOs() override { BaseClassMustBeDerivedFromService(this); @@ -1701,7 +1789,7 @@ class Bridge final { return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); } void RequestGoOs(::grpc::ServerContext* context, ::google::protobuf::Empty* request, ::grpc::ServerAsyncResponseWriter< ::google::protobuf::StringValue>* response, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) { - ::grpc::Service::RequestAsyncUnary(12, context, request, response, new_call_cq, notification_cq, tag); + ::grpc::Service::RequestAsyncUnary(14, context, request, response, new_call_cq, notification_cq, tag); } }; template @@ -1710,7 +1798,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithAsyncMethod_TriggerReset() { - ::grpc::Service::MarkMethodAsync(13); + ::grpc::Service::MarkMethodAsync(15); } ~WithAsyncMethod_TriggerReset() override { BaseClassMustBeDerivedFromService(this); @@ -1721,7 +1809,7 @@ class Bridge final { return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); } void RequestTriggerReset(::grpc::ServerContext* context, ::google::protobuf::Empty* request, ::grpc::ServerAsyncResponseWriter< ::google::protobuf::Empty>* response, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) { - ::grpc::Service::RequestAsyncUnary(13, context, request, response, new_call_cq, notification_cq, tag); + ::grpc::Service::RequestAsyncUnary(15, context, request, response, new_call_cq, notification_cq, tag); } }; template @@ -1730,7 +1818,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithAsyncMethod_Version() { - ::grpc::Service::MarkMethodAsync(14); + ::grpc::Service::MarkMethodAsync(16); } ~WithAsyncMethod_Version() override { BaseClassMustBeDerivedFromService(this); @@ -1741,7 +1829,7 @@ class Bridge final { return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); } void RequestVersion(::grpc::ServerContext* context, ::google::protobuf::Empty* request, ::grpc::ServerAsyncResponseWriter< ::google::protobuf::StringValue>* response, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) { - ::grpc::Service::RequestAsyncUnary(14, context, request, response, new_call_cq, notification_cq, tag); + ::grpc::Service::RequestAsyncUnary(16, context, request, response, new_call_cq, notification_cq, tag); } }; template @@ -1750,7 +1838,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithAsyncMethod_LogsPath() { - ::grpc::Service::MarkMethodAsync(15); + ::grpc::Service::MarkMethodAsync(17); } ~WithAsyncMethod_LogsPath() override { BaseClassMustBeDerivedFromService(this); @@ -1761,7 +1849,7 @@ class Bridge final { return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); } void RequestLogsPath(::grpc::ServerContext* context, ::google::protobuf::Empty* request, ::grpc::ServerAsyncResponseWriter< ::google::protobuf::StringValue>* response, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) { - ::grpc::Service::RequestAsyncUnary(15, context, request, response, new_call_cq, notification_cq, tag); + ::grpc::Service::RequestAsyncUnary(17, context, request, response, new_call_cq, notification_cq, tag); } }; template @@ -1770,7 +1858,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithAsyncMethod_LicensePath() { - ::grpc::Service::MarkMethodAsync(16); + ::grpc::Service::MarkMethodAsync(18); } ~WithAsyncMethod_LicensePath() override { BaseClassMustBeDerivedFromService(this); @@ -1781,7 +1869,7 @@ class Bridge final { return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); } void RequestLicensePath(::grpc::ServerContext* context, ::google::protobuf::Empty* request, ::grpc::ServerAsyncResponseWriter< ::google::protobuf::StringValue>* response, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) { - ::grpc::Service::RequestAsyncUnary(16, context, request, response, new_call_cq, notification_cq, tag); + ::grpc::Service::RequestAsyncUnary(18, context, request, response, new_call_cq, notification_cq, tag); } }; template @@ -1790,7 +1878,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithAsyncMethod_ReleaseNotesPageLink() { - ::grpc::Service::MarkMethodAsync(17); + ::grpc::Service::MarkMethodAsync(19); } ~WithAsyncMethod_ReleaseNotesPageLink() override { BaseClassMustBeDerivedFromService(this); @@ -1801,7 +1889,7 @@ class Bridge final { return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); } void RequestReleaseNotesPageLink(::grpc::ServerContext* context, ::google::protobuf::Empty* request, ::grpc::ServerAsyncResponseWriter< ::google::protobuf::StringValue>* response, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) { - ::grpc::Service::RequestAsyncUnary(17, context, request, response, new_call_cq, notification_cq, tag); + ::grpc::Service::RequestAsyncUnary(19, context, request, response, new_call_cq, notification_cq, tag); } }; template @@ -1810,7 +1898,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithAsyncMethod_DependencyLicensesLink() { - ::grpc::Service::MarkMethodAsync(18); + ::grpc::Service::MarkMethodAsync(20); } ~WithAsyncMethod_DependencyLicensesLink() override { BaseClassMustBeDerivedFromService(this); @@ -1821,7 +1909,7 @@ class Bridge final { return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); } void RequestDependencyLicensesLink(::grpc::ServerContext* context, ::google::protobuf::Empty* request, ::grpc::ServerAsyncResponseWriter< ::google::protobuf::StringValue>* response, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) { - ::grpc::Service::RequestAsyncUnary(18, context, request, response, new_call_cq, notification_cq, tag); + ::grpc::Service::RequestAsyncUnary(20, context, request, response, new_call_cq, notification_cq, tag); } }; template @@ -1830,7 +1918,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithAsyncMethod_LandingPageLink() { - ::grpc::Service::MarkMethodAsync(19); + ::grpc::Service::MarkMethodAsync(21); } ~WithAsyncMethod_LandingPageLink() override { BaseClassMustBeDerivedFromService(this); @@ -1841,7 +1929,7 @@ class Bridge final { return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); } void RequestLandingPageLink(::grpc::ServerContext* context, ::google::protobuf::Empty* request, ::grpc::ServerAsyncResponseWriter< ::google::protobuf::StringValue>* response, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) { - ::grpc::Service::RequestAsyncUnary(19, context, request, response, new_call_cq, notification_cq, tag); + ::grpc::Service::RequestAsyncUnary(21, context, request, response, new_call_cq, notification_cq, tag); } }; template @@ -1850,7 +1938,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithAsyncMethod_SetColorSchemeName() { - ::grpc::Service::MarkMethodAsync(20); + ::grpc::Service::MarkMethodAsync(22); } ~WithAsyncMethod_SetColorSchemeName() override { BaseClassMustBeDerivedFromService(this); @@ -1861,7 +1949,7 @@ class Bridge final { return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); } void RequestSetColorSchemeName(::grpc::ServerContext* context, ::google::protobuf::StringValue* request, ::grpc::ServerAsyncResponseWriter< ::google::protobuf::Empty>* response, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) { - ::grpc::Service::RequestAsyncUnary(20, context, request, response, new_call_cq, notification_cq, tag); + ::grpc::Service::RequestAsyncUnary(22, context, request, response, new_call_cq, notification_cq, tag); } }; template @@ -1870,7 +1958,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithAsyncMethod_ColorSchemeName() { - ::grpc::Service::MarkMethodAsync(21); + ::grpc::Service::MarkMethodAsync(23); } ~WithAsyncMethod_ColorSchemeName() override { BaseClassMustBeDerivedFromService(this); @@ -1881,7 +1969,7 @@ class Bridge final { return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); } void RequestColorSchemeName(::grpc::ServerContext* context, ::google::protobuf::Empty* request, ::grpc::ServerAsyncResponseWriter< ::google::protobuf::StringValue>* response, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) { - ::grpc::Service::RequestAsyncUnary(21, context, request, response, new_call_cq, notification_cq, tag); + ::grpc::Service::RequestAsyncUnary(23, context, request, response, new_call_cq, notification_cq, tag); } }; template @@ -1890,7 +1978,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithAsyncMethod_CurrentEmailClient() { - ::grpc::Service::MarkMethodAsync(22); + ::grpc::Service::MarkMethodAsync(24); } ~WithAsyncMethod_CurrentEmailClient() override { BaseClassMustBeDerivedFromService(this); @@ -1901,7 +1989,7 @@ class Bridge final { return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); } void RequestCurrentEmailClient(::grpc::ServerContext* context, ::google::protobuf::Empty* request, ::grpc::ServerAsyncResponseWriter< ::google::protobuf::StringValue>* response, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) { - ::grpc::Service::RequestAsyncUnary(22, context, request, response, new_call_cq, notification_cq, tag); + ::grpc::Service::RequestAsyncUnary(24, context, request, response, new_call_cq, notification_cq, tag); } }; template @@ -1910,7 +1998,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithAsyncMethod_ReportBug() { - ::grpc::Service::MarkMethodAsync(23); + ::grpc::Service::MarkMethodAsync(25); } ~WithAsyncMethod_ReportBug() override { BaseClassMustBeDerivedFromService(this); @@ -1921,7 +2009,7 @@ class Bridge final { return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); } void RequestReportBug(::grpc::ServerContext* context, ::grpc::ReportBugRequest* request, ::grpc::ServerAsyncResponseWriter< ::google::protobuf::Empty>* response, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) { - ::grpc::Service::RequestAsyncUnary(23, context, request, response, new_call_cq, notification_cq, tag); + ::grpc::Service::RequestAsyncUnary(25, context, request, response, new_call_cq, notification_cq, tag); } }; template @@ -1930,7 +2018,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithAsyncMethod_ExportTLSCertificates() { - ::grpc::Service::MarkMethodAsync(24); + ::grpc::Service::MarkMethodAsync(26); } ~WithAsyncMethod_ExportTLSCertificates() override { BaseClassMustBeDerivedFromService(this); @@ -1941,7 +2029,7 @@ class Bridge final { return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); } void RequestExportTLSCertificates(::grpc::ServerContext* context, ::google::protobuf::StringValue* request, ::grpc::ServerAsyncResponseWriter< ::google::protobuf::Empty>* response, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) { - ::grpc::Service::RequestAsyncUnary(24, context, request, response, new_call_cq, notification_cq, tag); + ::grpc::Service::RequestAsyncUnary(26, context, request, response, new_call_cq, notification_cq, tag); } }; template @@ -1950,7 +2038,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithAsyncMethod_ForceLauncher() { - ::grpc::Service::MarkMethodAsync(25); + ::grpc::Service::MarkMethodAsync(27); } ~WithAsyncMethod_ForceLauncher() override { BaseClassMustBeDerivedFromService(this); @@ -1961,7 +2049,7 @@ class Bridge final { return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); } void RequestForceLauncher(::grpc::ServerContext* context, ::google::protobuf::StringValue* request, ::grpc::ServerAsyncResponseWriter< ::google::protobuf::Empty>* response, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) { - ::grpc::Service::RequestAsyncUnary(25, context, request, response, new_call_cq, notification_cq, tag); + ::grpc::Service::RequestAsyncUnary(27, context, request, response, new_call_cq, notification_cq, tag); } }; template @@ -1970,7 +2058,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithAsyncMethod_SetMainExecutable() { - ::grpc::Service::MarkMethodAsync(26); + ::grpc::Service::MarkMethodAsync(28); } ~WithAsyncMethod_SetMainExecutable() override { BaseClassMustBeDerivedFromService(this); @@ -1981,7 +2069,7 @@ class Bridge final { return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); } void RequestSetMainExecutable(::grpc::ServerContext* context, ::google::protobuf::StringValue* request, ::grpc::ServerAsyncResponseWriter< ::google::protobuf::Empty>* response, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) { - ::grpc::Service::RequestAsyncUnary(26, context, request, response, new_call_cq, notification_cq, tag); + ::grpc::Service::RequestAsyncUnary(28, context, request, response, new_call_cq, notification_cq, tag); } }; template @@ -1990,7 +2078,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithAsyncMethod_Login() { - ::grpc::Service::MarkMethodAsync(27); + ::grpc::Service::MarkMethodAsync(29); } ~WithAsyncMethod_Login() override { BaseClassMustBeDerivedFromService(this); @@ -2001,7 +2089,7 @@ class Bridge final { return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); } void RequestLogin(::grpc::ServerContext* context, ::grpc::LoginRequest* request, ::grpc::ServerAsyncResponseWriter< ::google::protobuf::Empty>* response, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) { - ::grpc::Service::RequestAsyncUnary(27, context, request, response, new_call_cq, notification_cq, tag); + ::grpc::Service::RequestAsyncUnary(29, context, request, response, new_call_cq, notification_cq, tag); } }; template @@ -2010,7 +2098,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithAsyncMethod_Login2FA() { - ::grpc::Service::MarkMethodAsync(28); + ::grpc::Service::MarkMethodAsync(30); } ~WithAsyncMethod_Login2FA() override { BaseClassMustBeDerivedFromService(this); @@ -2021,7 +2109,7 @@ class Bridge final { return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); } void RequestLogin2FA(::grpc::ServerContext* context, ::grpc::LoginRequest* request, ::grpc::ServerAsyncResponseWriter< ::google::protobuf::Empty>* response, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) { - ::grpc::Service::RequestAsyncUnary(28, context, request, response, new_call_cq, notification_cq, tag); + ::grpc::Service::RequestAsyncUnary(30, context, request, response, new_call_cq, notification_cq, tag); } }; template @@ -2030,7 +2118,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithAsyncMethod_Login2Passwords() { - ::grpc::Service::MarkMethodAsync(29); + ::grpc::Service::MarkMethodAsync(31); } ~WithAsyncMethod_Login2Passwords() override { BaseClassMustBeDerivedFromService(this); @@ -2041,7 +2129,7 @@ class Bridge final { return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); } void RequestLogin2Passwords(::grpc::ServerContext* context, ::grpc::LoginRequest* request, ::grpc::ServerAsyncResponseWriter< ::google::protobuf::Empty>* response, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) { - ::grpc::Service::RequestAsyncUnary(29, context, request, response, new_call_cq, notification_cq, tag); + ::grpc::Service::RequestAsyncUnary(31, context, request, response, new_call_cq, notification_cq, tag); } }; template @@ -2050,7 +2138,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithAsyncMethod_LoginAbort() { - ::grpc::Service::MarkMethodAsync(30); + ::grpc::Service::MarkMethodAsync(32); } ~WithAsyncMethod_LoginAbort() override { BaseClassMustBeDerivedFromService(this); @@ -2061,7 +2149,7 @@ class Bridge final { return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); } void RequestLoginAbort(::grpc::ServerContext* context, ::grpc::LoginAbortRequest* request, ::grpc::ServerAsyncResponseWriter< ::google::protobuf::Empty>* response, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) { - ::grpc::Service::RequestAsyncUnary(30, context, request, response, new_call_cq, notification_cq, tag); + ::grpc::Service::RequestAsyncUnary(32, context, request, response, new_call_cq, notification_cq, tag); } }; template @@ -2070,7 +2158,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithAsyncMethod_CheckUpdate() { - ::grpc::Service::MarkMethodAsync(31); + ::grpc::Service::MarkMethodAsync(33); } ~WithAsyncMethod_CheckUpdate() override { BaseClassMustBeDerivedFromService(this); @@ -2081,7 +2169,7 @@ class Bridge final { return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); } void RequestCheckUpdate(::grpc::ServerContext* context, ::google::protobuf::Empty* request, ::grpc::ServerAsyncResponseWriter< ::google::protobuf::Empty>* response, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) { - ::grpc::Service::RequestAsyncUnary(31, context, request, response, new_call_cq, notification_cq, tag); + ::grpc::Service::RequestAsyncUnary(33, context, request, response, new_call_cq, notification_cq, tag); } }; template @@ -2090,7 +2178,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithAsyncMethod_InstallUpdate() { - ::grpc::Service::MarkMethodAsync(32); + ::grpc::Service::MarkMethodAsync(34); } ~WithAsyncMethod_InstallUpdate() override { BaseClassMustBeDerivedFromService(this); @@ -2101,7 +2189,7 @@ class Bridge final { return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); } void RequestInstallUpdate(::grpc::ServerContext* context, ::google::protobuf::Empty* request, ::grpc::ServerAsyncResponseWriter< ::google::protobuf::Empty>* response, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) { - ::grpc::Service::RequestAsyncUnary(32, context, request, response, new_call_cq, notification_cq, tag); + ::grpc::Service::RequestAsyncUnary(34, context, request, response, new_call_cq, notification_cq, tag); } }; template @@ -2110,7 +2198,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithAsyncMethod_SetIsAutomaticUpdateOn() { - ::grpc::Service::MarkMethodAsync(33); + ::grpc::Service::MarkMethodAsync(35); } ~WithAsyncMethod_SetIsAutomaticUpdateOn() override { BaseClassMustBeDerivedFromService(this); @@ -2121,7 +2209,7 @@ class Bridge final { return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); } void RequestSetIsAutomaticUpdateOn(::grpc::ServerContext* context, ::google::protobuf::BoolValue* request, ::grpc::ServerAsyncResponseWriter< ::google::protobuf::Empty>* response, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) { - ::grpc::Service::RequestAsyncUnary(33, context, request, response, new_call_cq, notification_cq, tag); + ::grpc::Service::RequestAsyncUnary(35, context, request, response, new_call_cq, notification_cq, tag); } }; template @@ -2130,7 +2218,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithAsyncMethod_IsAutomaticUpdateOn() { - ::grpc::Service::MarkMethodAsync(34); + ::grpc::Service::MarkMethodAsync(36); } ~WithAsyncMethod_IsAutomaticUpdateOn() override { BaseClassMustBeDerivedFromService(this); @@ -2141,7 +2229,7 @@ class Bridge final { return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); } void RequestIsAutomaticUpdateOn(::grpc::ServerContext* context, ::google::protobuf::Empty* request, ::grpc::ServerAsyncResponseWriter< ::google::protobuf::BoolValue>* response, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) { - ::grpc::Service::RequestAsyncUnary(34, context, request, response, new_call_cq, notification_cq, tag); + ::grpc::Service::RequestAsyncUnary(36, context, request, response, new_call_cq, notification_cq, tag); } }; template @@ -2150,7 +2238,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithAsyncMethod_DiskCachePath() { - ::grpc::Service::MarkMethodAsync(35); + ::grpc::Service::MarkMethodAsync(37); } ~WithAsyncMethod_DiskCachePath() override { BaseClassMustBeDerivedFromService(this); @@ -2161,7 +2249,7 @@ class Bridge final { return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); } void RequestDiskCachePath(::grpc::ServerContext* context, ::google::protobuf::Empty* request, ::grpc::ServerAsyncResponseWriter< ::google::protobuf::StringValue>* response, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) { - ::grpc::Service::RequestAsyncUnary(35, context, request, response, new_call_cq, notification_cq, tag); + ::grpc::Service::RequestAsyncUnary(37, context, request, response, new_call_cq, notification_cq, tag); } }; template @@ -2170,7 +2258,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithAsyncMethod_SetDiskCachePath() { - ::grpc::Service::MarkMethodAsync(36); + ::grpc::Service::MarkMethodAsync(38); } ~WithAsyncMethod_SetDiskCachePath() override { BaseClassMustBeDerivedFromService(this); @@ -2181,7 +2269,7 @@ class Bridge final { return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); } void RequestSetDiskCachePath(::grpc::ServerContext* context, ::google::protobuf::StringValue* request, ::grpc::ServerAsyncResponseWriter< ::google::protobuf::Empty>* response, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) { - ::grpc::Service::RequestAsyncUnary(36, context, request, response, new_call_cq, notification_cq, tag); + ::grpc::Service::RequestAsyncUnary(38, context, request, response, new_call_cq, notification_cq, tag); } }; template @@ -2190,7 +2278,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithAsyncMethod_SetIsDoHEnabled() { - ::grpc::Service::MarkMethodAsync(37); + ::grpc::Service::MarkMethodAsync(39); } ~WithAsyncMethod_SetIsDoHEnabled() override { BaseClassMustBeDerivedFromService(this); @@ -2201,7 +2289,7 @@ class Bridge final { return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); } void RequestSetIsDoHEnabled(::grpc::ServerContext* context, ::google::protobuf::BoolValue* request, ::grpc::ServerAsyncResponseWriter< ::google::protobuf::Empty>* response, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) { - ::grpc::Service::RequestAsyncUnary(37, context, request, response, new_call_cq, notification_cq, tag); + ::grpc::Service::RequestAsyncUnary(39, context, request, response, new_call_cq, notification_cq, tag); } }; template @@ -2210,7 +2298,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithAsyncMethod_IsDoHEnabled() { - ::grpc::Service::MarkMethodAsync(38); + ::grpc::Service::MarkMethodAsync(40); } ~WithAsyncMethod_IsDoHEnabled() override { BaseClassMustBeDerivedFromService(this); @@ -2221,7 +2309,7 @@ class Bridge final { return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); } void RequestIsDoHEnabled(::grpc::ServerContext* context, ::google::protobuf::Empty* request, ::grpc::ServerAsyncResponseWriter< ::google::protobuf::BoolValue>* response, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) { - ::grpc::Service::RequestAsyncUnary(38, context, request, response, new_call_cq, notification_cq, tag); + ::grpc::Service::RequestAsyncUnary(40, context, request, response, new_call_cq, notification_cq, tag); } }; template @@ -2230,7 +2318,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithAsyncMethod_MailServerSettings() { - ::grpc::Service::MarkMethodAsync(39); + ::grpc::Service::MarkMethodAsync(41); } ~WithAsyncMethod_MailServerSettings() override { BaseClassMustBeDerivedFromService(this); @@ -2241,7 +2329,7 @@ class Bridge final { return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); } void RequestMailServerSettings(::grpc::ServerContext* context, ::google::protobuf::Empty* request, ::grpc::ServerAsyncResponseWriter< ::grpc::ImapSmtpSettings>* response, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) { - ::grpc::Service::RequestAsyncUnary(39, context, request, response, new_call_cq, notification_cq, tag); + ::grpc::Service::RequestAsyncUnary(41, context, request, response, new_call_cq, notification_cq, tag); } }; template @@ -2250,7 +2338,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithAsyncMethod_SetMailServerSettings() { - ::grpc::Service::MarkMethodAsync(40); + ::grpc::Service::MarkMethodAsync(42); } ~WithAsyncMethod_SetMailServerSettings() override { BaseClassMustBeDerivedFromService(this); @@ -2261,7 +2349,7 @@ class Bridge final { return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); } void RequestSetMailServerSettings(::grpc::ServerContext* context, ::grpc::ImapSmtpSettings* request, ::grpc::ServerAsyncResponseWriter< ::google::protobuf::Empty>* response, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) { - ::grpc::Service::RequestAsyncUnary(40, context, request, response, new_call_cq, notification_cq, tag); + ::grpc::Service::RequestAsyncUnary(42, context, request, response, new_call_cq, notification_cq, tag); } }; template @@ -2270,7 +2358,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithAsyncMethod_Hostname() { - ::grpc::Service::MarkMethodAsync(41); + ::grpc::Service::MarkMethodAsync(43); } ~WithAsyncMethod_Hostname() override { BaseClassMustBeDerivedFromService(this); @@ -2281,7 +2369,7 @@ class Bridge final { return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); } void RequestHostname(::grpc::ServerContext* context, ::google::protobuf::Empty* request, ::grpc::ServerAsyncResponseWriter< ::google::protobuf::StringValue>* response, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) { - ::grpc::Service::RequestAsyncUnary(41, context, request, response, new_call_cq, notification_cq, tag); + ::grpc::Service::RequestAsyncUnary(43, context, request, response, new_call_cq, notification_cq, tag); } }; template @@ -2290,7 +2378,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithAsyncMethod_IsPortFree() { - ::grpc::Service::MarkMethodAsync(42); + ::grpc::Service::MarkMethodAsync(44); } ~WithAsyncMethod_IsPortFree() override { BaseClassMustBeDerivedFromService(this); @@ -2301,7 +2389,7 @@ class Bridge final { return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); } void RequestIsPortFree(::grpc::ServerContext* context, ::google::protobuf::Int32Value* request, ::grpc::ServerAsyncResponseWriter< ::google::protobuf::BoolValue>* response, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) { - ::grpc::Service::RequestAsyncUnary(42, context, request, response, new_call_cq, notification_cq, tag); + ::grpc::Service::RequestAsyncUnary(44, context, request, response, new_call_cq, notification_cq, tag); } }; template @@ -2310,7 +2398,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithAsyncMethod_AvailableKeychains() { - ::grpc::Service::MarkMethodAsync(43); + ::grpc::Service::MarkMethodAsync(45); } ~WithAsyncMethod_AvailableKeychains() override { BaseClassMustBeDerivedFromService(this); @@ -2321,7 +2409,7 @@ class Bridge final { return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); } void RequestAvailableKeychains(::grpc::ServerContext* context, ::google::protobuf::Empty* request, ::grpc::ServerAsyncResponseWriter< ::grpc::AvailableKeychainsResponse>* response, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) { - ::grpc::Service::RequestAsyncUnary(43, context, request, response, new_call_cq, notification_cq, tag); + ::grpc::Service::RequestAsyncUnary(45, context, request, response, new_call_cq, notification_cq, tag); } }; template @@ -2330,7 +2418,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithAsyncMethod_SetCurrentKeychain() { - ::grpc::Service::MarkMethodAsync(44); + ::grpc::Service::MarkMethodAsync(46); } ~WithAsyncMethod_SetCurrentKeychain() override { BaseClassMustBeDerivedFromService(this); @@ -2341,7 +2429,7 @@ class Bridge final { return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); } void RequestSetCurrentKeychain(::grpc::ServerContext* context, ::google::protobuf::StringValue* request, ::grpc::ServerAsyncResponseWriter< ::google::protobuf::Empty>* response, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) { - ::grpc::Service::RequestAsyncUnary(44, context, request, response, new_call_cq, notification_cq, tag); + ::grpc::Service::RequestAsyncUnary(46, context, request, response, new_call_cq, notification_cq, tag); } }; template @@ -2350,7 +2438,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithAsyncMethod_CurrentKeychain() { - ::grpc::Service::MarkMethodAsync(45); + ::grpc::Service::MarkMethodAsync(47); } ~WithAsyncMethod_CurrentKeychain() override { BaseClassMustBeDerivedFromService(this); @@ -2361,7 +2449,7 @@ class Bridge final { return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); } void RequestCurrentKeychain(::grpc::ServerContext* context, ::google::protobuf::Empty* request, ::grpc::ServerAsyncResponseWriter< ::google::protobuf::StringValue>* response, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) { - ::grpc::Service::RequestAsyncUnary(45, context, request, response, new_call_cq, notification_cq, tag); + ::grpc::Service::RequestAsyncUnary(47, context, request, response, new_call_cq, notification_cq, tag); } }; template @@ -2370,7 +2458,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithAsyncMethod_GetUserList() { - ::grpc::Service::MarkMethodAsync(46); + ::grpc::Service::MarkMethodAsync(48); } ~WithAsyncMethod_GetUserList() override { BaseClassMustBeDerivedFromService(this); @@ -2381,7 +2469,7 @@ class Bridge final { return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); } void RequestGetUserList(::grpc::ServerContext* context, ::google::protobuf::Empty* request, ::grpc::ServerAsyncResponseWriter< ::grpc::UserListResponse>* response, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) { - ::grpc::Service::RequestAsyncUnary(46, context, request, response, new_call_cq, notification_cq, tag); + ::grpc::Service::RequestAsyncUnary(48, context, request, response, new_call_cq, notification_cq, tag); } }; template @@ -2390,7 +2478,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithAsyncMethod_GetUser() { - ::grpc::Service::MarkMethodAsync(47); + ::grpc::Service::MarkMethodAsync(49); } ~WithAsyncMethod_GetUser() override { BaseClassMustBeDerivedFromService(this); @@ -2401,7 +2489,7 @@ class Bridge final { return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); } void RequestGetUser(::grpc::ServerContext* context, ::google::protobuf::StringValue* request, ::grpc::ServerAsyncResponseWriter< ::grpc::User>* response, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) { - ::grpc::Service::RequestAsyncUnary(47, context, request, response, new_call_cq, notification_cq, tag); + ::grpc::Service::RequestAsyncUnary(49, context, request, response, new_call_cq, notification_cq, tag); } }; template @@ -2410,7 +2498,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithAsyncMethod_SetUserSplitMode() { - ::grpc::Service::MarkMethodAsync(48); + ::grpc::Service::MarkMethodAsync(50); } ~WithAsyncMethod_SetUserSplitMode() override { BaseClassMustBeDerivedFromService(this); @@ -2421,7 +2509,7 @@ class Bridge final { return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); } void RequestSetUserSplitMode(::grpc::ServerContext* context, ::grpc::UserSplitModeRequest* request, ::grpc::ServerAsyncResponseWriter< ::google::protobuf::Empty>* response, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) { - ::grpc::Service::RequestAsyncUnary(48, context, request, response, new_call_cq, notification_cq, tag); + ::grpc::Service::RequestAsyncUnary(50, context, request, response, new_call_cq, notification_cq, tag); } }; template @@ -2430,7 +2518,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithAsyncMethod_SendBadEventUserFeedback() { - ::grpc::Service::MarkMethodAsync(49); + ::grpc::Service::MarkMethodAsync(51); } ~WithAsyncMethod_SendBadEventUserFeedback() override { BaseClassMustBeDerivedFromService(this); @@ -2441,7 +2529,7 @@ class Bridge final { return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); } void RequestSendBadEventUserFeedback(::grpc::ServerContext* context, ::grpc::UserBadEventFeedbackRequest* request, ::grpc::ServerAsyncResponseWriter< ::google::protobuf::Empty>* response, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) { - ::grpc::Service::RequestAsyncUnary(49, context, request, response, new_call_cq, notification_cq, tag); + ::grpc::Service::RequestAsyncUnary(51, context, request, response, new_call_cq, notification_cq, tag); } }; template @@ -2450,7 +2538,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithAsyncMethod_LogoutUser() { - ::grpc::Service::MarkMethodAsync(50); + ::grpc::Service::MarkMethodAsync(52); } ~WithAsyncMethod_LogoutUser() override { BaseClassMustBeDerivedFromService(this); @@ -2461,7 +2549,7 @@ class Bridge final { return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); } void RequestLogoutUser(::grpc::ServerContext* context, ::google::protobuf::StringValue* request, ::grpc::ServerAsyncResponseWriter< ::google::protobuf::Empty>* response, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) { - ::grpc::Service::RequestAsyncUnary(50, context, request, response, new_call_cq, notification_cq, tag); + ::grpc::Service::RequestAsyncUnary(52, context, request, response, new_call_cq, notification_cq, tag); } }; template @@ -2470,7 +2558,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithAsyncMethod_RemoveUser() { - ::grpc::Service::MarkMethodAsync(51); + ::grpc::Service::MarkMethodAsync(53); } ~WithAsyncMethod_RemoveUser() override { BaseClassMustBeDerivedFromService(this); @@ -2481,7 +2569,7 @@ class Bridge final { return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); } void RequestRemoveUser(::grpc::ServerContext* context, ::google::protobuf::StringValue* request, ::grpc::ServerAsyncResponseWriter< ::google::protobuf::Empty>* response, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) { - ::grpc::Service::RequestAsyncUnary(51, context, request, response, new_call_cq, notification_cq, tag); + ::grpc::Service::RequestAsyncUnary(53, context, request, response, new_call_cq, notification_cq, tag); } }; template @@ -2490,7 +2578,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithAsyncMethod_ConfigureUserAppleMail() { - ::grpc::Service::MarkMethodAsync(52); + ::grpc::Service::MarkMethodAsync(54); } ~WithAsyncMethod_ConfigureUserAppleMail() override { BaseClassMustBeDerivedFromService(this); @@ -2501,7 +2589,7 @@ class Bridge final { return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); } void RequestConfigureUserAppleMail(::grpc::ServerContext* context, ::grpc::ConfigureAppleMailRequest* request, ::grpc::ServerAsyncResponseWriter< ::google::protobuf::Empty>* response, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) { - ::grpc::Service::RequestAsyncUnary(52, context, request, response, new_call_cq, notification_cq, tag); + ::grpc::Service::RequestAsyncUnary(54, context, request, response, new_call_cq, notification_cq, tag); } }; template @@ -2510,7 +2598,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithAsyncMethod_RunEventStream() { - ::grpc::Service::MarkMethodAsync(53); + ::grpc::Service::MarkMethodAsync(55); } ~WithAsyncMethod_RunEventStream() override { BaseClassMustBeDerivedFromService(this); @@ -2521,7 +2609,7 @@ class Bridge final { return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); } void RequestRunEventStream(::grpc::ServerContext* context, ::grpc::EventStreamRequest* request, ::grpc::ServerAsyncWriter< ::grpc::StreamEvent>* writer, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) { - ::grpc::Service::RequestAsyncServerStreaming(53, context, request, writer, new_call_cq, notification_cq, tag); + ::grpc::Service::RequestAsyncServerStreaming(55, context, request, writer, new_call_cq, notification_cq, tag); } }; template @@ -2530,7 +2618,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithAsyncMethod_StopEventStream() { - ::grpc::Service::MarkMethodAsync(54); + ::grpc::Service::MarkMethodAsync(56); } ~WithAsyncMethod_StopEventStream() override { BaseClassMustBeDerivedFromService(this); @@ -2541,10 +2629,10 @@ class Bridge final { return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); } void RequestStopEventStream(::grpc::ServerContext* context, ::google::protobuf::Empty* request, ::grpc::ServerAsyncResponseWriter< ::google::protobuf::Empty>* response, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) { - ::grpc::Service::RequestAsyncUnary(54, context, request, response, new_call_cq, notification_cq, tag); + ::grpc::Service::RequestAsyncUnary(56, context, request, response, new_call_cq, notification_cq, tag); } }; - typedef WithAsyncMethod_CheckTokens > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > AsyncService; + typedef WithAsyncMethod_CheckTokens > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > AsyncService; template class WithCallbackMethod_CheckTokens : public BaseClass { private: @@ -2870,18 +2958,72 @@ class Bridge final { ::grpc::CallbackServerContext* /*context*/, const ::google::protobuf::Empty* /*request*/, ::google::protobuf::BoolValue* /*response*/) { return nullptr; } }; template + class WithCallbackMethod_SetIsTelemetryDisabled : public BaseClass { + private: + void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} + public: + WithCallbackMethod_SetIsTelemetryDisabled() { + ::grpc::Service::MarkMethodCallback(12, + new ::grpc::internal::CallbackUnaryHandler< ::google::protobuf::BoolValue, ::google::protobuf::Empty>( + [this]( + ::grpc::CallbackServerContext* context, const ::google::protobuf::BoolValue* request, ::google::protobuf::Empty* response) { return this->SetIsTelemetryDisabled(context, request, response); }));} + void SetMessageAllocatorFor_SetIsTelemetryDisabled( + ::grpc::MessageAllocator< ::google::protobuf::BoolValue, ::google::protobuf::Empty>* allocator) { + ::grpc::internal::MethodHandler* const handler = ::grpc::Service::GetHandler(12); + static_cast<::grpc::internal::CallbackUnaryHandler< ::google::protobuf::BoolValue, ::google::protobuf::Empty>*>(handler) + ->SetMessageAllocator(allocator); + } + ~WithCallbackMethod_SetIsTelemetryDisabled() override { + BaseClassMustBeDerivedFromService(this); + } + // disable synchronous version of this method + ::grpc::Status SetIsTelemetryDisabled(::grpc::ServerContext* /*context*/, const ::google::protobuf::BoolValue* /*request*/, ::google::protobuf::Empty* /*response*/) override { + abort(); + return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); + } + virtual ::grpc::ServerUnaryReactor* SetIsTelemetryDisabled( + ::grpc::CallbackServerContext* /*context*/, const ::google::protobuf::BoolValue* /*request*/, ::google::protobuf::Empty* /*response*/) { return nullptr; } + }; + template + class WithCallbackMethod_IsTelemetryDisabled : public BaseClass { + private: + void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} + public: + WithCallbackMethod_IsTelemetryDisabled() { + ::grpc::Service::MarkMethodCallback(13, + new ::grpc::internal::CallbackUnaryHandler< ::google::protobuf::Empty, ::google::protobuf::BoolValue>( + [this]( + ::grpc::CallbackServerContext* context, const ::google::protobuf::Empty* request, ::google::protobuf::BoolValue* response) { return this->IsTelemetryDisabled(context, request, response); }));} + void SetMessageAllocatorFor_IsTelemetryDisabled( + ::grpc::MessageAllocator< ::google::protobuf::Empty, ::google::protobuf::BoolValue>* allocator) { + ::grpc::internal::MethodHandler* const handler = ::grpc::Service::GetHandler(13); + static_cast<::grpc::internal::CallbackUnaryHandler< ::google::protobuf::Empty, ::google::protobuf::BoolValue>*>(handler) + ->SetMessageAllocator(allocator); + } + ~WithCallbackMethod_IsTelemetryDisabled() override { + BaseClassMustBeDerivedFromService(this); + } + // disable synchronous version of this method + ::grpc::Status IsTelemetryDisabled(::grpc::ServerContext* /*context*/, const ::google::protobuf::Empty* /*request*/, ::google::protobuf::BoolValue* /*response*/) override { + abort(); + return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); + } + virtual ::grpc::ServerUnaryReactor* IsTelemetryDisabled( + ::grpc::CallbackServerContext* /*context*/, const ::google::protobuf::Empty* /*request*/, ::google::protobuf::BoolValue* /*response*/) { return nullptr; } + }; + template class WithCallbackMethod_GoOs : public BaseClass { private: void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithCallbackMethod_GoOs() { - ::grpc::Service::MarkMethodCallback(12, + ::grpc::Service::MarkMethodCallback(14, new ::grpc::internal::CallbackUnaryHandler< ::google::protobuf::Empty, ::google::protobuf::StringValue>( [this]( ::grpc::CallbackServerContext* context, const ::google::protobuf::Empty* request, ::google::protobuf::StringValue* response) { return this->GoOs(context, request, response); }));} void SetMessageAllocatorFor_GoOs( ::grpc::MessageAllocator< ::google::protobuf::Empty, ::google::protobuf::StringValue>* allocator) { - ::grpc::internal::MethodHandler* const handler = ::grpc::Service::GetHandler(12); + ::grpc::internal::MethodHandler* const handler = ::grpc::Service::GetHandler(14); static_cast<::grpc::internal::CallbackUnaryHandler< ::google::protobuf::Empty, ::google::protobuf::StringValue>*>(handler) ->SetMessageAllocator(allocator); } @@ -2902,13 +3044,13 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithCallbackMethod_TriggerReset() { - ::grpc::Service::MarkMethodCallback(13, + ::grpc::Service::MarkMethodCallback(15, new ::grpc::internal::CallbackUnaryHandler< ::google::protobuf::Empty, ::google::protobuf::Empty>( [this]( ::grpc::CallbackServerContext* context, const ::google::protobuf::Empty* request, ::google::protobuf::Empty* response) { return this->TriggerReset(context, request, response); }));} void SetMessageAllocatorFor_TriggerReset( ::grpc::MessageAllocator< ::google::protobuf::Empty, ::google::protobuf::Empty>* allocator) { - ::grpc::internal::MethodHandler* const handler = ::grpc::Service::GetHandler(13); + ::grpc::internal::MethodHandler* const handler = ::grpc::Service::GetHandler(15); static_cast<::grpc::internal::CallbackUnaryHandler< ::google::protobuf::Empty, ::google::protobuf::Empty>*>(handler) ->SetMessageAllocator(allocator); } @@ -2929,13 +3071,13 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithCallbackMethod_Version() { - ::grpc::Service::MarkMethodCallback(14, + ::grpc::Service::MarkMethodCallback(16, new ::grpc::internal::CallbackUnaryHandler< ::google::protobuf::Empty, ::google::protobuf::StringValue>( [this]( ::grpc::CallbackServerContext* context, const ::google::protobuf::Empty* request, ::google::protobuf::StringValue* response) { return this->Version(context, request, response); }));} void SetMessageAllocatorFor_Version( ::grpc::MessageAllocator< ::google::protobuf::Empty, ::google::protobuf::StringValue>* allocator) { - ::grpc::internal::MethodHandler* const handler = ::grpc::Service::GetHandler(14); + ::grpc::internal::MethodHandler* const handler = ::grpc::Service::GetHandler(16); static_cast<::grpc::internal::CallbackUnaryHandler< ::google::protobuf::Empty, ::google::protobuf::StringValue>*>(handler) ->SetMessageAllocator(allocator); } @@ -2956,13 +3098,13 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithCallbackMethod_LogsPath() { - ::grpc::Service::MarkMethodCallback(15, + ::grpc::Service::MarkMethodCallback(17, new ::grpc::internal::CallbackUnaryHandler< ::google::protobuf::Empty, ::google::protobuf::StringValue>( [this]( ::grpc::CallbackServerContext* context, const ::google::protobuf::Empty* request, ::google::protobuf::StringValue* response) { return this->LogsPath(context, request, response); }));} void SetMessageAllocatorFor_LogsPath( ::grpc::MessageAllocator< ::google::protobuf::Empty, ::google::protobuf::StringValue>* allocator) { - ::grpc::internal::MethodHandler* const handler = ::grpc::Service::GetHandler(15); + ::grpc::internal::MethodHandler* const handler = ::grpc::Service::GetHandler(17); static_cast<::grpc::internal::CallbackUnaryHandler< ::google::protobuf::Empty, ::google::protobuf::StringValue>*>(handler) ->SetMessageAllocator(allocator); } @@ -2983,13 +3125,13 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithCallbackMethod_LicensePath() { - ::grpc::Service::MarkMethodCallback(16, + ::grpc::Service::MarkMethodCallback(18, new ::grpc::internal::CallbackUnaryHandler< ::google::protobuf::Empty, ::google::protobuf::StringValue>( [this]( ::grpc::CallbackServerContext* context, const ::google::protobuf::Empty* request, ::google::protobuf::StringValue* response) { return this->LicensePath(context, request, response); }));} void SetMessageAllocatorFor_LicensePath( ::grpc::MessageAllocator< ::google::protobuf::Empty, ::google::protobuf::StringValue>* allocator) { - ::grpc::internal::MethodHandler* const handler = ::grpc::Service::GetHandler(16); + ::grpc::internal::MethodHandler* const handler = ::grpc::Service::GetHandler(18); static_cast<::grpc::internal::CallbackUnaryHandler< ::google::protobuf::Empty, ::google::protobuf::StringValue>*>(handler) ->SetMessageAllocator(allocator); } @@ -3010,13 +3152,13 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithCallbackMethod_ReleaseNotesPageLink() { - ::grpc::Service::MarkMethodCallback(17, + ::grpc::Service::MarkMethodCallback(19, new ::grpc::internal::CallbackUnaryHandler< ::google::protobuf::Empty, ::google::protobuf::StringValue>( [this]( ::grpc::CallbackServerContext* context, const ::google::protobuf::Empty* request, ::google::protobuf::StringValue* response) { return this->ReleaseNotesPageLink(context, request, response); }));} void SetMessageAllocatorFor_ReleaseNotesPageLink( ::grpc::MessageAllocator< ::google::protobuf::Empty, ::google::protobuf::StringValue>* allocator) { - ::grpc::internal::MethodHandler* const handler = ::grpc::Service::GetHandler(17); + ::grpc::internal::MethodHandler* const handler = ::grpc::Service::GetHandler(19); static_cast<::grpc::internal::CallbackUnaryHandler< ::google::protobuf::Empty, ::google::protobuf::StringValue>*>(handler) ->SetMessageAllocator(allocator); } @@ -3037,13 +3179,13 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithCallbackMethod_DependencyLicensesLink() { - ::grpc::Service::MarkMethodCallback(18, + ::grpc::Service::MarkMethodCallback(20, new ::grpc::internal::CallbackUnaryHandler< ::google::protobuf::Empty, ::google::protobuf::StringValue>( [this]( ::grpc::CallbackServerContext* context, const ::google::protobuf::Empty* request, ::google::protobuf::StringValue* response) { return this->DependencyLicensesLink(context, request, response); }));} void SetMessageAllocatorFor_DependencyLicensesLink( ::grpc::MessageAllocator< ::google::protobuf::Empty, ::google::protobuf::StringValue>* allocator) { - ::grpc::internal::MethodHandler* const handler = ::grpc::Service::GetHandler(18); + ::grpc::internal::MethodHandler* const handler = ::grpc::Service::GetHandler(20); static_cast<::grpc::internal::CallbackUnaryHandler< ::google::protobuf::Empty, ::google::protobuf::StringValue>*>(handler) ->SetMessageAllocator(allocator); } @@ -3064,13 +3206,13 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithCallbackMethod_LandingPageLink() { - ::grpc::Service::MarkMethodCallback(19, + ::grpc::Service::MarkMethodCallback(21, new ::grpc::internal::CallbackUnaryHandler< ::google::protobuf::Empty, ::google::protobuf::StringValue>( [this]( ::grpc::CallbackServerContext* context, const ::google::protobuf::Empty* request, ::google::protobuf::StringValue* response) { return this->LandingPageLink(context, request, response); }));} void SetMessageAllocatorFor_LandingPageLink( ::grpc::MessageAllocator< ::google::protobuf::Empty, ::google::protobuf::StringValue>* allocator) { - ::grpc::internal::MethodHandler* const handler = ::grpc::Service::GetHandler(19); + ::grpc::internal::MethodHandler* const handler = ::grpc::Service::GetHandler(21); static_cast<::grpc::internal::CallbackUnaryHandler< ::google::protobuf::Empty, ::google::protobuf::StringValue>*>(handler) ->SetMessageAllocator(allocator); } @@ -3091,13 +3233,13 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithCallbackMethod_SetColorSchemeName() { - ::grpc::Service::MarkMethodCallback(20, + ::grpc::Service::MarkMethodCallback(22, new ::grpc::internal::CallbackUnaryHandler< ::google::protobuf::StringValue, ::google::protobuf::Empty>( [this]( ::grpc::CallbackServerContext* context, const ::google::protobuf::StringValue* request, ::google::protobuf::Empty* response) { return this->SetColorSchemeName(context, request, response); }));} void SetMessageAllocatorFor_SetColorSchemeName( ::grpc::MessageAllocator< ::google::protobuf::StringValue, ::google::protobuf::Empty>* allocator) { - ::grpc::internal::MethodHandler* const handler = ::grpc::Service::GetHandler(20); + ::grpc::internal::MethodHandler* const handler = ::grpc::Service::GetHandler(22); static_cast<::grpc::internal::CallbackUnaryHandler< ::google::protobuf::StringValue, ::google::protobuf::Empty>*>(handler) ->SetMessageAllocator(allocator); } @@ -3118,13 +3260,13 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithCallbackMethod_ColorSchemeName() { - ::grpc::Service::MarkMethodCallback(21, + ::grpc::Service::MarkMethodCallback(23, new ::grpc::internal::CallbackUnaryHandler< ::google::protobuf::Empty, ::google::protobuf::StringValue>( [this]( ::grpc::CallbackServerContext* context, const ::google::protobuf::Empty* request, ::google::protobuf::StringValue* response) { return this->ColorSchemeName(context, request, response); }));} void SetMessageAllocatorFor_ColorSchemeName( ::grpc::MessageAllocator< ::google::protobuf::Empty, ::google::protobuf::StringValue>* allocator) { - ::grpc::internal::MethodHandler* const handler = ::grpc::Service::GetHandler(21); + ::grpc::internal::MethodHandler* const handler = ::grpc::Service::GetHandler(23); static_cast<::grpc::internal::CallbackUnaryHandler< ::google::protobuf::Empty, ::google::protobuf::StringValue>*>(handler) ->SetMessageAllocator(allocator); } @@ -3145,13 +3287,13 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithCallbackMethod_CurrentEmailClient() { - ::grpc::Service::MarkMethodCallback(22, + ::grpc::Service::MarkMethodCallback(24, new ::grpc::internal::CallbackUnaryHandler< ::google::protobuf::Empty, ::google::protobuf::StringValue>( [this]( ::grpc::CallbackServerContext* context, const ::google::protobuf::Empty* request, ::google::protobuf::StringValue* response) { return this->CurrentEmailClient(context, request, response); }));} void SetMessageAllocatorFor_CurrentEmailClient( ::grpc::MessageAllocator< ::google::protobuf::Empty, ::google::protobuf::StringValue>* allocator) { - ::grpc::internal::MethodHandler* const handler = ::grpc::Service::GetHandler(22); + ::grpc::internal::MethodHandler* const handler = ::grpc::Service::GetHandler(24); static_cast<::grpc::internal::CallbackUnaryHandler< ::google::protobuf::Empty, ::google::protobuf::StringValue>*>(handler) ->SetMessageAllocator(allocator); } @@ -3172,13 +3314,13 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithCallbackMethod_ReportBug() { - ::grpc::Service::MarkMethodCallback(23, + ::grpc::Service::MarkMethodCallback(25, new ::grpc::internal::CallbackUnaryHandler< ::grpc::ReportBugRequest, ::google::protobuf::Empty>( [this]( ::grpc::CallbackServerContext* context, const ::grpc::ReportBugRequest* request, ::google::protobuf::Empty* response) { return this->ReportBug(context, request, response); }));} void SetMessageAllocatorFor_ReportBug( ::grpc::MessageAllocator< ::grpc::ReportBugRequest, ::google::protobuf::Empty>* allocator) { - ::grpc::internal::MethodHandler* const handler = ::grpc::Service::GetHandler(23); + ::grpc::internal::MethodHandler* const handler = ::grpc::Service::GetHandler(25); static_cast<::grpc::internal::CallbackUnaryHandler< ::grpc::ReportBugRequest, ::google::protobuf::Empty>*>(handler) ->SetMessageAllocator(allocator); } @@ -3199,13 +3341,13 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithCallbackMethod_ExportTLSCertificates() { - ::grpc::Service::MarkMethodCallback(24, + ::grpc::Service::MarkMethodCallback(26, new ::grpc::internal::CallbackUnaryHandler< ::google::protobuf::StringValue, ::google::protobuf::Empty>( [this]( ::grpc::CallbackServerContext* context, const ::google::protobuf::StringValue* request, ::google::protobuf::Empty* response) { return this->ExportTLSCertificates(context, request, response); }));} void SetMessageAllocatorFor_ExportTLSCertificates( ::grpc::MessageAllocator< ::google::protobuf::StringValue, ::google::protobuf::Empty>* allocator) { - ::grpc::internal::MethodHandler* const handler = ::grpc::Service::GetHandler(24); + ::grpc::internal::MethodHandler* const handler = ::grpc::Service::GetHandler(26); static_cast<::grpc::internal::CallbackUnaryHandler< ::google::protobuf::StringValue, ::google::protobuf::Empty>*>(handler) ->SetMessageAllocator(allocator); } @@ -3226,13 +3368,13 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithCallbackMethod_ForceLauncher() { - ::grpc::Service::MarkMethodCallback(25, + ::grpc::Service::MarkMethodCallback(27, new ::grpc::internal::CallbackUnaryHandler< ::google::protobuf::StringValue, ::google::protobuf::Empty>( [this]( ::grpc::CallbackServerContext* context, const ::google::protobuf::StringValue* request, ::google::protobuf::Empty* response) { return this->ForceLauncher(context, request, response); }));} void SetMessageAllocatorFor_ForceLauncher( ::grpc::MessageAllocator< ::google::protobuf::StringValue, ::google::protobuf::Empty>* allocator) { - ::grpc::internal::MethodHandler* const handler = ::grpc::Service::GetHandler(25); + ::grpc::internal::MethodHandler* const handler = ::grpc::Service::GetHandler(27); static_cast<::grpc::internal::CallbackUnaryHandler< ::google::protobuf::StringValue, ::google::protobuf::Empty>*>(handler) ->SetMessageAllocator(allocator); } @@ -3253,13 +3395,13 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithCallbackMethod_SetMainExecutable() { - ::grpc::Service::MarkMethodCallback(26, + ::grpc::Service::MarkMethodCallback(28, new ::grpc::internal::CallbackUnaryHandler< ::google::protobuf::StringValue, ::google::protobuf::Empty>( [this]( ::grpc::CallbackServerContext* context, const ::google::protobuf::StringValue* request, ::google::protobuf::Empty* response) { return this->SetMainExecutable(context, request, response); }));} void SetMessageAllocatorFor_SetMainExecutable( ::grpc::MessageAllocator< ::google::protobuf::StringValue, ::google::protobuf::Empty>* allocator) { - ::grpc::internal::MethodHandler* const handler = ::grpc::Service::GetHandler(26); + ::grpc::internal::MethodHandler* const handler = ::grpc::Service::GetHandler(28); static_cast<::grpc::internal::CallbackUnaryHandler< ::google::protobuf::StringValue, ::google::protobuf::Empty>*>(handler) ->SetMessageAllocator(allocator); } @@ -3280,13 +3422,13 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithCallbackMethod_Login() { - ::grpc::Service::MarkMethodCallback(27, + ::grpc::Service::MarkMethodCallback(29, new ::grpc::internal::CallbackUnaryHandler< ::grpc::LoginRequest, ::google::protobuf::Empty>( [this]( ::grpc::CallbackServerContext* context, const ::grpc::LoginRequest* request, ::google::protobuf::Empty* response) { return this->Login(context, request, response); }));} void SetMessageAllocatorFor_Login( ::grpc::MessageAllocator< ::grpc::LoginRequest, ::google::protobuf::Empty>* allocator) { - ::grpc::internal::MethodHandler* const handler = ::grpc::Service::GetHandler(27); + ::grpc::internal::MethodHandler* const handler = ::grpc::Service::GetHandler(29); static_cast<::grpc::internal::CallbackUnaryHandler< ::grpc::LoginRequest, ::google::protobuf::Empty>*>(handler) ->SetMessageAllocator(allocator); } @@ -3307,13 +3449,13 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithCallbackMethod_Login2FA() { - ::grpc::Service::MarkMethodCallback(28, + ::grpc::Service::MarkMethodCallback(30, new ::grpc::internal::CallbackUnaryHandler< ::grpc::LoginRequest, ::google::protobuf::Empty>( [this]( ::grpc::CallbackServerContext* context, const ::grpc::LoginRequest* request, ::google::protobuf::Empty* response) { return this->Login2FA(context, request, response); }));} void SetMessageAllocatorFor_Login2FA( ::grpc::MessageAllocator< ::grpc::LoginRequest, ::google::protobuf::Empty>* allocator) { - ::grpc::internal::MethodHandler* const handler = ::grpc::Service::GetHandler(28); + ::grpc::internal::MethodHandler* const handler = ::grpc::Service::GetHandler(30); static_cast<::grpc::internal::CallbackUnaryHandler< ::grpc::LoginRequest, ::google::protobuf::Empty>*>(handler) ->SetMessageAllocator(allocator); } @@ -3334,13 +3476,13 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithCallbackMethod_Login2Passwords() { - ::grpc::Service::MarkMethodCallback(29, + ::grpc::Service::MarkMethodCallback(31, new ::grpc::internal::CallbackUnaryHandler< ::grpc::LoginRequest, ::google::protobuf::Empty>( [this]( ::grpc::CallbackServerContext* context, const ::grpc::LoginRequest* request, ::google::protobuf::Empty* response) { return this->Login2Passwords(context, request, response); }));} void SetMessageAllocatorFor_Login2Passwords( ::grpc::MessageAllocator< ::grpc::LoginRequest, ::google::protobuf::Empty>* allocator) { - ::grpc::internal::MethodHandler* const handler = ::grpc::Service::GetHandler(29); + ::grpc::internal::MethodHandler* const handler = ::grpc::Service::GetHandler(31); static_cast<::grpc::internal::CallbackUnaryHandler< ::grpc::LoginRequest, ::google::protobuf::Empty>*>(handler) ->SetMessageAllocator(allocator); } @@ -3361,13 +3503,13 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithCallbackMethod_LoginAbort() { - ::grpc::Service::MarkMethodCallback(30, + ::grpc::Service::MarkMethodCallback(32, new ::grpc::internal::CallbackUnaryHandler< ::grpc::LoginAbortRequest, ::google::protobuf::Empty>( [this]( ::grpc::CallbackServerContext* context, const ::grpc::LoginAbortRequest* request, ::google::protobuf::Empty* response) { return this->LoginAbort(context, request, response); }));} void SetMessageAllocatorFor_LoginAbort( ::grpc::MessageAllocator< ::grpc::LoginAbortRequest, ::google::protobuf::Empty>* allocator) { - ::grpc::internal::MethodHandler* const handler = ::grpc::Service::GetHandler(30); + ::grpc::internal::MethodHandler* const handler = ::grpc::Service::GetHandler(32); static_cast<::grpc::internal::CallbackUnaryHandler< ::grpc::LoginAbortRequest, ::google::protobuf::Empty>*>(handler) ->SetMessageAllocator(allocator); } @@ -3388,13 +3530,13 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithCallbackMethod_CheckUpdate() { - ::grpc::Service::MarkMethodCallback(31, + ::grpc::Service::MarkMethodCallback(33, new ::grpc::internal::CallbackUnaryHandler< ::google::protobuf::Empty, ::google::protobuf::Empty>( [this]( ::grpc::CallbackServerContext* context, const ::google::protobuf::Empty* request, ::google::protobuf::Empty* response) { return this->CheckUpdate(context, request, response); }));} void SetMessageAllocatorFor_CheckUpdate( ::grpc::MessageAllocator< ::google::protobuf::Empty, ::google::protobuf::Empty>* allocator) { - ::grpc::internal::MethodHandler* const handler = ::grpc::Service::GetHandler(31); + ::grpc::internal::MethodHandler* const handler = ::grpc::Service::GetHandler(33); static_cast<::grpc::internal::CallbackUnaryHandler< ::google::protobuf::Empty, ::google::protobuf::Empty>*>(handler) ->SetMessageAllocator(allocator); } @@ -3415,13 +3557,13 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithCallbackMethod_InstallUpdate() { - ::grpc::Service::MarkMethodCallback(32, + ::grpc::Service::MarkMethodCallback(34, new ::grpc::internal::CallbackUnaryHandler< ::google::protobuf::Empty, ::google::protobuf::Empty>( [this]( ::grpc::CallbackServerContext* context, const ::google::protobuf::Empty* request, ::google::protobuf::Empty* response) { return this->InstallUpdate(context, request, response); }));} void SetMessageAllocatorFor_InstallUpdate( ::grpc::MessageAllocator< ::google::protobuf::Empty, ::google::protobuf::Empty>* allocator) { - ::grpc::internal::MethodHandler* const handler = ::grpc::Service::GetHandler(32); + ::grpc::internal::MethodHandler* const handler = ::grpc::Service::GetHandler(34); static_cast<::grpc::internal::CallbackUnaryHandler< ::google::protobuf::Empty, ::google::protobuf::Empty>*>(handler) ->SetMessageAllocator(allocator); } @@ -3442,13 +3584,13 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithCallbackMethod_SetIsAutomaticUpdateOn() { - ::grpc::Service::MarkMethodCallback(33, + ::grpc::Service::MarkMethodCallback(35, new ::grpc::internal::CallbackUnaryHandler< ::google::protobuf::BoolValue, ::google::protobuf::Empty>( [this]( ::grpc::CallbackServerContext* context, const ::google::protobuf::BoolValue* request, ::google::protobuf::Empty* response) { return this->SetIsAutomaticUpdateOn(context, request, response); }));} void SetMessageAllocatorFor_SetIsAutomaticUpdateOn( ::grpc::MessageAllocator< ::google::protobuf::BoolValue, ::google::protobuf::Empty>* allocator) { - ::grpc::internal::MethodHandler* const handler = ::grpc::Service::GetHandler(33); + ::grpc::internal::MethodHandler* const handler = ::grpc::Service::GetHandler(35); static_cast<::grpc::internal::CallbackUnaryHandler< ::google::protobuf::BoolValue, ::google::protobuf::Empty>*>(handler) ->SetMessageAllocator(allocator); } @@ -3469,13 +3611,13 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithCallbackMethod_IsAutomaticUpdateOn() { - ::grpc::Service::MarkMethodCallback(34, + ::grpc::Service::MarkMethodCallback(36, new ::grpc::internal::CallbackUnaryHandler< ::google::protobuf::Empty, ::google::protobuf::BoolValue>( [this]( ::grpc::CallbackServerContext* context, const ::google::protobuf::Empty* request, ::google::protobuf::BoolValue* response) { return this->IsAutomaticUpdateOn(context, request, response); }));} void SetMessageAllocatorFor_IsAutomaticUpdateOn( ::grpc::MessageAllocator< ::google::protobuf::Empty, ::google::protobuf::BoolValue>* allocator) { - ::grpc::internal::MethodHandler* const handler = ::grpc::Service::GetHandler(34); + ::grpc::internal::MethodHandler* const handler = ::grpc::Service::GetHandler(36); static_cast<::grpc::internal::CallbackUnaryHandler< ::google::protobuf::Empty, ::google::protobuf::BoolValue>*>(handler) ->SetMessageAllocator(allocator); } @@ -3496,13 +3638,13 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithCallbackMethod_DiskCachePath() { - ::grpc::Service::MarkMethodCallback(35, + ::grpc::Service::MarkMethodCallback(37, new ::grpc::internal::CallbackUnaryHandler< ::google::protobuf::Empty, ::google::protobuf::StringValue>( [this]( ::grpc::CallbackServerContext* context, const ::google::protobuf::Empty* request, ::google::protobuf::StringValue* response) { return this->DiskCachePath(context, request, response); }));} void SetMessageAllocatorFor_DiskCachePath( ::grpc::MessageAllocator< ::google::protobuf::Empty, ::google::protobuf::StringValue>* allocator) { - ::grpc::internal::MethodHandler* const handler = ::grpc::Service::GetHandler(35); + ::grpc::internal::MethodHandler* const handler = ::grpc::Service::GetHandler(37); static_cast<::grpc::internal::CallbackUnaryHandler< ::google::protobuf::Empty, ::google::protobuf::StringValue>*>(handler) ->SetMessageAllocator(allocator); } @@ -3523,13 +3665,13 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithCallbackMethod_SetDiskCachePath() { - ::grpc::Service::MarkMethodCallback(36, + ::grpc::Service::MarkMethodCallback(38, new ::grpc::internal::CallbackUnaryHandler< ::google::protobuf::StringValue, ::google::protobuf::Empty>( [this]( ::grpc::CallbackServerContext* context, const ::google::protobuf::StringValue* request, ::google::protobuf::Empty* response) { return this->SetDiskCachePath(context, request, response); }));} void SetMessageAllocatorFor_SetDiskCachePath( ::grpc::MessageAllocator< ::google::protobuf::StringValue, ::google::protobuf::Empty>* allocator) { - ::grpc::internal::MethodHandler* const handler = ::grpc::Service::GetHandler(36); + ::grpc::internal::MethodHandler* const handler = ::grpc::Service::GetHandler(38); static_cast<::grpc::internal::CallbackUnaryHandler< ::google::protobuf::StringValue, ::google::protobuf::Empty>*>(handler) ->SetMessageAllocator(allocator); } @@ -3550,13 +3692,13 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithCallbackMethod_SetIsDoHEnabled() { - ::grpc::Service::MarkMethodCallback(37, + ::grpc::Service::MarkMethodCallback(39, new ::grpc::internal::CallbackUnaryHandler< ::google::protobuf::BoolValue, ::google::protobuf::Empty>( [this]( ::grpc::CallbackServerContext* context, const ::google::protobuf::BoolValue* request, ::google::protobuf::Empty* response) { return this->SetIsDoHEnabled(context, request, response); }));} void SetMessageAllocatorFor_SetIsDoHEnabled( ::grpc::MessageAllocator< ::google::protobuf::BoolValue, ::google::protobuf::Empty>* allocator) { - ::grpc::internal::MethodHandler* const handler = ::grpc::Service::GetHandler(37); + ::grpc::internal::MethodHandler* const handler = ::grpc::Service::GetHandler(39); static_cast<::grpc::internal::CallbackUnaryHandler< ::google::protobuf::BoolValue, ::google::protobuf::Empty>*>(handler) ->SetMessageAllocator(allocator); } @@ -3577,13 +3719,13 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithCallbackMethod_IsDoHEnabled() { - ::grpc::Service::MarkMethodCallback(38, + ::grpc::Service::MarkMethodCallback(40, new ::grpc::internal::CallbackUnaryHandler< ::google::protobuf::Empty, ::google::protobuf::BoolValue>( [this]( ::grpc::CallbackServerContext* context, const ::google::protobuf::Empty* request, ::google::protobuf::BoolValue* response) { return this->IsDoHEnabled(context, request, response); }));} void SetMessageAllocatorFor_IsDoHEnabled( ::grpc::MessageAllocator< ::google::protobuf::Empty, ::google::protobuf::BoolValue>* allocator) { - ::grpc::internal::MethodHandler* const handler = ::grpc::Service::GetHandler(38); + ::grpc::internal::MethodHandler* const handler = ::grpc::Service::GetHandler(40); static_cast<::grpc::internal::CallbackUnaryHandler< ::google::protobuf::Empty, ::google::protobuf::BoolValue>*>(handler) ->SetMessageAllocator(allocator); } @@ -3604,13 +3746,13 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithCallbackMethod_MailServerSettings() { - ::grpc::Service::MarkMethodCallback(39, + ::grpc::Service::MarkMethodCallback(41, new ::grpc::internal::CallbackUnaryHandler< ::google::protobuf::Empty, ::grpc::ImapSmtpSettings>( [this]( ::grpc::CallbackServerContext* context, const ::google::protobuf::Empty* request, ::grpc::ImapSmtpSettings* response) { return this->MailServerSettings(context, request, response); }));} void SetMessageAllocatorFor_MailServerSettings( ::grpc::MessageAllocator< ::google::protobuf::Empty, ::grpc::ImapSmtpSettings>* allocator) { - ::grpc::internal::MethodHandler* const handler = ::grpc::Service::GetHandler(39); + ::grpc::internal::MethodHandler* const handler = ::grpc::Service::GetHandler(41); static_cast<::grpc::internal::CallbackUnaryHandler< ::google::protobuf::Empty, ::grpc::ImapSmtpSettings>*>(handler) ->SetMessageAllocator(allocator); } @@ -3631,13 +3773,13 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithCallbackMethod_SetMailServerSettings() { - ::grpc::Service::MarkMethodCallback(40, + ::grpc::Service::MarkMethodCallback(42, new ::grpc::internal::CallbackUnaryHandler< ::grpc::ImapSmtpSettings, ::google::protobuf::Empty>( [this]( ::grpc::CallbackServerContext* context, const ::grpc::ImapSmtpSettings* request, ::google::protobuf::Empty* response) { return this->SetMailServerSettings(context, request, response); }));} void SetMessageAllocatorFor_SetMailServerSettings( ::grpc::MessageAllocator< ::grpc::ImapSmtpSettings, ::google::protobuf::Empty>* allocator) { - ::grpc::internal::MethodHandler* const handler = ::grpc::Service::GetHandler(40); + ::grpc::internal::MethodHandler* const handler = ::grpc::Service::GetHandler(42); static_cast<::grpc::internal::CallbackUnaryHandler< ::grpc::ImapSmtpSettings, ::google::protobuf::Empty>*>(handler) ->SetMessageAllocator(allocator); } @@ -3658,13 +3800,13 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithCallbackMethod_Hostname() { - ::grpc::Service::MarkMethodCallback(41, + ::grpc::Service::MarkMethodCallback(43, new ::grpc::internal::CallbackUnaryHandler< ::google::protobuf::Empty, ::google::protobuf::StringValue>( [this]( ::grpc::CallbackServerContext* context, const ::google::protobuf::Empty* request, ::google::protobuf::StringValue* response) { return this->Hostname(context, request, response); }));} void SetMessageAllocatorFor_Hostname( ::grpc::MessageAllocator< ::google::protobuf::Empty, ::google::protobuf::StringValue>* allocator) { - ::grpc::internal::MethodHandler* const handler = ::grpc::Service::GetHandler(41); + ::grpc::internal::MethodHandler* const handler = ::grpc::Service::GetHandler(43); static_cast<::grpc::internal::CallbackUnaryHandler< ::google::protobuf::Empty, ::google::protobuf::StringValue>*>(handler) ->SetMessageAllocator(allocator); } @@ -3685,13 +3827,13 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithCallbackMethod_IsPortFree() { - ::grpc::Service::MarkMethodCallback(42, + ::grpc::Service::MarkMethodCallback(44, new ::grpc::internal::CallbackUnaryHandler< ::google::protobuf::Int32Value, ::google::protobuf::BoolValue>( [this]( ::grpc::CallbackServerContext* context, const ::google::protobuf::Int32Value* request, ::google::protobuf::BoolValue* response) { return this->IsPortFree(context, request, response); }));} void SetMessageAllocatorFor_IsPortFree( ::grpc::MessageAllocator< ::google::protobuf::Int32Value, ::google::protobuf::BoolValue>* allocator) { - ::grpc::internal::MethodHandler* const handler = ::grpc::Service::GetHandler(42); + ::grpc::internal::MethodHandler* const handler = ::grpc::Service::GetHandler(44); static_cast<::grpc::internal::CallbackUnaryHandler< ::google::protobuf::Int32Value, ::google::protobuf::BoolValue>*>(handler) ->SetMessageAllocator(allocator); } @@ -3712,13 +3854,13 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithCallbackMethod_AvailableKeychains() { - ::grpc::Service::MarkMethodCallback(43, + ::grpc::Service::MarkMethodCallback(45, new ::grpc::internal::CallbackUnaryHandler< ::google::protobuf::Empty, ::grpc::AvailableKeychainsResponse>( [this]( ::grpc::CallbackServerContext* context, const ::google::protobuf::Empty* request, ::grpc::AvailableKeychainsResponse* response) { return this->AvailableKeychains(context, request, response); }));} void SetMessageAllocatorFor_AvailableKeychains( ::grpc::MessageAllocator< ::google::protobuf::Empty, ::grpc::AvailableKeychainsResponse>* allocator) { - ::grpc::internal::MethodHandler* const handler = ::grpc::Service::GetHandler(43); + ::grpc::internal::MethodHandler* const handler = ::grpc::Service::GetHandler(45); static_cast<::grpc::internal::CallbackUnaryHandler< ::google::protobuf::Empty, ::grpc::AvailableKeychainsResponse>*>(handler) ->SetMessageAllocator(allocator); } @@ -3739,13 +3881,13 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithCallbackMethod_SetCurrentKeychain() { - ::grpc::Service::MarkMethodCallback(44, + ::grpc::Service::MarkMethodCallback(46, new ::grpc::internal::CallbackUnaryHandler< ::google::protobuf::StringValue, ::google::protobuf::Empty>( [this]( ::grpc::CallbackServerContext* context, const ::google::protobuf::StringValue* request, ::google::protobuf::Empty* response) { return this->SetCurrentKeychain(context, request, response); }));} void SetMessageAllocatorFor_SetCurrentKeychain( ::grpc::MessageAllocator< ::google::protobuf::StringValue, ::google::protobuf::Empty>* allocator) { - ::grpc::internal::MethodHandler* const handler = ::grpc::Service::GetHandler(44); + ::grpc::internal::MethodHandler* const handler = ::grpc::Service::GetHandler(46); static_cast<::grpc::internal::CallbackUnaryHandler< ::google::protobuf::StringValue, ::google::protobuf::Empty>*>(handler) ->SetMessageAllocator(allocator); } @@ -3766,13 +3908,13 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithCallbackMethod_CurrentKeychain() { - ::grpc::Service::MarkMethodCallback(45, + ::grpc::Service::MarkMethodCallback(47, new ::grpc::internal::CallbackUnaryHandler< ::google::protobuf::Empty, ::google::protobuf::StringValue>( [this]( ::grpc::CallbackServerContext* context, const ::google::protobuf::Empty* request, ::google::protobuf::StringValue* response) { return this->CurrentKeychain(context, request, response); }));} void SetMessageAllocatorFor_CurrentKeychain( ::grpc::MessageAllocator< ::google::protobuf::Empty, ::google::protobuf::StringValue>* allocator) { - ::grpc::internal::MethodHandler* const handler = ::grpc::Service::GetHandler(45); + ::grpc::internal::MethodHandler* const handler = ::grpc::Service::GetHandler(47); static_cast<::grpc::internal::CallbackUnaryHandler< ::google::protobuf::Empty, ::google::protobuf::StringValue>*>(handler) ->SetMessageAllocator(allocator); } @@ -3793,13 +3935,13 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithCallbackMethod_GetUserList() { - ::grpc::Service::MarkMethodCallback(46, + ::grpc::Service::MarkMethodCallback(48, new ::grpc::internal::CallbackUnaryHandler< ::google::protobuf::Empty, ::grpc::UserListResponse>( [this]( ::grpc::CallbackServerContext* context, const ::google::protobuf::Empty* request, ::grpc::UserListResponse* response) { return this->GetUserList(context, request, response); }));} void SetMessageAllocatorFor_GetUserList( ::grpc::MessageAllocator< ::google::protobuf::Empty, ::grpc::UserListResponse>* allocator) { - ::grpc::internal::MethodHandler* const handler = ::grpc::Service::GetHandler(46); + ::grpc::internal::MethodHandler* const handler = ::grpc::Service::GetHandler(48); static_cast<::grpc::internal::CallbackUnaryHandler< ::google::protobuf::Empty, ::grpc::UserListResponse>*>(handler) ->SetMessageAllocator(allocator); } @@ -3820,13 +3962,13 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithCallbackMethod_GetUser() { - ::grpc::Service::MarkMethodCallback(47, + ::grpc::Service::MarkMethodCallback(49, new ::grpc::internal::CallbackUnaryHandler< ::google::protobuf::StringValue, ::grpc::User>( [this]( ::grpc::CallbackServerContext* context, const ::google::protobuf::StringValue* request, ::grpc::User* response) { return this->GetUser(context, request, response); }));} void SetMessageAllocatorFor_GetUser( ::grpc::MessageAllocator< ::google::protobuf::StringValue, ::grpc::User>* allocator) { - ::grpc::internal::MethodHandler* const handler = ::grpc::Service::GetHandler(47); + ::grpc::internal::MethodHandler* const handler = ::grpc::Service::GetHandler(49); static_cast<::grpc::internal::CallbackUnaryHandler< ::google::protobuf::StringValue, ::grpc::User>*>(handler) ->SetMessageAllocator(allocator); } @@ -3847,13 +3989,13 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithCallbackMethod_SetUserSplitMode() { - ::grpc::Service::MarkMethodCallback(48, + ::grpc::Service::MarkMethodCallback(50, new ::grpc::internal::CallbackUnaryHandler< ::grpc::UserSplitModeRequest, ::google::protobuf::Empty>( [this]( ::grpc::CallbackServerContext* context, const ::grpc::UserSplitModeRequest* request, ::google::protobuf::Empty* response) { return this->SetUserSplitMode(context, request, response); }));} void SetMessageAllocatorFor_SetUserSplitMode( ::grpc::MessageAllocator< ::grpc::UserSplitModeRequest, ::google::protobuf::Empty>* allocator) { - ::grpc::internal::MethodHandler* const handler = ::grpc::Service::GetHandler(48); + ::grpc::internal::MethodHandler* const handler = ::grpc::Service::GetHandler(50); static_cast<::grpc::internal::CallbackUnaryHandler< ::grpc::UserSplitModeRequest, ::google::protobuf::Empty>*>(handler) ->SetMessageAllocator(allocator); } @@ -3874,13 +4016,13 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithCallbackMethod_SendBadEventUserFeedback() { - ::grpc::Service::MarkMethodCallback(49, + ::grpc::Service::MarkMethodCallback(51, new ::grpc::internal::CallbackUnaryHandler< ::grpc::UserBadEventFeedbackRequest, ::google::protobuf::Empty>( [this]( ::grpc::CallbackServerContext* context, const ::grpc::UserBadEventFeedbackRequest* request, ::google::protobuf::Empty* response) { return this->SendBadEventUserFeedback(context, request, response); }));} void SetMessageAllocatorFor_SendBadEventUserFeedback( ::grpc::MessageAllocator< ::grpc::UserBadEventFeedbackRequest, ::google::protobuf::Empty>* allocator) { - ::grpc::internal::MethodHandler* const handler = ::grpc::Service::GetHandler(49); + ::grpc::internal::MethodHandler* const handler = ::grpc::Service::GetHandler(51); static_cast<::grpc::internal::CallbackUnaryHandler< ::grpc::UserBadEventFeedbackRequest, ::google::protobuf::Empty>*>(handler) ->SetMessageAllocator(allocator); } @@ -3901,13 +4043,13 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithCallbackMethod_LogoutUser() { - ::grpc::Service::MarkMethodCallback(50, + ::grpc::Service::MarkMethodCallback(52, new ::grpc::internal::CallbackUnaryHandler< ::google::protobuf::StringValue, ::google::protobuf::Empty>( [this]( ::grpc::CallbackServerContext* context, const ::google::protobuf::StringValue* request, ::google::protobuf::Empty* response) { return this->LogoutUser(context, request, response); }));} void SetMessageAllocatorFor_LogoutUser( ::grpc::MessageAllocator< ::google::protobuf::StringValue, ::google::protobuf::Empty>* allocator) { - ::grpc::internal::MethodHandler* const handler = ::grpc::Service::GetHandler(50); + ::grpc::internal::MethodHandler* const handler = ::grpc::Service::GetHandler(52); static_cast<::grpc::internal::CallbackUnaryHandler< ::google::protobuf::StringValue, ::google::protobuf::Empty>*>(handler) ->SetMessageAllocator(allocator); } @@ -3928,13 +4070,13 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithCallbackMethod_RemoveUser() { - ::grpc::Service::MarkMethodCallback(51, + ::grpc::Service::MarkMethodCallback(53, new ::grpc::internal::CallbackUnaryHandler< ::google::protobuf::StringValue, ::google::protobuf::Empty>( [this]( ::grpc::CallbackServerContext* context, const ::google::protobuf::StringValue* request, ::google::protobuf::Empty* response) { return this->RemoveUser(context, request, response); }));} void SetMessageAllocatorFor_RemoveUser( ::grpc::MessageAllocator< ::google::protobuf::StringValue, ::google::protobuf::Empty>* allocator) { - ::grpc::internal::MethodHandler* const handler = ::grpc::Service::GetHandler(51); + ::grpc::internal::MethodHandler* const handler = ::grpc::Service::GetHandler(53); static_cast<::grpc::internal::CallbackUnaryHandler< ::google::protobuf::StringValue, ::google::protobuf::Empty>*>(handler) ->SetMessageAllocator(allocator); } @@ -3955,13 +4097,13 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithCallbackMethod_ConfigureUserAppleMail() { - ::grpc::Service::MarkMethodCallback(52, + ::grpc::Service::MarkMethodCallback(54, new ::grpc::internal::CallbackUnaryHandler< ::grpc::ConfigureAppleMailRequest, ::google::protobuf::Empty>( [this]( ::grpc::CallbackServerContext* context, const ::grpc::ConfigureAppleMailRequest* request, ::google::protobuf::Empty* response) { return this->ConfigureUserAppleMail(context, request, response); }));} void SetMessageAllocatorFor_ConfigureUserAppleMail( ::grpc::MessageAllocator< ::grpc::ConfigureAppleMailRequest, ::google::protobuf::Empty>* allocator) { - ::grpc::internal::MethodHandler* const handler = ::grpc::Service::GetHandler(52); + ::grpc::internal::MethodHandler* const handler = ::grpc::Service::GetHandler(54); static_cast<::grpc::internal::CallbackUnaryHandler< ::grpc::ConfigureAppleMailRequest, ::google::protobuf::Empty>*>(handler) ->SetMessageAllocator(allocator); } @@ -3982,7 +4124,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithCallbackMethod_RunEventStream() { - ::grpc::Service::MarkMethodCallback(53, + ::grpc::Service::MarkMethodCallback(55, new ::grpc::internal::CallbackServerStreamingHandler< ::grpc::EventStreamRequest, ::grpc::StreamEvent>( [this]( ::grpc::CallbackServerContext* context, const ::grpc::EventStreamRequest* request) { return this->RunEventStream(context, request); })); @@ -4004,13 +4146,13 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithCallbackMethod_StopEventStream() { - ::grpc::Service::MarkMethodCallback(54, + ::grpc::Service::MarkMethodCallback(56, new ::grpc::internal::CallbackUnaryHandler< ::google::protobuf::Empty, ::google::protobuf::Empty>( [this]( ::grpc::CallbackServerContext* context, const ::google::protobuf::Empty* request, ::google::protobuf::Empty* response) { return this->StopEventStream(context, request, response); }));} void SetMessageAllocatorFor_StopEventStream( ::grpc::MessageAllocator< ::google::protobuf::Empty, ::google::protobuf::Empty>* allocator) { - ::grpc::internal::MethodHandler* const handler = ::grpc::Service::GetHandler(54); + ::grpc::internal::MethodHandler* const handler = ::grpc::Service::GetHandler(56); static_cast<::grpc::internal::CallbackUnaryHandler< ::google::protobuf::Empty, ::google::protobuf::Empty>*>(handler) ->SetMessageAllocator(allocator); } @@ -4025,7 +4167,7 @@ class Bridge final { virtual ::grpc::ServerUnaryReactor* StopEventStream( ::grpc::CallbackServerContext* /*context*/, const ::google::protobuf::Empty* /*request*/, ::google::protobuf::Empty* /*response*/) { return nullptr; } }; - typedef WithCallbackMethod_CheckTokens > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > CallbackService; + typedef WithCallbackMethod_CheckTokens > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > CallbackService; typedef CallbackService ExperimentalCallbackService; template class WithGenericMethod_CheckTokens : public BaseClass { @@ -4232,12 +4374,46 @@ class Bridge final { } }; template + class WithGenericMethod_SetIsTelemetryDisabled : public BaseClass { + private: + void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} + public: + WithGenericMethod_SetIsTelemetryDisabled() { + ::grpc::Service::MarkMethodGeneric(12); + } + ~WithGenericMethod_SetIsTelemetryDisabled() override { + BaseClassMustBeDerivedFromService(this); + } + // disable synchronous version of this method + ::grpc::Status SetIsTelemetryDisabled(::grpc::ServerContext* /*context*/, const ::google::protobuf::BoolValue* /*request*/, ::google::protobuf::Empty* /*response*/) override { + abort(); + return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); + } + }; + template + class WithGenericMethod_IsTelemetryDisabled : public BaseClass { + private: + void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} + public: + WithGenericMethod_IsTelemetryDisabled() { + ::grpc::Service::MarkMethodGeneric(13); + } + ~WithGenericMethod_IsTelemetryDisabled() override { + BaseClassMustBeDerivedFromService(this); + } + // disable synchronous version of this method + ::grpc::Status IsTelemetryDisabled(::grpc::ServerContext* /*context*/, const ::google::protobuf::Empty* /*request*/, ::google::protobuf::BoolValue* /*response*/) override { + abort(); + return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); + } + }; + template class WithGenericMethod_GoOs : public BaseClass { private: void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithGenericMethod_GoOs() { - ::grpc::Service::MarkMethodGeneric(12); + ::grpc::Service::MarkMethodGeneric(14); } ~WithGenericMethod_GoOs() override { BaseClassMustBeDerivedFromService(this); @@ -4254,7 +4430,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithGenericMethod_TriggerReset() { - ::grpc::Service::MarkMethodGeneric(13); + ::grpc::Service::MarkMethodGeneric(15); } ~WithGenericMethod_TriggerReset() override { BaseClassMustBeDerivedFromService(this); @@ -4271,7 +4447,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithGenericMethod_Version() { - ::grpc::Service::MarkMethodGeneric(14); + ::grpc::Service::MarkMethodGeneric(16); } ~WithGenericMethod_Version() override { BaseClassMustBeDerivedFromService(this); @@ -4288,7 +4464,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithGenericMethod_LogsPath() { - ::grpc::Service::MarkMethodGeneric(15); + ::grpc::Service::MarkMethodGeneric(17); } ~WithGenericMethod_LogsPath() override { BaseClassMustBeDerivedFromService(this); @@ -4305,7 +4481,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithGenericMethod_LicensePath() { - ::grpc::Service::MarkMethodGeneric(16); + ::grpc::Service::MarkMethodGeneric(18); } ~WithGenericMethod_LicensePath() override { BaseClassMustBeDerivedFromService(this); @@ -4322,7 +4498,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithGenericMethod_ReleaseNotesPageLink() { - ::grpc::Service::MarkMethodGeneric(17); + ::grpc::Service::MarkMethodGeneric(19); } ~WithGenericMethod_ReleaseNotesPageLink() override { BaseClassMustBeDerivedFromService(this); @@ -4339,7 +4515,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithGenericMethod_DependencyLicensesLink() { - ::grpc::Service::MarkMethodGeneric(18); + ::grpc::Service::MarkMethodGeneric(20); } ~WithGenericMethod_DependencyLicensesLink() override { BaseClassMustBeDerivedFromService(this); @@ -4356,7 +4532,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithGenericMethod_LandingPageLink() { - ::grpc::Service::MarkMethodGeneric(19); + ::grpc::Service::MarkMethodGeneric(21); } ~WithGenericMethod_LandingPageLink() override { BaseClassMustBeDerivedFromService(this); @@ -4373,7 +4549,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithGenericMethod_SetColorSchemeName() { - ::grpc::Service::MarkMethodGeneric(20); + ::grpc::Service::MarkMethodGeneric(22); } ~WithGenericMethod_SetColorSchemeName() override { BaseClassMustBeDerivedFromService(this); @@ -4390,7 +4566,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithGenericMethod_ColorSchemeName() { - ::grpc::Service::MarkMethodGeneric(21); + ::grpc::Service::MarkMethodGeneric(23); } ~WithGenericMethod_ColorSchemeName() override { BaseClassMustBeDerivedFromService(this); @@ -4407,7 +4583,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithGenericMethod_CurrentEmailClient() { - ::grpc::Service::MarkMethodGeneric(22); + ::grpc::Service::MarkMethodGeneric(24); } ~WithGenericMethod_CurrentEmailClient() override { BaseClassMustBeDerivedFromService(this); @@ -4424,7 +4600,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithGenericMethod_ReportBug() { - ::grpc::Service::MarkMethodGeneric(23); + ::grpc::Service::MarkMethodGeneric(25); } ~WithGenericMethod_ReportBug() override { BaseClassMustBeDerivedFromService(this); @@ -4441,7 +4617,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithGenericMethod_ExportTLSCertificates() { - ::grpc::Service::MarkMethodGeneric(24); + ::grpc::Service::MarkMethodGeneric(26); } ~WithGenericMethod_ExportTLSCertificates() override { BaseClassMustBeDerivedFromService(this); @@ -4458,7 +4634,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithGenericMethod_ForceLauncher() { - ::grpc::Service::MarkMethodGeneric(25); + ::grpc::Service::MarkMethodGeneric(27); } ~WithGenericMethod_ForceLauncher() override { BaseClassMustBeDerivedFromService(this); @@ -4475,7 +4651,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithGenericMethod_SetMainExecutable() { - ::grpc::Service::MarkMethodGeneric(26); + ::grpc::Service::MarkMethodGeneric(28); } ~WithGenericMethod_SetMainExecutable() override { BaseClassMustBeDerivedFromService(this); @@ -4492,7 +4668,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithGenericMethod_Login() { - ::grpc::Service::MarkMethodGeneric(27); + ::grpc::Service::MarkMethodGeneric(29); } ~WithGenericMethod_Login() override { BaseClassMustBeDerivedFromService(this); @@ -4509,7 +4685,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithGenericMethod_Login2FA() { - ::grpc::Service::MarkMethodGeneric(28); + ::grpc::Service::MarkMethodGeneric(30); } ~WithGenericMethod_Login2FA() override { BaseClassMustBeDerivedFromService(this); @@ -4526,7 +4702,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithGenericMethod_Login2Passwords() { - ::grpc::Service::MarkMethodGeneric(29); + ::grpc::Service::MarkMethodGeneric(31); } ~WithGenericMethod_Login2Passwords() override { BaseClassMustBeDerivedFromService(this); @@ -4543,7 +4719,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithGenericMethod_LoginAbort() { - ::grpc::Service::MarkMethodGeneric(30); + ::grpc::Service::MarkMethodGeneric(32); } ~WithGenericMethod_LoginAbort() override { BaseClassMustBeDerivedFromService(this); @@ -4560,7 +4736,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithGenericMethod_CheckUpdate() { - ::grpc::Service::MarkMethodGeneric(31); + ::grpc::Service::MarkMethodGeneric(33); } ~WithGenericMethod_CheckUpdate() override { BaseClassMustBeDerivedFromService(this); @@ -4577,7 +4753,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithGenericMethod_InstallUpdate() { - ::grpc::Service::MarkMethodGeneric(32); + ::grpc::Service::MarkMethodGeneric(34); } ~WithGenericMethod_InstallUpdate() override { BaseClassMustBeDerivedFromService(this); @@ -4594,7 +4770,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithGenericMethod_SetIsAutomaticUpdateOn() { - ::grpc::Service::MarkMethodGeneric(33); + ::grpc::Service::MarkMethodGeneric(35); } ~WithGenericMethod_SetIsAutomaticUpdateOn() override { BaseClassMustBeDerivedFromService(this); @@ -4611,7 +4787,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithGenericMethod_IsAutomaticUpdateOn() { - ::grpc::Service::MarkMethodGeneric(34); + ::grpc::Service::MarkMethodGeneric(36); } ~WithGenericMethod_IsAutomaticUpdateOn() override { BaseClassMustBeDerivedFromService(this); @@ -4628,7 +4804,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithGenericMethod_DiskCachePath() { - ::grpc::Service::MarkMethodGeneric(35); + ::grpc::Service::MarkMethodGeneric(37); } ~WithGenericMethod_DiskCachePath() override { BaseClassMustBeDerivedFromService(this); @@ -4645,7 +4821,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithGenericMethod_SetDiskCachePath() { - ::grpc::Service::MarkMethodGeneric(36); + ::grpc::Service::MarkMethodGeneric(38); } ~WithGenericMethod_SetDiskCachePath() override { BaseClassMustBeDerivedFromService(this); @@ -4662,7 +4838,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithGenericMethod_SetIsDoHEnabled() { - ::grpc::Service::MarkMethodGeneric(37); + ::grpc::Service::MarkMethodGeneric(39); } ~WithGenericMethod_SetIsDoHEnabled() override { BaseClassMustBeDerivedFromService(this); @@ -4679,7 +4855,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithGenericMethod_IsDoHEnabled() { - ::grpc::Service::MarkMethodGeneric(38); + ::grpc::Service::MarkMethodGeneric(40); } ~WithGenericMethod_IsDoHEnabled() override { BaseClassMustBeDerivedFromService(this); @@ -4696,7 +4872,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithGenericMethod_MailServerSettings() { - ::grpc::Service::MarkMethodGeneric(39); + ::grpc::Service::MarkMethodGeneric(41); } ~WithGenericMethod_MailServerSettings() override { BaseClassMustBeDerivedFromService(this); @@ -4713,7 +4889,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithGenericMethod_SetMailServerSettings() { - ::grpc::Service::MarkMethodGeneric(40); + ::grpc::Service::MarkMethodGeneric(42); } ~WithGenericMethod_SetMailServerSettings() override { BaseClassMustBeDerivedFromService(this); @@ -4730,7 +4906,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithGenericMethod_Hostname() { - ::grpc::Service::MarkMethodGeneric(41); + ::grpc::Service::MarkMethodGeneric(43); } ~WithGenericMethod_Hostname() override { BaseClassMustBeDerivedFromService(this); @@ -4747,7 +4923,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithGenericMethod_IsPortFree() { - ::grpc::Service::MarkMethodGeneric(42); + ::grpc::Service::MarkMethodGeneric(44); } ~WithGenericMethod_IsPortFree() override { BaseClassMustBeDerivedFromService(this); @@ -4764,7 +4940,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithGenericMethod_AvailableKeychains() { - ::grpc::Service::MarkMethodGeneric(43); + ::grpc::Service::MarkMethodGeneric(45); } ~WithGenericMethod_AvailableKeychains() override { BaseClassMustBeDerivedFromService(this); @@ -4781,7 +4957,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithGenericMethod_SetCurrentKeychain() { - ::grpc::Service::MarkMethodGeneric(44); + ::grpc::Service::MarkMethodGeneric(46); } ~WithGenericMethod_SetCurrentKeychain() override { BaseClassMustBeDerivedFromService(this); @@ -4798,7 +4974,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithGenericMethod_CurrentKeychain() { - ::grpc::Service::MarkMethodGeneric(45); + ::grpc::Service::MarkMethodGeneric(47); } ~WithGenericMethod_CurrentKeychain() override { BaseClassMustBeDerivedFromService(this); @@ -4815,7 +4991,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithGenericMethod_GetUserList() { - ::grpc::Service::MarkMethodGeneric(46); + ::grpc::Service::MarkMethodGeneric(48); } ~WithGenericMethod_GetUserList() override { BaseClassMustBeDerivedFromService(this); @@ -4832,7 +5008,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithGenericMethod_GetUser() { - ::grpc::Service::MarkMethodGeneric(47); + ::grpc::Service::MarkMethodGeneric(49); } ~WithGenericMethod_GetUser() override { BaseClassMustBeDerivedFromService(this); @@ -4849,7 +5025,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithGenericMethod_SetUserSplitMode() { - ::grpc::Service::MarkMethodGeneric(48); + ::grpc::Service::MarkMethodGeneric(50); } ~WithGenericMethod_SetUserSplitMode() override { BaseClassMustBeDerivedFromService(this); @@ -4866,7 +5042,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithGenericMethod_SendBadEventUserFeedback() { - ::grpc::Service::MarkMethodGeneric(49); + ::grpc::Service::MarkMethodGeneric(51); } ~WithGenericMethod_SendBadEventUserFeedback() override { BaseClassMustBeDerivedFromService(this); @@ -4883,7 +5059,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithGenericMethod_LogoutUser() { - ::grpc::Service::MarkMethodGeneric(50); + ::grpc::Service::MarkMethodGeneric(52); } ~WithGenericMethod_LogoutUser() override { BaseClassMustBeDerivedFromService(this); @@ -4900,7 +5076,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithGenericMethod_RemoveUser() { - ::grpc::Service::MarkMethodGeneric(51); + ::grpc::Service::MarkMethodGeneric(53); } ~WithGenericMethod_RemoveUser() override { BaseClassMustBeDerivedFromService(this); @@ -4917,7 +5093,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithGenericMethod_ConfigureUserAppleMail() { - ::grpc::Service::MarkMethodGeneric(52); + ::grpc::Service::MarkMethodGeneric(54); } ~WithGenericMethod_ConfigureUserAppleMail() override { BaseClassMustBeDerivedFromService(this); @@ -4934,7 +5110,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithGenericMethod_RunEventStream() { - ::grpc::Service::MarkMethodGeneric(53); + ::grpc::Service::MarkMethodGeneric(55); } ~WithGenericMethod_RunEventStream() override { BaseClassMustBeDerivedFromService(this); @@ -4951,7 +5127,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithGenericMethod_StopEventStream() { - ::grpc::Service::MarkMethodGeneric(54); + ::grpc::Service::MarkMethodGeneric(56); } ~WithGenericMethod_StopEventStream() override { BaseClassMustBeDerivedFromService(this); @@ -5203,12 +5379,52 @@ class Bridge final { } }; template + class WithRawMethod_SetIsTelemetryDisabled : public BaseClass { + private: + void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} + public: + WithRawMethod_SetIsTelemetryDisabled() { + ::grpc::Service::MarkMethodRaw(12); + } + ~WithRawMethod_SetIsTelemetryDisabled() override { + BaseClassMustBeDerivedFromService(this); + } + // disable synchronous version of this method + ::grpc::Status SetIsTelemetryDisabled(::grpc::ServerContext* /*context*/, const ::google::protobuf::BoolValue* /*request*/, ::google::protobuf::Empty* /*response*/) override { + abort(); + return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); + } + void RequestSetIsTelemetryDisabled(::grpc::ServerContext* context, ::grpc::ByteBuffer* request, ::grpc::ServerAsyncResponseWriter< ::grpc::ByteBuffer>* response, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) { + ::grpc::Service::RequestAsyncUnary(12, context, request, response, new_call_cq, notification_cq, tag); + } + }; + template + class WithRawMethod_IsTelemetryDisabled : public BaseClass { + private: + void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} + public: + WithRawMethod_IsTelemetryDisabled() { + ::grpc::Service::MarkMethodRaw(13); + } + ~WithRawMethod_IsTelemetryDisabled() override { + BaseClassMustBeDerivedFromService(this); + } + // disable synchronous version of this method + ::grpc::Status IsTelemetryDisabled(::grpc::ServerContext* /*context*/, const ::google::protobuf::Empty* /*request*/, ::google::protobuf::BoolValue* /*response*/) override { + abort(); + return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); + } + void RequestIsTelemetryDisabled(::grpc::ServerContext* context, ::grpc::ByteBuffer* request, ::grpc::ServerAsyncResponseWriter< ::grpc::ByteBuffer>* response, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) { + ::grpc::Service::RequestAsyncUnary(13, context, request, response, new_call_cq, notification_cq, tag); + } + }; + template class WithRawMethod_GoOs : public BaseClass { private: void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithRawMethod_GoOs() { - ::grpc::Service::MarkMethodRaw(12); + ::grpc::Service::MarkMethodRaw(14); } ~WithRawMethod_GoOs() override { BaseClassMustBeDerivedFromService(this); @@ -5219,7 +5435,7 @@ class Bridge final { return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); } void RequestGoOs(::grpc::ServerContext* context, ::grpc::ByteBuffer* request, ::grpc::ServerAsyncResponseWriter< ::grpc::ByteBuffer>* response, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) { - ::grpc::Service::RequestAsyncUnary(12, context, request, response, new_call_cq, notification_cq, tag); + ::grpc::Service::RequestAsyncUnary(14, context, request, response, new_call_cq, notification_cq, tag); } }; template @@ -5228,7 +5444,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithRawMethod_TriggerReset() { - ::grpc::Service::MarkMethodRaw(13); + ::grpc::Service::MarkMethodRaw(15); } ~WithRawMethod_TriggerReset() override { BaseClassMustBeDerivedFromService(this); @@ -5239,7 +5455,7 @@ class Bridge final { return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); } void RequestTriggerReset(::grpc::ServerContext* context, ::grpc::ByteBuffer* request, ::grpc::ServerAsyncResponseWriter< ::grpc::ByteBuffer>* response, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) { - ::grpc::Service::RequestAsyncUnary(13, context, request, response, new_call_cq, notification_cq, tag); + ::grpc::Service::RequestAsyncUnary(15, context, request, response, new_call_cq, notification_cq, tag); } }; template @@ -5248,7 +5464,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithRawMethod_Version() { - ::grpc::Service::MarkMethodRaw(14); + ::grpc::Service::MarkMethodRaw(16); } ~WithRawMethod_Version() override { BaseClassMustBeDerivedFromService(this); @@ -5259,7 +5475,7 @@ class Bridge final { return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); } void RequestVersion(::grpc::ServerContext* context, ::grpc::ByteBuffer* request, ::grpc::ServerAsyncResponseWriter< ::grpc::ByteBuffer>* response, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) { - ::grpc::Service::RequestAsyncUnary(14, context, request, response, new_call_cq, notification_cq, tag); + ::grpc::Service::RequestAsyncUnary(16, context, request, response, new_call_cq, notification_cq, tag); } }; template @@ -5268,7 +5484,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithRawMethod_LogsPath() { - ::grpc::Service::MarkMethodRaw(15); + ::grpc::Service::MarkMethodRaw(17); } ~WithRawMethod_LogsPath() override { BaseClassMustBeDerivedFromService(this); @@ -5279,7 +5495,7 @@ class Bridge final { return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); } void RequestLogsPath(::grpc::ServerContext* context, ::grpc::ByteBuffer* request, ::grpc::ServerAsyncResponseWriter< ::grpc::ByteBuffer>* response, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) { - ::grpc::Service::RequestAsyncUnary(15, context, request, response, new_call_cq, notification_cq, tag); + ::grpc::Service::RequestAsyncUnary(17, context, request, response, new_call_cq, notification_cq, tag); } }; template @@ -5288,7 +5504,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithRawMethod_LicensePath() { - ::grpc::Service::MarkMethodRaw(16); + ::grpc::Service::MarkMethodRaw(18); } ~WithRawMethod_LicensePath() override { BaseClassMustBeDerivedFromService(this); @@ -5299,7 +5515,7 @@ class Bridge final { return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); } void RequestLicensePath(::grpc::ServerContext* context, ::grpc::ByteBuffer* request, ::grpc::ServerAsyncResponseWriter< ::grpc::ByteBuffer>* response, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) { - ::grpc::Service::RequestAsyncUnary(16, context, request, response, new_call_cq, notification_cq, tag); + ::grpc::Service::RequestAsyncUnary(18, context, request, response, new_call_cq, notification_cq, tag); } }; template @@ -5308,7 +5524,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithRawMethod_ReleaseNotesPageLink() { - ::grpc::Service::MarkMethodRaw(17); + ::grpc::Service::MarkMethodRaw(19); } ~WithRawMethod_ReleaseNotesPageLink() override { BaseClassMustBeDerivedFromService(this); @@ -5319,7 +5535,7 @@ class Bridge final { return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); } void RequestReleaseNotesPageLink(::grpc::ServerContext* context, ::grpc::ByteBuffer* request, ::grpc::ServerAsyncResponseWriter< ::grpc::ByteBuffer>* response, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) { - ::grpc::Service::RequestAsyncUnary(17, context, request, response, new_call_cq, notification_cq, tag); + ::grpc::Service::RequestAsyncUnary(19, context, request, response, new_call_cq, notification_cq, tag); } }; template @@ -5328,7 +5544,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithRawMethod_DependencyLicensesLink() { - ::grpc::Service::MarkMethodRaw(18); + ::grpc::Service::MarkMethodRaw(20); } ~WithRawMethod_DependencyLicensesLink() override { BaseClassMustBeDerivedFromService(this); @@ -5339,7 +5555,7 @@ class Bridge final { return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); } void RequestDependencyLicensesLink(::grpc::ServerContext* context, ::grpc::ByteBuffer* request, ::grpc::ServerAsyncResponseWriter< ::grpc::ByteBuffer>* response, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) { - ::grpc::Service::RequestAsyncUnary(18, context, request, response, new_call_cq, notification_cq, tag); + ::grpc::Service::RequestAsyncUnary(20, context, request, response, new_call_cq, notification_cq, tag); } }; template @@ -5348,7 +5564,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithRawMethod_LandingPageLink() { - ::grpc::Service::MarkMethodRaw(19); + ::grpc::Service::MarkMethodRaw(21); } ~WithRawMethod_LandingPageLink() override { BaseClassMustBeDerivedFromService(this); @@ -5359,7 +5575,7 @@ class Bridge final { return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); } void RequestLandingPageLink(::grpc::ServerContext* context, ::grpc::ByteBuffer* request, ::grpc::ServerAsyncResponseWriter< ::grpc::ByteBuffer>* response, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) { - ::grpc::Service::RequestAsyncUnary(19, context, request, response, new_call_cq, notification_cq, tag); + ::grpc::Service::RequestAsyncUnary(21, context, request, response, new_call_cq, notification_cq, tag); } }; template @@ -5368,7 +5584,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithRawMethod_SetColorSchemeName() { - ::grpc::Service::MarkMethodRaw(20); + ::grpc::Service::MarkMethodRaw(22); } ~WithRawMethod_SetColorSchemeName() override { BaseClassMustBeDerivedFromService(this); @@ -5379,7 +5595,7 @@ class Bridge final { return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); } void RequestSetColorSchemeName(::grpc::ServerContext* context, ::grpc::ByteBuffer* request, ::grpc::ServerAsyncResponseWriter< ::grpc::ByteBuffer>* response, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) { - ::grpc::Service::RequestAsyncUnary(20, context, request, response, new_call_cq, notification_cq, tag); + ::grpc::Service::RequestAsyncUnary(22, context, request, response, new_call_cq, notification_cq, tag); } }; template @@ -5388,7 +5604,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithRawMethod_ColorSchemeName() { - ::grpc::Service::MarkMethodRaw(21); + ::grpc::Service::MarkMethodRaw(23); } ~WithRawMethod_ColorSchemeName() override { BaseClassMustBeDerivedFromService(this); @@ -5399,7 +5615,7 @@ class Bridge final { return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); } void RequestColorSchemeName(::grpc::ServerContext* context, ::grpc::ByteBuffer* request, ::grpc::ServerAsyncResponseWriter< ::grpc::ByteBuffer>* response, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) { - ::grpc::Service::RequestAsyncUnary(21, context, request, response, new_call_cq, notification_cq, tag); + ::grpc::Service::RequestAsyncUnary(23, context, request, response, new_call_cq, notification_cq, tag); } }; template @@ -5408,7 +5624,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithRawMethod_CurrentEmailClient() { - ::grpc::Service::MarkMethodRaw(22); + ::grpc::Service::MarkMethodRaw(24); } ~WithRawMethod_CurrentEmailClient() override { BaseClassMustBeDerivedFromService(this); @@ -5419,7 +5635,7 @@ class Bridge final { return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); } void RequestCurrentEmailClient(::grpc::ServerContext* context, ::grpc::ByteBuffer* request, ::grpc::ServerAsyncResponseWriter< ::grpc::ByteBuffer>* response, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) { - ::grpc::Service::RequestAsyncUnary(22, context, request, response, new_call_cq, notification_cq, tag); + ::grpc::Service::RequestAsyncUnary(24, context, request, response, new_call_cq, notification_cq, tag); } }; template @@ -5428,7 +5644,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithRawMethod_ReportBug() { - ::grpc::Service::MarkMethodRaw(23); + ::grpc::Service::MarkMethodRaw(25); } ~WithRawMethod_ReportBug() override { BaseClassMustBeDerivedFromService(this); @@ -5439,7 +5655,7 @@ class Bridge final { return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); } void RequestReportBug(::grpc::ServerContext* context, ::grpc::ByteBuffer* request, ::grpc::ServerAsyncResponseWriter< ::grpc::ByteBuffer>* response, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) { - ::grpc::Service::RequestAsyncUnary(23, context, request, response, new_call_cq, notification_cq, tag); + ::grpc::Service::RequestAsyncUnary(25, context, request, response, new_call_cq, notification_cq, tag); } }; template @@ -5448,7 +5664,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithRawMethod_ExportTLSCertificates() { - ::grpc::Service::MarkMethodRaw(24); + ::grpc::Service::MarkMethodRaw(26); } ~WithRawMethod_ExportTLSCertificates() override { BaseClassMustBeDerivedFromService(this); @@ -5459,7 +5675,7 @@ class Bridge final { return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); } void RequestExportTLSCertificates(::grpc::ServerContext* context, ::grpc::ByteBuffer* request, ::grpc::ServerAsyncResponseWriter< ::grpc::ByteBuffer>* response, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) { - ::grpc::Service::RequestAsyncUnary(24, context, request, response, new_call_cq, notification_cq, tag); + ::grpc::Service::RequestAsyncUnary(26, context, request, response, new_call_cq, notification_cq, tag); } }; template @@ -5468,7 +5684,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithRawMethod_ForceLauncher() { - ::grpc::Service::MarkMethodRaw(25); + ::grpc::Service::MarkMethodRaw(27); } ~WithRawMethod_ForceLauncher() override { BaseClassMustBeDerivedFromService(this); @@ -5479,7 +5695,7 @@ class Bridge final { return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); } void RequestForceLauncher(::grpc::ServerContext* context, ::grpc::ByteBuffer* request, ::grpc::ServerAsyncResponseWriter< ::grpc::ByteBuffer>* response, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) { - ::grpc::Service::RequestAsyncUnary(25, context, request, response, new_call_cq, notification_cq, tag); + ::grpc::Service::RequestAsyncUnary(27, context, request, response, new_call_cq, notification_cq, tag); } }; template @@ -5488,7 +5704,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithRawMethod_SetMainExecutable() { - ::grpc::Service::MarkMethodRaw(26); + ::grpc::Service::MarkMethodRaw(28); } ~WithRawMethod_SetMainExecutable() override { BaseClassMustBeDerivedFromService(this); @@ -5499,7 +5715,7 @@ class Bridge final { return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); } void RequestSetMainExecutable(::grpc::ServerContext* context, ::grpc::ByteBuffer* request, ::grpc::ServerAsyncResponseWriter< ::grpc::ByteBuffer>* response, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) { - ::grpc::Service::RequestAsyncUnary(26, context, request, response, new_call_cq, notification_cq, tag); + ::grpc::Service::RequestAsyncUnary(28, context, request, response, new_call_cq, notification_cq, tag); } }; template @@ -5508,7 +5724,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithRawMethod_Login() { - ::grpc::Service::MarkMethodRaw(27); + ::grpc::Service::MarkMethodRaw(29); } ~WithRawMethod_Login() override { BaseClassMustBeDerivedFromService(this); @@ -5519,7 +5735,7 @@ class Bridge final { return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); } void RequestLogin(::grpc::ServerContext* context, ::grpc::ByteBuffer* request, ::grpc::ServerAsyncResponseWriter< ::grpc::ByteBuffer>* response, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) { - ::grpc::Service::RequestAsyncUnary(27, context, request, response, new_call_cq, notification_cq, tag); + ::grpc::Service::RequestAsyncUnary(29, context, request, response, new_call_cq, notification_cq, tag); } }; template @@ -5528,7 +5744,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithRawMethod_Login2FA() { - ::grpc::Service::MarkMethodRaw(28); + ::grpc::Service::MarkMethodRaw(30); } ~WithRawMethod_Login2FA() override { BaseClassMustBeDerivedFromService(this); @@ -5539,7 +5755,7 @@ class Bridge final { return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); } void RequestLogin2FA(::grpc::ServerContext* context, ::grpc::ByteBuffer* request, ::grpc::ServerAsyncResponseWriter< ::grpc::ByteBuffer>* response, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) { - ::grpc::Service::RequestAsyncUnary(28, context, request, response, new_call_cq, notification_cq, tag); + ::grpc::Service::RequestAsyncUnary(30, context, request, response, new_call_cq, notification_cq, tag); } }; template @@ -5548,7 +5764,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithRawMethod_Login2Passwords() { - ::grpc::Service::MarkMethodRaw(29); + ::grpc::Service::MarkMethodRaw(31); } ~WithRawMethod_Login2Passwords() override { BaseClassMustBeDerivedFromService(this); @@ -5559,7 +5775,7 @@ class Bridge final { return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); } void RequestLogin2Passwords(::grpc::ServerContext* context, ::grpc::ByteBuffer* request, ::grpc::ServerAsyncResponseWriter< ::grpc::ByteBuffer>* response, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) { - ::grpc::Service::RequestAsyncUnary(29, context, request, response, new_call_cq, notification_cq, tag); + ::grpc::Service::RequestAsyncUnary(31, context, request, response, new_call_cq, notification_cq, tag); } }; template @@ -5568,7 +5784,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithRawMethod_LoginAbort() { - ::grpc::Service::MarkMethodRaw(30); + ::grpc::Service::MarkMethodRaw(32); } ~WithRawMethod_LoginAbort() override { BaseClassMustBeDerivedFromService(this); @@ -5579,7 +5795,7 @@ class Bridge final { return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); } void RequestLoginAbort(::grpc::ServerContext* context, ::grpc::ByteBuffer* request, ::grpc::ServerAsyncResponseWriter< ::grpc::ByteBuffer>* response, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) { - ::grpc::Service::RequestAsyncUnary(30, context, request, response, new_call_cq, notification_cq, tag); + ::grpc::Service::RequestAsyncUnary(32, context, request, response, new_call_cq, notification_cq, tag); } }; template @@ -5588,7 +5804,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithRawMethod_CheckUpdate() { - ::grpc::Service::MarkMethodRaw(31); + ::grpc::Service::MarkMethodRaw(33); } ~WithRawMethod_CheckUpdate() override { BaseClassMustBeDerivedFromService(this); @@ -5599,7 +5815,7 @@ class Bridge final { return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); } void RequestCheckUpdate(::grpc::ServerContext* context, ::grpc::ByteBuffer* request, ::grpc::ServerAsyncResponseWriter< ::grpc::ByteBuffer>* response, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) { - ::grpc::Service::RequestAsyncUnary(31, context, request, response, new_call_cq, notification_cq, tag); + ::grpc::Service::RequestAsyncUnary(33, context, request, response, new_call_cq, notification_cq, tag); } }; template @@ -5608,7 +5824,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithRawMethod_InstallUpdate() { - ::grpc::Service::MarkMethodRaw(32); + ::grpc::Service::MarkMethodRaw(34); } ~WithRawMethod_InstallUpdate() override { BaseClassMustBeDerivedFromService(this); @@ -5619,7 +5835,7 @@ class Bridge final { return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); } void RequestInstallUpdate(::grpc::ServerContext* context, ::grpc::ByteBuffer* request, ::grpc::ServerAsyncResponseWriter< ::grpc::ByteBuffer>* response, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) { - ::grpc::Service::RequestAsyncUnary(32, context, request, response, new_call_cq, notification_cq, tag); + ::grpc::Service::RequestAsyncUnary(34, context, request, response, new_call_cq, notification_cq, tag); } }; template @@ -5628,7 +5844,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithRawMethod_SetIsAutomaticUpdateOn() { - ::grpc::Service::MarkMethodRaw(33); + ::grpc::Service::MarkMethodRaw(35); } ~WithRawMethod_SetIsAutomaticUpdateOn() override { BaseClassMustBeDerivedFromService(this); @@ -5639,7 +5855,7 @@ class Bridge final { return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); } void RequestSetIsAutomaticUpdateOn(::grpc::ServerContext* context, ::grpc::ByteBuffer* request, ::grpc::ServerAsyncResponseWriter< ::grpc::ByteBuffer>* response, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) { - ::grpc::Service::RequestAsyncUnary(33, context, request, response, new_call_cq, notification_cq, tag); + ::grpc::Service::RequestAsyncUnary(35, context, request, response, new_call_cq, notification_cq, tag); } }; template @@ -5648,7 +5864,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithRawMethod_IsAutomaticUpdateOn() { - ::grpc::Service::MarkMethodRaw(34); + ::grpc::Service::MarkMethodRaw(36); } ~WithRawMethod_IsAutomaticUpdateOn() override { BaseClassMustBeDerivedFromService(this); @@ -5659,7 +5875,7 @@ class Bridge final { return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); } void RequestIsAutomaticUpdateOn(::grpc::ServerContext* context, ::grpc::ByteBuffer* request, ::grpc::ServerAsyncResponseWriter< ::grpc::ByteBuffer>* response, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) { - ::grpc::Service::RequestAsyncUnary(34, context, request, response, new_call_cq, notification_cq, tag); + ::grpc::Service::RequestAsyncUnary(36, context, request, response, new_call_cq, notification_cq, tag); } }; template @@ -5668,7 +5884,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithRawMethod_DiskCachePath() { - ::grpc::Service::MarkMethodRaw(35); + ::grpc::Service::MarkMethodRaw(37); } ~WithRawMethod_DiskCachePath() override { BaseClassMustBeDerivedFromService(this); @@ -5679,7 +5895,7 @@ class Bridge final { return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); } void RequestDiskCachePath(::grpc::ServerContext* context, ::grpc::ByteBuffer* request, ::grpc::ServerAsyncResponseWriter< ::grpc::ByteBuffer>* response, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) { - ::grpc::Service::RequestAsyncUnary(35, context, request, response, new_call_cq, notification_cq, tag); + ::grpc::Service::RequestAsyncUnary(37, context, request, response, new_call_cq, notification_cq, tag); } }; template @@ -5688,7 +5904,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithRawMethod_SetDiskCachePath() { - ::grpc::Service::MarkMethodRaw(36); + ::grpc::Service::MarkMethodRaw(38); } ~WithRawMethod_SetDiskCachePath() override { BaseClassMustBeDerivedFromService(this); @@ -5699,7 +5915,7 @@ class Bridge final { return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); } void RequestSetDiskCachePath(::grpc::ServerContext* context, ::grpc::ByteBuffer* request, ::grpc::ServerAsyncResponseWriter< ::grpc::ByteBuffer>* response, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) { - ::grpc::Service::RequestAsyncUnary(36, context, request, response, new_call_cq, notification_cq, tag); + ::grpc::Service::RequestAsyncUnary(38, context, request, response, new_call_cq, notification_cq, tag); } }; template @@ -5708,7 +5924,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithRawMethod_SetIsDoHEnabled() { - ::grpc::Service::MarkMethodRaw(37); + ::grpc::Service::MarkMethodRaw(39); } ~WithRawMethod_SetIsDoHEnabled() override { BaseClassMustBeDerivedFromService(this); @@ -5719,7 +5935,7 @@ class Bridge final { return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); } void RequestSetIsDoHEnabled(::grpc::ServerContext* context, ::grpc::ByteBuffer* request, ::grpc::ServerAsyncResponseWriter< ::grpc::ByteBuffer>* response, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) { - ::grpc::Service::RequestAsyncUnary(37, context, request, response, new_call_cq, notification_cq, tag); + ::grpc::Service::RequestAsyncUnary(39, context, request, response, new_call_cq, notification_cq, tag); } }; template @@ -5728,7 +5944,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithRawMethod_IsDoHEnabled() { - ::grpc::Service::MarkMethodRaw(38); + ::grpc::Service::MarkMethodRaw(40); } ~WithRawMethod_IsDoHEnabled() override { BaseClassMustBeDerivedFromService(this); @@ -5739,7 +5955,7 @@ class Bridge final { return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); } void RequestIsDoHEnabled(::grpc::ServerContext* context, ::grpc::ByteBuffer* request, ::grpc::ServerAsyncResponseWriter< ::grpc::ByteBuffer>* response, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) { - ::grpc::Service::RequestAsyncUnary(38, context, request, response, new_call_cq, notification_cq, tag); + ::grpc::Service::RequestAsyncUnary(40, context, request, response, new_call_cq, notification_cq, tag); } }; template @@ -5748,7 +5964,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithRawMethod_MailServerSettings() { - ::grpc::Service::MarkMethodRaw(39); + ::grpc::Service::MarkMethodRaw(41); } ~WithRawMethod_MailServerSettings() override { BaseClassMustBeDerivedFromService(this); @@ -5759,7 +5975,7 @@ class Bridge final { return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); } void RequestMailServerSettings(::grpc::ServerContext* context, ::grpc::ByteBuffer* request, ::grpc::ServerAsyncResponseWriter< ::grpc::ByteBuffer>* response, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) { - ::grpc::Service::RequestAsyncUnary(39, context, request, response, new_call_cq, notification_cq, tag); + ::grpc::Service::RequestAsyncUnary(41, context, request, response, new_call_cq, notification_cq, tag); } }; template @@ -5768,7 +5984,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithRawMethod_SetMailServerSettings() { - ::grpc::Service::MarkMethodRaw(40); + ::grpc::Service::MarkMethodRaw(42); } ~WithRawMethod_SetMailServerSettings() override { BaseClassMustBeDerivedFromService(this); @@ -5779,7 +5995,7 @@ class Bridge final { return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); } void RequestSetMailServerSettings(::grpc::ServerContext* context, ::grpc::ByteBuffer* request, ::grpc::ServerAsyncResponseWriter< ::grpc::ByteBuffer>* response, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) { - ::grpc::Service::RequestAsyncUnary(40, context, request, response, new_call_cq, notification_cq, tag); + ::grpc::Service::RequestAsyncUnary(42, context, request, response, new_call_cq, notification_cq, tag); } }; template @@ -5788,7 +6004,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithRawMethod_Hostname() { - ::grpc::Service::MarkMethodRaw(41); + ::grpc::Service::MarkMethodRaw(43); } ~WithRawMethod_Hostname() override { BaseClassMustBeDerivedFromService(this); @@ -5799,7 +6015,7 @@ class Bridge final { return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); } void RequestHostname(::grpc::ServerContext* context, ::grpc::ByteBuffer* request, ::grpc::ServerAsyncResponseWriter< ::grpc::ByteBuffer>* response, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) { - ::grpc::Service::RequestAsyncUnary(41, context, request, response, new_call_cq, notification_cq, tag); + ::grpc::Service::RequestAsyncUnary(43, context, request, response, new_call_cq, notification_cq, tag); } }; template @@ -5808,7 +6024,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithRawMethod_IsPortFree() { - ::grpc::Service::MarkMethodRaw(42); + ::grpc::Service::MarkMethodRaw(44); } ~WithRawMethod_IsPortFree() override { BaseClassMustBeDerivedFromService(this); @@ -5819,7 +6035,7 @@ class Bridge final { return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); } void RequestIsPortFree(::grpc::ServerContext* context, ::grpc::ByteBuffer* request, ::grpc::ServerAsyncResponseWriter< ::grpc::ByteBuffer>* response, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) { - ::grpc::Service::RequestAsyncUnary(42, context, request, response, new_call_cq, notification_cq, tag); + ::grpc::Service::RequestAsyncUnary(44, context, request, response, new_call_cq, notification_cq, tag); } }; template @@ -5828,7 +6044,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithRawMethod_AvailableKeychains() { - ::grpc::Service::MarkMethodRaw(43); + ::grpc::Service::MarkMethodRaw(45); } ~WithRawMethod_AvailableKeychains() override { BaseClassMustBeDerivedFromService(this); @@ -5839,7 +6055,7 @@ class Bridge final { return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); } void RequestAvailableKeychains(::grpc::ServerContext* context, ::grpc::ByteBuffer* request, ::grpc::ServerAsyncResponseWriter< ::grpc::ByteBuffer>* response, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) { - ::grpc::Service::RequestAsyncUnary(43, context, request, response, new_call_cq, notification_cq, tag); + ::grpc::Service::RequestAsyncUnary(45, context, request, response, new_call_cq, notification_cq, tag); } }; template @@ -5848,7 +6064,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithRawMethod_SetCurrentKeychain() { - ::grpc::Service::MarkMethodRaw(44); + ::grpc::Service::MarkMethodRaw(46); } ~WithRawMethod_SetCurrentKeychain() override { BaseClassMustBeDerivedFromService(this); @@ -5859,7 +6075,7 @@ class Bridge final { return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); } void RequestSetCurrentKeychain(::grpc::ServerContext* context, ::grpc::ByteBuffer* request, ::grpc::ServerAsyncResponseWriter< ::grpc::ByteBuffer>* response, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) { - ::grpc::Service::RequestAsyncUnary(44, context, request, response, new_call_cq, notification_cq, tag); + ::grpc::Service::RequestAsyncUnary(46, context, request, response, new_call_cq, notification_cq, tag); } }; template @@ -5868,7 +6084,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithRawMethod_CurrentKeychain() { - ::grpc::Service::MarkMethodRaw(45); + ::grpc::Service::MarkMethodRaw(47); } ~WithRawMethod_CurrentKeychain() override { BaseClassMustBeDerivedFromService(this); @@ -5879,7 +6095,7 @@ class Bridge final { return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); } void RequestCurrentKeychain(::grpc::ServerContext* context, ::grpc::ByteBuffer* request, ::grpc::ServerAsyncResponseWriter< ::grpc::ByteBuffer>* response, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) { - ::grpc::Service::RequestAsyncUnary(45, context, request, response, new_call_cq, notification_cq, tag); + ::grpc::Service::RequestAsyncUnary(47, context, request, response, new_call_cq, notification_cq, tag); } }; template @@ -5888,7 +6104,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithRawMethod_GetUserList() { - ::grpc::Service::MarkMethodRaw(46); + ::grpc::Service::MarkMethodRaw(48); } ~WithRawMethod_GetUserList() override { BaseClassMustBeDerivedFromService(this); @@ -5899,7 +6115,7 @@ class Bridge final { return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); } void RequestGetUserList(::grpc::ServerContext* context, ::grpc::ByteBuffer* request, ::grpc::ServerAsyncResponseWriter< ::grpc::ByteBuffer>* response, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) { - ::grpc::Service::RequestAsyncUnary(46, context, request, response, new_call_cq, notification_cq, tag); + ::grpc::Service::RequestAsyncUnary(48, context, request, response, new_call_cq, notification_cq, tag); } }; template @@ -5908,7 +6124,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithRawMethod_GetUser() { - ::grpc::Service::MarkMethodRaw(47); + ::grpc::Service::MarkMethodRaw(49); } ~WithRawMethod_GetUser() override { BaseClassMustBeDerivedFromService(this); @@ -5919,7 +6135,7 @@ class Bridge final { return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); } void RequestGetUser(::grpc::ServerContext* context, ::grpc::ByteBuffer* request, ::grpc::ServerAsyncResponseWriter< ::grpc::ByteBuffer>* response, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) { - ::grpc::Service::RequestAsyncUnary(47, context, request, response, new_call_cq, notification_cq, tag); + ::grpc::Service::RequestAsyncUnary(49, context, request, response, new_call_cq, notification_cq, tag); } }; template @@ -5928,7 +6144,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithRawMethod_SetUserSplitMode() { - ::grpc::Service::MarkMethodRaw(48); + ::grpc::Service::MarkMethodRaw(50); } ~WithRawMethod_SetUserSplitMode() override { BaseClassMustBeDerivedFromService(this); @@ -5939,7 +6155,7 @@ class Bridge final { return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); } void RequestSetUserSplitMode(::grpc::ServerContext* context, ::grpc::ByteBuffer* request, ::grpc::ServerAsyncResponseWriter< ::grpc::ByteBuffer>* response, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) { - ::grpc::Service::RequestAsyncUnary(48, context, request, response, new_call_cq, notification_cq, tag); + ::grpc::Service::RequestAsyncUnary(50, context, request, response, new_call_cq, notification_cq, tag); } }; template @@ -5948,7 +6164,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithRawMethod_SendBadEventUserFeedback() { - ::grpc::Service::MarkMethodRaw(49); + ::grpc::Service::MarkMethodRaw(51); } ~WithRawMethod_SendBadEventUserFeedback() override { BaseClassMustBeDerivedFromService(this); @@ -5959,7 +6175,7 @@ class Bridge final { return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); } void RequestSendBadEventUserFeedback(::grpc::ServerContext* context, ::grpc::ByteBuffer* request, ::grpc::ServerAsyncResponseWriter< ::grpc::ByteBuffer>* response, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) { - ::grpc::Service::RequestAsyncUnary(49, context, request, response, new_call_cq, notification_cq, tag); + ::grpc::Service::RequestAsyncUnary(51, context, request, response, new_call_cq, notification_cq, tag); } }; template @@ -5968,7 +6184,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithRawMethod_LogoutUser() { - ::grpc::Service::MarkMethodRaw(50); + ::grpc::Service::MarkMethodRaw(52); } ~WithRawMethod_LogoutUser() override { BaseClassMustBeDerivedFromService(this); @@ -5979,7 +6195,7 @@ class Bridge final { return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); } void RequestLogoutUser(::grpc::ServerContext* context, ::grpc::ByteBuffer* request, ::grpc::ServerAsyncResponseWriter< ::grpc::ByteBuffer>* response, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) { - ::grpc::Service::RequestAsyncUnary(50, context, request, response, new_call_cq, notification_cq, tag); + ::grpc::Service::RequestAsyncUnary(52, context, request, response, new_call_cq, notification_cq, tag); } }; template @@ -5988,7 +6204,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithRawMethod_RemoveUser() { - ::grpc::Service::MarkMethodRaw(51); + ::grpc::Service::MarkMethodRaw(53); } ~WithRawMethod_RemoveUser() override { BaseClassMustBeDerivedFromService(this); @@ -5999,7 +6215,7 @@ class Bridge final { return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); } void RequestRemoveUser(::grpc::ServerContext* context, ::grpc::ByteBuffer* request, ::grpc::ServerAsyncResponseWriter< ::grpc::ByteBuffer>* response, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) { - ::grpc::Service::RequestAsyncUnary(51, context, request, response, new_call_cq, notification_cq, tag); + ::grpc::Service::RequestAsyncUnary(53, context, request, response, new_call_cq, notification_cq, tag); } }; template @@ -6008,7 +6224,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithRawMethod_ConfigureUserAppleMail() { - ::grpc::Service::MarkMethodRaw(52); + ::grpc::Service::MarkMethodRaw(54); } ~WithRawMethod_ConfigureUserAppleMail() override { BaseClassMustBeDerivedFromService(this); @@ -6019,7 +6235,7 @@ class Bridge final { return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); } void RequestConfigureUserAppleMail(::grpc::ServerContext* context, ::grpc::ByteBuffer* request, ::grpc::ServerAsyncResponseWriter< ::grpc::ByteBuffer>* response, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) { - ::grpc::Service::RequestAsyncUnary(52, context, request, response, new_call_cq, notification_cq, tag); + ::grpc::Service::RequestAsyncUnary(54, context, request, response, new_call_cq, notification_cq, tag); } }; template @@ -6028,7 +6244,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithRawMethod_RunEventStream() { - ::grpc::Service::MarkMethodRaw(53); + ::grpc::Service::MarkMethodRaw(55); } ~WithRawMethod_RunEventStream() override { BaseClassMustBeDerivedFromService(this); @@ -6039,7 +6255,7 @@ class Bridge final { return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); } void RequestRunEventStream(::grpc::ServerContext* context, ::grpc::ByteBuffer* request, ::grpc::ServerAsyncWriter< ::grpc::ByteBuffer>* writer, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) { - ::grpc::Service::RequestAsyncServerStreaming(53, context, request, writer, new_call_cq, notification_cq, tag); + ::grpc::Service::RequestAsyncServerStreaming(55, context, request, writer, new_call_cq, notification_cq, tag); } }; template @@ -6048,7 +6264,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithRawMethod_StopEventStream() { - ::grpc::Service::MarkMethodRaw(54); + ::grpc::Service::MarkMethodRaw(56); } ~WithRawMethod_StopEventStream() override { BaseClassMustBeDerivedFromService(this); @@ -6059,7 +6275,7 @@ class Bridge final { return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); } void RequestStopEventStream(::grpc::ServerContext* context, ::grpc::ByteBuffer* request, ::grpc::ServerAsyncResponseWriter< ::grpc::ByteBuffer>* response, ::grpc::CompletionQueue* new_call_cq, ::grpc::ServerCompletionQueue* notification_cq, void *tag) { - ::grpc::Service::RequestAsyncUnary(54, context, request, response, new_call_cq, notification_cq, tag); + ::grpc::Service::RequestAsyncUnary(56, context, request, response, new_call_cq, notification_cq, tag); } }; template @@ -6327,12 +6543,56 @@ class Bridge final { ::grpc::CallbackServerContext* /*context*/, const ::grpc::ByteBuffer* /*request*/, ::grpc::ByteBuffer* /*response*/) { return nullptr; } }; template + class WithRawCallbackMethod_SetIsTelemetryDisabled : public BaseClass { + private: + void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} + public: + WithRawCallbackMethod_SetIsTelemetryDisabled() { + ::grpc::Service::MarkMethodRawCallback(12, + new ::grpc::internal::CallbackUnaryHandler< ::grpc::ByteBuffer, ::grpc::ByteBuffer>( + [this]( + ::grpc::CallbackServerContext* context, const ::grpc::ByteBuffer* request, ::grpc::ByteBuffer* response) { return this->SetIsTelemetryDisabled(context, request, response); })); + } + ~WithRawCallbackMethod_SetIsTelemetryDisabled() override { + BaseClassMustBeDerivedFromService(this); + } + // disable synchronous version of this method + ::grpc::Status SetIsTelemetryDisabled(::grpc::ServerContext* /*context*/, const ::google::protobuf::BoolValue* /*request*/, ::google::protobuf::Empty* /*response*/) override { + abort(); + return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); + } + virtual ::grpc::ServerUnaryReactor* SetIsTelemetryDisabled( + ::grpc::CallbackServerContext* /*context*/, const ::grpc::ByteBuffer* /*request*/, ::grpc::ByteBuffer* /*response*/) { return nullptr; } + }; + template + class WithRawCallbackMethod_IsTelemetryDisabled : public BaseClass { + private: + void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} + public: + WithRawCallbackMethod_IsTelemetryDisabled() { + ::grpc::Service::MarkMethodRawCallback(13, + new ::grpc::internal::CallbackUnaryHandler< ::grpc::ByteBuffer, ::grpc::ByteBuffer>( + [this]( + ::grpc::CallbackServerContext* context, const ::grpc::ByteBuffer* request, ::grpc::ByteBuffer* response) { return this->IsTelemetryDisabled(context, request, response); })); + } + ~WithRawCallbackMethod_IsTelemetryDisabled() override { + BaseClassMustBeDerivedFromService(this); + } + // disable synchronous version of this method + ::grpc::Status IsTelemetryDisabled(::grpc::ServerContext* /*context*/, const ::google::protobuf::Empty* /*request*/, ::google::protobuf::BoolValue* /*response*/) override { + abort(); + return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); + } + virtual ::grpc::ServerUnaryReactor* IsTelemetryDisabled( + ::grpc::CallbackServerContext* /*context*/, const ::grpc::ByteBuffer* /*request*/, ::grpc::ByteBuffer* /*response*/) { return nullptr; } + }; + template class WithRawCallbackMethod_GoOs : public BaseClass { private: void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithRawCallbackMethod_GoOs() { - ::grpc::Service::MarkMethodRawCallback(12, + ::grpc::Service::MarkMethodRawCallback(14, new ::grpc::internal::CallbackUnaryHandler< ::grpc::ByteBuffer, ::grpc::ByteBuffer>( [this]( ::grpc::CallbackServerContext* context, const ::grpc::ByteBuffer* request, ::grpc::ByteBuffer* response) { return this->GoOs(context, request, response); })); @@ -6354,7 +6614,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithRawCallbackMethod_TriggerReset() { - ::grpc::Service::MarkMethodRawCallback(13, + ::grpc::Service::MarkMethodRawCallback(15, new ::grpc::internal::CallbackUnaryHandler< ::grpc::ByteBuffer, ::grpc::ByteBuffer>( [this]( ::grpc::CallbackServerContext* context, const ::grpc::ByteBuffer* request, ::grpc::ByteBuffer* response) { return this->TriggerReset(context, request, response); })); @@ -6376,7 +6636,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithRawCallbackMethod_Version() { - ::grpc::Service::MarkMethodRawCallback(14, + ::grpc::Service::MarkMethodRawCallback(16, new ::grpc::internal::CallbackUnaryHandler< ::grpc::ByteBuffer, ::grpc::ByteBuffer>( [this]( ::grpc::CallbackServerContext* context, const ::grpc::ByteBuffer* request, ::grpc::ByteBuffer* response) { return this->Version(context, request, response); })); @@ -6398,7 +6658,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithRawCallbackMethod_LogsPath() { - ::grpc::Service::MarkMethodRawCallback(15, + ::grpc::Service::MarkMethodRawCallback(17, new ::grpc::internal::CallbackUnaryHandler< ::grpc::ByteBuffer, ::grpc::ByteBuffer>( [this]( ::grpc::CallbackServerContext* context, const ::grpc::ByteBuffer* request, ::grpc::ByteBuffer* response) { return this->LogsPath(context, request, response); })); @@ -6420,7 +6680,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithRawCallbackMethod_LicensePath() { - ::grpc::Service::MarkMethodRawCallback(16, + ::grpc::Service::MarkMethodRawCallback(18, new ::grpc::internal::CallbackUnaryHandler< ::grpc::ByteBuffer, ::grpc::ByteBuffer>( [this]( ::grpc::CallbackServerContext* context, const ::grpc::ByteBuffer* request, ::grpc::ByteBuffer* response) { return this->LicensePath(context, request, response); })); @@ -6442,7 +6702,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithRawCallbackMethod_ReleaseNotesPageLink() { - ::grpc::Service::MarkMethodRawCallback(17, + ::grpc::Service::MarkMethodRawCallback(19, new ::grpc::internal::CallbackUnaryHandler< ::grpc::ByteBuffer, ::grpc::ByteBuffer>( [this]( ::grpc::CallbackServerContext* context, const ::grpc::ByteBuffer* request, ::grpc::ByteBuffer* response) { return this->ReleaseNotesPageLink(context, request, response); })); @@ -6464,7 +6724,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithRawCallbackMethod_DependencyLicensesLink() { - ::grpc::Service::MarkMethodRawCallback(18, + ::grpc::Service::MarkMethodRawCallback(20, new ::grpc::internal::CallbackUnaryHandler< ::grpc::ByteBuffer, ::grpc::ByteBuffer>( [this]( ::grpc::CallbackServerContext* context, const ::grpc::ByteBuffer* request, ::grpc::ByteBuffer* response) { return this->DependencyLicensesLink(context, request, response); })); @@ -6486,7 +6746,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithRawCallbackMethod_LandingPageLink() { - ::grpc::Service::MarkMethodRawCallback(19, + ::grpc::Service::MarkMethodRawCallback(21, new ::grpc::internal::CallbackUnaryHandler< ::grpc::ByteBuffer, ::grpc::ByteBuffer>( [this]( ::grpc::CallbackServerContext* context, const ::grpc::ByteBuffer* request, ::grpc::ByteBuffer* response) { return this->LandingPageLink(context, request, response); })); @@ -6508,7 +6768,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithRawCallbackMethod_SetColorSchemeName() { - ::grpc::Service::MarkMethodRawCallback(20, + ::grpc::Service::MarkMethodRawCallback(22, new ::grpc::internal::CallbackUnaryHandler< ::grpc::ByteBuffer, ::grpc::ByteBuffer>( [this]( ::grpc::CallbackServerContext* context, const ::grpc::ByteBuffer* request, ::grpc::ByteBuffer* response) { return this->SetColorSchemeName(context, request, response); })); @@ -6530,7 +6790,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithRawCallbackMethod_ColorSchemeName() { - ::grpc::Service::MarkMethodRawCallback(21, + ::grpc::Service::MarkMethodRawCallback(23, new ::grpc::internal::CallbackUnaryHandler< ::grpc::ByteBuffer, ::grpc::ByteBuffer>( [this]( ::grpc::CallbackServerContext* context, const ::grpc::ByteBuffer* request, ::grpc::ByteBuffer* response) { return this->ColorSchemeName(context, request, response); })); @@ -6552,7 +6812,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithRawCallbackMethod_CurrentEmailClient() { - ::grpc::Service::MarkMethodRawCallback(22, + ::grpc::Service::MarkMethodRawCallback(24, new ::grpc::internal::CallbackUnaryHandler< ::grpc::ByteBuffer, ::grpc::ByteBuffer>( [this]( ::grpc::CallbackServerContext* context, const ::grpc::ByteBuffer* request, ::grpc::ByteBuffer* response) { return this->CurrentEmailClient(context, request, response); })); @@ -6574,7 +6834,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithRawCallbackMethod_ReportBug() { - ::grpc::Service::MarkMethodRawCallback(23, + ::grpc::Service::MarkMethodRawCallback(25, new ::grpc::internal::CallbackUnaryHandler< ::grpc::ByteBuffer, ::grpc::ByteBuffer>( [this]( ::grpc::CallbackServerContext* context, const ::grpc::ByteBuffer* request, ::grpc::ByteBuffer* response) { return this->ReportBug(context, request, response); })); @@ -6596,7 +6856,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithRawCallbackMethod_ExportTLSCertificates() { - ::grpc::Service::MarkMethodRawCallback(24, + ::grpc::Service::MarkMethodRawCallback(26, new ::grpc::internal::CallbackUnaryHandler< ::grpc::ByteBuffer, ::grpc::ByteBuffer>( [this]( ::grpc::CallbackServerContext* context, const ::grpc::ByteBuffer* request, ::grpc::ByteBuffer* response) { return this->ExportTLSCertificates(context, request, response); })); @@ -6618,7 +6878,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithRawCallbackMethod_ForceLauncher() { - ::grpc::Service::MarkMethodRawCallback(25, + ::grpc::Service::MarkMethodRawCallback(27, new ::grpc::internal::CallbackUnaryHandler< ::grpc::ByteBuffer, ::grpc::ByteBuffer>( [this]( ::grpc::CallbackServerContext* context, const ::grpc::ByteBuffer* request, ::grpc::ByteBuffer* response) { return this->ForceLauncher(context, request, response); })); @@ -6640,7 +6900,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithRawCallbackMethod_SetMainExecutable() { - ::grpc::Service::MarkMethodRawCallback(26, + ::grpc::Service::MarkMethodRawCallback(28, new ::grpc::internal::CallbackUnaryHandler< ::grpc::ByteBuffer, ::grpc::ByteBuffer>( [this]( ::grpc::CallbackServerContext* context, const ::grpc::ByteBuffer* request, ::grpc::ByteBuffer* response) { return this->SetMainExecutable(context, request, response); })); @@ -6662,7 +6922,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithRawCallbackMethod_Login() { - ::grpc::Service::MarkMethodRawCallback(27, + ::grpc::Service::MarkMethodRawCallback(29, new ::grpc::internal::CallbackUnaryHandler< ::grpc::ByteBuffer, ::grpc::ByteBuffer>( [this]( ::grpc::CallbackServerContext* context, const ::grpc::ByteBuffer* request, ::grpc::ByteBuffer* response) { return this->Login(context, request, response); })); @@ -6684,7 +6944,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithRawCallbackMethod_Login2FA() { - ::grpc::Service::MarkMethodRawCallback(28, + ::grpc::Service::MarkMethodRawCallback(30, new ::grpc::internal::CallbackUnaryHandler< ::grpc::ByteBuffer, ::grpc::ByteBuffer>( [this]( ::grpc::CallbackServerContext* context, const ::grpc::ByteBuffer* request, ::grpc::ByteBuffer* response) { return this->Login2FA(context, request, response); })); @@ -6706,7 +6966,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithRawCallbackMethod_Login2Passwords() { - ::grpc::Service::MarkMethodRawCallback(29, + ::grpc::Service::MarkMethodRawCallback(31, new ::grpc::internal::CallbackUnaryHandler< ::grpc::ByteBuffer, ::grpc::ByteBuffer>( [this]( ::grpc::CallbackServerContext* context, const ::grpc::ByteBuffer* request, ::grpc::ByteBuffer* response) { return this->Login2Passwords(context, request, response); })); @@ -6728,7 +6988,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithRawCallbackMethod_LoginAbort() { - ::grpc::Service::MarkMethodRawCallback(30, + ::grpc::Service::MarkMethodRawCallback(32, new ::grpc::internal::CallbackUnaryHandler< ::grpc::ByteBuffer, ::grpc::ByteBuffer>( [this]( ::grpc::CallbackServerContext* context, const ::grpc::ByteBuffer* request, ::grpc::ByteBuffer* response) { return this->LoginAbort(context, request, response); })); @@ -6750,7 +7010,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithRawCallbackMethod_CheckUpdate() { - ::grpc::Service::MarkMethodRawCallback(31, + ::grpc::Service::MarkMethodRawCallback(33, new ::grpc::internal::CallbackUnaryHandler< ::grpc::ByteBuffer, ::grpc::ByteBuffer>( [this]( ::grpc::CallbackServerContext* context, const ::grpc::ByteBuffer* request, ::grpc::ByteBuffer* response) { return this->CheckUpdate(context, request, response); })); @@ -6772,7 +7032,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithRawCallbackMethod_InstallUpdate() { - ::grpc::Service::MarkMethodRawCallback(32, + ::grpc::Service::MarkMethodRawCallback(34, new ::grpc::internal::CallbackUnaryHandler< ::grpc::ByteBuffer, ::grpc::ByteBuffer>( [this]( ::grpc::CallbackServerContext* context, const ::grpc::ByteBuffer* request, ::grpc::ByteBuffer* response) { return this->InstallUpdate(context, request, response); })); @@ -6794,7 +7054,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithRawCallbackMethod_SetIsAutomaticUpdateOn() { - ::grpc::Service::MarkMethodRawCallback(33, + ::grpc::Service::MarkMethodRawCallback(35, new ::grpc::internal::CallbackUnaryHandler< ::grpc::ByteBuffer, ::grpc::ByteBuffer>( [this]( ::grpc::CallbackServerContext* context, const ::grpc::ByteBuffer* request, ::grpc::ByteBuffer* response) { return this->SetIsAutomaticUpdateOn(context, request, response); })); @@ -6816,7 +7076,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithRawCallbackMethod_IsAutomaticUpdateOn() { - ::grpc::Service::MarkMethodRawCallback(34, + ::grpc::Service::MarkMethodRawCallback(36, new ::grpc::internal::CallbackUnaryHandler< ::grpc::ByteBuffer, ::grpc::ByteBuffer>( [this]( ::grpc::CallbackServerContext* context, const ::grpc::ByteBuffer* request, ::grpc::ByteBuffer* response) { return this->IsAutomaticUpdateOn(context, request, response); })); @@ -6838,7 +7098,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithRawCallbackMethod_DiskCachePath() { - ::grpc::Service::MarkMethodRawCallback(35, + ::grpc::Service::MarkMethodRawCallback(37, new ::grpc::internal::CallbackUnaryHandler< ::grpc::ByteBuffer, ::grpc::ByteBuffer>( [this]( ::grpc::CallbackServerContext* context, const ::grpc::ByteBuffer* request, ::grpc::ByteBuffer* response) { return this->DiskCachePath(context, request, response); })); @@ -6860,7 +7120,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithRawCallbackMethod_SetDiskCachePath() { - ::grpc::Service::MarkMethodRawCallback(36, + ::grpc::Service::MarkMethodRawCallback(38, new ::grpc::internal::CallbackUnaryHandler< ::grpc::ByteBuffer, ::grpc::ByteBuffer>( [this]( ::grpc::CallbackServerContext* context, const ::grpc::ByteBuffer* request, ::grpc::ByteBuffer* response) { return this->SetDiskCachePath(context, request, response); })); @@ -6882,7 +7142,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithRawCallbackMethod_SetIsDoHEnabled() { - ::grpc::Service::MarkMethodRawCallback(37, + ::grpc::Service::MarkMethodRawCallback(39, new ::grpc::internal::CallbackUnaryHandler< ::grpc::ByteBuffer, ::grpc::ByteBuffer>( [this]( ::grpc::CallbackServerContext* context, const ::grpc::ByteBuffer* request, ::grpc::ByteBuffer* response) { return this->SetIsDoHEnabled(context, request, response); })); @@ -6904,7 +7164,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithRawCallbackMethod_IsDoHEnabled() { - ::grpc::Service::MarkMethodRawCallback(38, + ::grpc::Service::MarkMethodRawCallback(40, new ::grpc::internal::CallbackUnaryHandler< ::grpc::ByteBuffer, ::grpc::ByteBuffer>( [this]( ::grpc::CallbackServerContext* context, const ::grpc::ByteBuffer* request, ::grpc::ByteBuffer* response) { return this->IsDoHEnabled(context, request, response); })); @@ -6926,7 +7186,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithRawCallbackMethod_MailServerSettings() { - ::grpc::Service::MarkMethodRawCallback(39, + ::grpc::Service::MarkMethodRawCallback(41, new ::grpc::internal::CallbackUnaryHandler< ::grpc::ByteBuffer, ::grpc::ByteBuffer>( [this]( ::grpc::CallbackServerContext* context, const ::grpc::ByteBuffer* request, ::grpc::ByteBuffer* response) { return this->MailServerSettings(context, request, response); })); @@ -6948,7 +7208,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithRawCallbackMethod_SetMailServerSettings() { - ::grpc::Service::MarkMethodRawCallback(40, + ::grpc::Service::MarkMethodRawCallback(42, new ::grpc::internal::CallbackUnaryHandler< ::grpc::ByteBuffer, ::grpc::ByteBuffer>( [this]( ::grpc::CallbackServerContext* context, const ::grpc::ByteBuffer* request, ::grpc::ByteBuffer* response) { return this->SetMailServerSettings(context, request, response); })); @@ -6970,7 +7230,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithRawCallbackMethod_Hostname() { - ::grpc::Service::MarkMethodRawCallback(41, + ::grpc::Service::MarkMethodRawCallback(43, new ::grpc::internal::CallbackUnaryHandler< ::grpc::ByteBuffer, ::grpc::ByteBuffer>( [this]( ::grpc::CallbackServerContext* context, const ::grpc::ByteBuffer* request, ::grpc::ByteBuffer* response) { return this->Hostname(context, request, response); })); @@ -6992,7 +7252,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithRawCallbackMethod_IsPortFree() { - ::grpc::Service::MarkMethodRawCallback(42, + ::grpc::Service::MarkMethodRawCallback(44, new ::grpc::internal::CallbackUnaryHandler< ::grpc::ByteBuffer, ::grpc::ByteBuffer>( [this]( ::grpc::CallbackServerContext* context, const ::grpc::ByteBuffer* request, ::grpc::ByteBuffer* response) { return this->IsPortFree(context, request, response); })); @@ -7014,7 +7274,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithRawCallbackMethod_AvailableKeychains() { - ::grpc::Service::MarkMethodRawCallback(43, + ::grpc::Service::MarkMethodRawCallback(45, new ::grpc::internal::CallbackUnaryHandler< ::grpc::ByteBuffer, ::grpc::ByteBuffer>( [this]( ::grpc::CallbackServerContext* context, const ::grpc::ByteBuffer* request, ::grpc::ByteBuffer* response) { return this->AvailableKeychains(context, request, response); })); @@ -7036,7 +7296,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithRawCallbackMethod_SetCurrentKeychain() { - ::grpc::Service::MarkMethodRawCallback(44, + ::grpc::Service::MarkMethodRawCallback(46, new ::grpc::internal::CallbackUnaryHandler< ::grpc::ByteBuffer, ::grpc::ByteBuffer>( [this]( ::grpc::CallbackServerContext* context, const ::grpc::ByteBuffer* request, ::grpc::ByteBuffer* response) { return this->SetCurrentKeychain(context, request, response); })); @@ -7058,7 +7318,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithRawCallbackMethod_CurrentKeychain() { - ::grpc::Service::MarkMethodRawCallback(45, + ::grpc::Service::MarkMethodRawCallback(47, new ::grpc::internal::CallbackUnaryHandler< ::grpc::ByteBuffer, ::grpc::ByteBuffer>( [this]( ::grpc::CallbackServerContext* context, const ::grpc::ByteBuffer* request, ::grpc::ByteBuffer* response) { return this->CurrentKeychain(context, request, response); })); @@ -7080,7 +7340,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithRawCallbackMethod_GetUserList() { - ::grpc::Service::MarkMethodRawCallback(46, + ::grpc::Service::MarkMethodRawCallback(48, new ::grpc::internal::CallbackUnaryHandler< ::grpc::ByteBuffer, ::grpc::ByteBuffer>( [this]( ::grpc::CallbackServerContext* context, const ::grpc::ByteBuffer* request, ::grpc::ByteBuffer* response) { return this->GetUserList(context, request, response); })); @@ -7102,7 +7362,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithRawCallbackMethod_GetUser() { - ::grpc::Service::MarkMethodRawCallback(47, + ::grpc::Service::MarkMethodRawCallback(49, new ::grpc::internal::CallbackUnaryHandler< ::grpc::ByteBuffer, ::grpc::ByteBuffer>( [this]( ::grpc::CallbackServerContext* context, const ::grpc::ByteBuffer* request, ::grpc::ByteBuffer* response) { return this->GetUser(context, request, response); })); @@ -7124,7 +7384,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithRawCallbackMethod_SetUserSplitMode() { - ::grpc::Service::MarkMethodRawCallback(48, + ::grpc::Service::MarkMethodRawCallback(50, new ::grpc::internal::CallbackUnaryHandler< ::grpc::ByteBuffer, ::grpc::ByteBuffer>( [this]( ::grpc::CallbackServerContext* context, const ::grpc::ByteBuffer* request, ::grpc::ByteBuffer* response) { return this->SetUserSplitMode(context, request, response); })); @@ -7146,7 +7406,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithRawCallbackMethod_SendBadEventUserFeedback() { - ::grpc::Service::MarkMethodRawCallback(49, + ::grpc::Service::MarkMethodRawCallback(51, new ::grpc::internal::CallbackUnaryHandler< ::grpc::ByteBuffer, ::grpc::ByteBuffer>( [this]( ::grpc::CallbackServerContext* context, const ::grpc::ByteBuffer* request, ::grpc::ByteBuffer* response) { return this->SendBadEventUserFeedback(context, request, response); })); @@ -7168,7 +7428,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithRawCallbackMethod_LogoutUser() { - ::grpc::Service::MarkMethodRawCallback(50, + ::grpc::Service::MarkMethodRawCallback(52, new ::grpc::internal::CallbackUnaryHandler< ::grpc::ByteBuffer, ::grpc::ByteBuffer>( [this]( ::grpc::CallbackServerContext* context, const ::grpc::ByteBuffer* request, ::grpc::ByteBuffer* response) { return this->LogoutUser(context, request, response); })); @@ -7190,7 +7450,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithRawCallbackMethod_RemoveUser() { - ::grpc::Service::MarkMethodRawCallback(51, + ::grpc::Service::MarkMethodRawCallback(53, new ::grpc::internal::CallbackUnaryHandler< ::grpc::ByteBuffer, ::grpc::ByteBuffer>( [this]( ::grpc::CallbackServerContext* context, const ::grpc::ByteBuffer* request, ::grpc::ByteBuffer* response) { return this->RemoveUser(context, request, response); })); @@ -7212,7 +7472,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithRawCallbackMethod_ConfigureUserAppleMail() { - ::grpc::Service::MarkMethodRawCallback(52, + ::grpc::Service::MarkMethodRawCallback(54, new ::grpc::internal::CallbackUnaryHandler< ::grpc::ByteBuffer, ::grpc::ByteBuffer>( [this]( ::grpc::CallbackServerContext* context, const ::grpc::ByteBuffer* request, ::grpc::ByteBuffer* response) { return this->ConfigureUserAppleMail(context, request, response); })); @@ -7234,7 +7494,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithRawCallbackMethod_RunEventStream() { - ::grpc::Service::MarkMethodRawCallback(53, + ::grpc::Service::MarkMethodRawCallback(55, new ::grpc::internal::CallbackServerStreamingHandler< ::grpc::ByteBuffer, ::grpc::ByteBuffer>( [this]( ::grpc::CallbackServerContext* context, const::grpc::ByteBuffer* request) { return this->RunEventStream(context, request); })); @@ -7256,7 +7516,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithRawCallbackMethod_StopEventStream() { - ::grpc::Service::MarkMethodRawCallback(54, + ::grpc::Service::MarkMethodRawCallback(56, new ::grpc::internal::CallbackUnaryHandler< ::grpc::ByteBuffer, ::grpc::ByteBuffer>( [this]( ::grpc::CallbackServerContext* context, const ::grpc::ByteBuffer* request, ::grpc::ByteBuffer* response) { return this->StopEventStream(context, request, response); })); @@ -7597,12 +7857,66 @@ class Bridge final { virtual ::grpc::Status StreamedIsAllMailVisible(::grpc::ServerContext* context, ::grpc::ServerUnaryStreamer< ::google::protobuf::Empty,::google::protobuf::BoolValue>* server_unary_streamer) = 0; }; template + class WithStreamedUnaryMethod_SetIsTelemetryDisabled : public BaseClass { + private: + void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} + public: + WithStreamedUnaryMethod_SetIsTelemetryDisabled() { + ::grpc::Service::MarkMethodStreamed(12, + new ::grpc::internal::StreamedUnaryHandler< + ::google::protobuf::BoolValue, ::google::protobuf::Empty>( + [this](::grpc::ServerContext* context, + ::grpc::ServerUnaryStreamer< + ::google::protobuf::BoolValue, ::google::protobuf::Empty>* streamer) { + return this->StreamedSetIsTelemetryDisabled(context, + streamer); + })); + } + ~WithStreamedUnaryMethod_SetIsTelemetryDisabled() override { + BaseClassMustBeDerivedFromService(this); + } + // disable regular version of this method + ::grpc::Status SetIsTelemetryDisabled(::grpc::ServerContext* /*context*/, const ::google::protobuf::BoolValue* /*request*/, ::google::protobuf::Empty* /*response*/) override { + abort(); + return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); + } + // replace default version of method with streamed unary + virtual ::grpc::Status StreamedSetIsTelemetryDisabled(::grpc::ServerContext* context, ::grpc::ServerUnaryStreamer< ::google::protobuf::BoolValue,::google::protobuf::Empty>* server_unary_streamer) = 0; + }; + template + class WithStreamedUnaryMethod_IsTelemetryDisabled : public BaseClass { + private: + void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} + public: + WithStreamedUnaryMethod_IsTelemetryDisabled() { + ::grpc::Service::MarkMethodStreamed(13, + new ::grpc::internal::StreamedUnaryHandler< + ::google::protobuf::Empty, ::google::protobuf::BoolValue>( + [this](::grpc::ServerContext* context, + ::grpc::ServerUnaryStreamer< + ::google::protobuf::Empty, ::google::protobuf::BoolValue>* streamer) { + return this->StreamedIsTelemetryDisabled(context, + streamer); + })); + } + ~WithStreamedUnaryMethod_IsTelemetryDisabled() override { + BaseClassMustBeDerivedFromService(this); + } + // disable regular version of this method + ::grpc::Status IsTelemetryDisabled(::grpc::ServerContext* /*context*/, const ::google::protobuf::Empty* /*request*/, ::google::protobuf::BoolValue* /*response*/) override { + abort(); + return ::grpc::Status(::grpc::StatusCode::UNIMPLEMENTED, ""); + } + // replace default version of method with streamed unary + virtual ::grpc::Status StreamedIsTelemetryDisabled(::grpc::ServerContext* context, ::grpc::ServerUnaryStreamer< ::google::protobuf::Empty,::google::protobuf::BoolValue>* server_unary_streamer) = 0; + }; + template class WithStreamedUnaryMethod_GoOs : public BaseClass { private: void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithStreamedUnaryMethod_GoOs() { - ::grpc::Service::MarkMethodStreamed(12, + ::grpc::Service::MarkMethodStreamed(14, new ::grpc::internal::StreamedUnaryHandler< ::google::protobuf::Empty, ::google::protobuf::StringValue>( [this](::grpc::ServerContext* context, @@ -7629,7 +7943,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithStreamedUnaryMethod_TriggerReset() { - ::grpc::Service::MarkMethodStreamed(13, + ::grpc::Service::MarkMethodStreamed(15, new ::grpc::internal::StreamedUnaryHandler< ::google::protobuf::Empty, ::google::protobuf::Empty>( [this](::grpc::ServerContext* context, @@ -7656,7 +7970,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithStreamedUnaryMethod_Version() { - ::grpc::Service::MarkMethodStreamed(14, + ::grpc::Service::MarkMethodStreamed(16, new ::grpc::internal::StreamedUnaryHandler< ::google::protobuf::Empty, ::google::protobuf::StringValue>( [this](::grpc::ServerContext* context, @@ -7683,7 +7997,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithStreamedUnaryMethod_LogsPath() { - ::grpc::Service::MarkMethodStreamed(15, + ::grpc::Service::MarkMethodStreamed(17, new ::grpc::internal::StreamedUnaryHandler< ::google::protobuf::Empty, ::google::protobuf::StringValue>( [this](::grpc::ServerContext* context, @@ -7710,7 +8024,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithStreamedUnaryMethod_LicensePath() { - ::grpc::Service::MarkMethodStreamed(16, + ::grpc::Service::MarkMethodStreamed(18, new ::grpc::internal::StreamedUnaryHandler< ::google::protobuf::Empty, ::google::protobuf::StringValue>( [this](::grpc::ServerContext* context, @@ -7737,7 +8051,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithStreamedUnaryMethod_ReleaseNotesPageLink() { - ::grpc::Service::MarkMethodStreamed(17, + ::grpc::Service::MarkMethodStreamed(19, new ::grpc::internal::StreamedUnaryHandler< ::google::protobuf::Empty, ::google::protobuf::StringValue>( [this](::grpc::ServerContext* context, @@ -7764,7 +8078,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithStreamedUnaryMethod_DependencyLicensesLink() { - ::grpc::Service::MarkMethodStreamed(18, + ::grpc::Service::MarkMethodStreamed(20, new ::grpc::internal::StreamedUnaryHandler< ::google::protobuf::Empty, ::google::protobuf::StringValue>( [this](::grpc::ServerContext* context, @@ -7791,7 +8105,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithStreamedUnaryMethod_LandingPageLink() { - ::grpc::Service::MarkMethodStreamed(19, + ::grpc::Service::MarkMethodStreamed(21, new ::grpc::internal::StreamedUnaryHandler< ::google::protobuf::Empty, ::google::protobuf::StringValue>( [this](::grpc::ServerContext* context, @@ -7818,7 +8132,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithStreamedUnaryMethod_SetColorSchemeName() { - ::grpc::Service::MarkMethodStreamed(20, + ::grpc::Service::MarkMethodStreamed(22, new ::grpc::internal::StreamedUnaryHandler< ::google::protobuf::StringValue, ::google::protobuf::Empty>( [this](::grpc::ServerContext* context, @@ -7845,7 +8159,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithStreamedUnaryMethod_ColorSchemeName() { - ::grpc::Service::MarkMethodStreamed(21, + ::grpc::Service::MarkMethodStreamed(23, new ::grpc::internal::StreamedUnaryHandler< ::google::protobuf::Empty, ::google::protobuf::StringValue>( [this](::grpc::ServerContext* context, @@ -7872,7 +8186,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithStreamedUnaryMethod_CurrentEmailClient() { - ::grpc::Service::MarkMethodStreamed(22, + ::grpc::Service::MarkMethodStreamed(24, new ::grpc::internal::StreamedUnaryHandler< ::google::protobuf::Empty, ::google::protobuf::StringValue>( [this](::grpc::ServerContext* context, @@ -7899,7 +8213,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithStreamedUnaryMethod_ReportBug() { - ::grpc::Service::MarkMethodStreamed(23, + ::grpc::Service::MarkMethodStreamed(25, new ::grpc::internal::StreamedUnaryHandler< ::grpc::ReportBugRequest, ::google::protobuf::Empty>( [this](::grpc::ServerContext* context, @@ -7926,7 +8240,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithStreamedUnaryMethod_ExportTLSCertificates() { - ::grpc::Service::MarkMethodStreamed(24, + ::grpc::Service::MarkMethodStreamed(26, new ::grpc::internal::StreamedUnaryHandler< ::google::protobuf::StringValue, ::google::protobuf::Empty>( [this](::grpc::ServerContext* context, @@ -7953,7 +8267,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithStreamedUnaryMethod_ForceLauncher() { - ::grpc::Service::MarkMethodStreamed(25, + ::grpc::Service::MarkMethodStreamed(27, new ::grpc::internal::StreamedUnaryHandler< ::google::protobuf::StringValue, ::google::protobuf::Empty>( [this](::grpc::ServerContext* context, @@ -7980,7 +8294,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithStreamedUnaryMethod_SetMainExecutable() { - ::grpc::Service::MarkMethodStreamed(26, + ::grpc::Service::MarkMethodStreamed(28, new ::grpc::internal::StreamedUnaryHandler< ::google::protobuf::StringValue, ::google::protobuf::Empty>( [this](::grpc::ServerContext* context, @@ -8007,7 +8321,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithStreamedUnaryMethod_Login() { - ::grpc::Service::MarkMethodStreamed(27, + ::grpc::Service::MarkMethodStreamed(29, new ::grpc::internal::StreamedUnaryHandler< ::grpc::LoginRequest, ::google::protobuf::Empty>( [this](::grpc::ServerContext* context, @@ -8034,7 +8348,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithStreamedUnaryMethod_Login2FA() { - ::grpc::Service::MarkMethodStreamed(28, + ::grpc::Service::MarkMethodStreamed(30, new ::grpc::internal::StreamedUnaryHandler< ::grpc::LoginRequest, ::google::protobuf::Empty>( [this](::grpc::ServerContext* context, @@ -8061,7 +8375,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithStreamedUnaryMethod_Login2Passwords() { - ::grpc::Service::MarkMethodStreamed(29, + ::grpc::Service::MarkMethodStreamed(31, new ::grpc::internal::StreamedUnaryHandler< ::grpc::LoginRequest, ::google::protobuf::Empty>( [this](::grpc::ServerContext* context, @@ -8088,7 +8402,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithStreamedUnaryMethod_LoginAbort() { - ::grpc::Service::MarkMethodStreamed(30, + ::grpc::Service::MarkMethodStreamed(32, new ::grpc::internal::StreamedUnaryHandler< ::grpc::LoginAbortRequest, ::google::protobuf::Empty>( [this](::grpc::ServerContext* context, @@ -8115,7 +8429,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithStreamedUnaryMethod_CheckUpdate() { - ::grpc::Service::MarkMethodStreamed(31, + ::grpc::Service::MarkMethodStreamed(33, new ::grpc::internal::StreamedUnaryHandler< ::google::protobuf::Empty, ::google::protobuf::Empty>( [this](::grpc::ServerContext* context, @@ -8142,7 +8456,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithStreamedUnaryMethod_InstallUpdate() { - ::grpc::Service::MarkMethodStreamed(32, + ::grpc::Service::MarkMethodStreamed(34, new ::grpc::internal::StreamedUnaryHandler< ::google::protobuf::Empty, ::google::protobuf::Empty>( [this](::grpc::ServerContext* context, @@ -8169,7 +8483,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithStreamedUnaryMethod_SetIsAutomaticUpdateOn() { - ::grpc::Service::MarkMethodStreamed(33, + ::grpc::Service::MarkMethodStreamed(35, new ::grpc::internal::StreamedUnaryHandler< ::google::protobuf::BoolValue, ::google::protobuf::Empty>( [this](::grpc::ServerContext* context, @@ -8196,7 +8510,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithStreamedUnaryMethod_IsAutomaticUpdateOn() { - ::grpc::Service::MarkMethodStreamed(34, + ::grpc::Service::MarkMethodStreamed(36, new ::grpc::internal::StreamedUnaryHandler< ::google::protobuf::Empty, ::google::protobuf::BoolValue>( [this](::grpc::ServerContext* context, @@ -8223,7 +8537,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithStreamedUnaryMethod_DiskCachePath() { - ::grpc::Service::MarkMethodStreamed(35, + ::grpc::Service::MarkMethodStreamed(37, new ::grpc::internal::StreamedUnaryHandler< ::google::protobuf::Empty, ::google::protobuf::StringValue>( [this](::grpc::ServerContext* context, @@ -8250,7 +8564,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithStreamedUnaryMethod_SetDiskCachePath() { - ::grpc::Service::MarkMethodStreamed(36, + ::grpc::Service::MarkMethodStreamed(38, new ::grpc::internal::StreamedUnaryHandler< ::google::protobuf::StringValue, ::google::protobuf::Empty>( [this](::grpc::ServerContext* context, @@ -8277,7 +8591,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithStreamedUnaryMethod_SetIsDoHEnabled() { - ::grpc::Service::MarkMethodStreamed(37, + ::grpc::Service::MarkMethodStreamed(39, new ::grpc::internal::StreamedUnaryHandler< ::google::protobuf::BoolValue, ::google::protobuf::Empty>( [this](::grpc::ServerContext* context, @@ -8304,7 +8618,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithStreamedUnaryMethod_IsDoHEnabled() { - ::grpc::Service::MarkMethodStreamed(38, + ::grpc::Service::MarkMethodStreamed(40, new ::grpc::internal::StreamedUnaryHandler< ::google::protobuf::Empty, ::google::protobuf::BoolValue>( [this](::grpc::ServerContext* context, @@ -8331,7 +8645,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithStreamedUnaryMethod_MailServerSettings() { - ::grpc::Service::MarkMethodStreamed(39, + ::grpc::Service::MarkMethodStreamed(41, new ::grpc::internal::StreamedUnaryHandler< ::google::protobuf::Empty, ::grpc::ImapSmtpSettings>( [this](::grpc::ServerContext* context, @@ -8358,7 +8672,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithStreamedUnaryMethod_SetMailServerSettings() { - ::grpc::Service::MarkMethodStreamed(40, + ::grpc::Service::MarkMethodStreamed(42, new ::grpc::internal::StreamedUnaryHandler< ::grpc::ImapSmtpSettings, ::google::protobuf::Empty>( [this](::grpc::ServerContext* context, @@ -8385,7 +8699,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithStreamedUnaryMethod_Hostname() { - ::grpc::Service::MarkMethodStreamed(41, + ::grpc::Service::MarkMethodStreamed(43, new ::grpc::internal::StreamedUnaryHandler< ::google::protobuf::Empty, ::google::protobuf::StringValue>( [this](::grpc::ServerContext* context, @@ -8412,7 +8726,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithStreamedUnaryMethod_IsPortFree() { - ::grpc::Service::MarkMethodStreamed(42, + ::grpc::Service::MarkMethodStreamed(44, new ::grpc::internal::StreamedUnaryHandler< ::google::protobuf::Int32Value, ::google::protobuf::BoolValue>( [this](::grpc::ServerContext* context, @@ -8439,7 +8753,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithStreamedUnaryMethod_AvailableKeychains() { - ::grpc::Service::MarkMethodStreamed(43, + ::grpc::Service::MarkMethodStreamed(45, new ::grpc::internal::StreamedUnaryHandler< ::google::protobuf::Empty, ::grpc::AvailableKeychainsResponse>( [this](::grpc::ServerContext* context, @@ -8466,7 +8780,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithStreamedUnaryMethod_SetCurrentKeychain() { - ::grpc::Service::MarkMethodStreamed(44, + ::grpc::Service::MarkMethodStreamed(46, new ::grpc::internal::StreamedUnaryHandler< ::google::protobuf::StringValue, ::google::protobuf::Empty>( [this](::grpc::ServerContext* context, @@ -8493,7 +8807,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithStreamedUnaryMethod_CurrentKeychain() { - ::grpc::Service::MarkMethodStreamed(45, + ::grpc::Service::MarkMethodStreamed(47, new ::grpc::internal::StreamedUnaryHandler< ::google::protobuf::Empty, ::google::protobuf::StringValue>( [this](::grpc::ServerContext* context, @@ -8520,7 +8834,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithStreamedUnaryMethod_GetUserList() { - ::grpc::Service::MarkMethodStreamed(46, + ::grpc::Service::MarkMethodStreamed(48, new ::grpc::internal::StreamedUnaryHandler< ::google::protobuf::Empty, ::grpc::UserListResponse>( [this](::grpc::ServerContext* context, @@ -8547,7 +8861,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithStreamedUnaryMethod_GetUser() { - ::grpc::Service::MarkMethodStreamed(47, + ::grpc::Service::MarkMethodStreamed(49, new ::grpc::internal::StreamedUnaryHandler< ::google::protobuf::StringValue, ::grpc::User>( [this](::grpc::ServerContext* context, @@ -8574,7 +8888,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithStreamedUnaryMethod_SetUserSplitMode() { - ::grpc::Service::MarkMethodStreamed(48, + ::grpc::Service::MarkMethodStreamed(50, new ::grpc::internal::StreamedUnaryHandler< ::grpc::UserSplitModeRequest, ::google::protobuf::Empty>( [this](::grpc::ServerContext* context, @@ -8601,7 +8915,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithStreamedUnaryMethod_SendBadEventUserFeedback() { - ::grpc::Service::MarkMethodStreamed(49, + ::grpc::Service::MarkMethodStreamed(51, new ::grpc::internal::StreamedUnaryHandler< ::grpc::UserBadEventFeedbackRequest, ::google::protobuf::Empty>( [this](::grpc::ServerContext* context, @@ -8628,7 +8942,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithStreamedUnaryMethod_LogoutUser() { - ::grpc::Service::MarkMethodStreamed(50, + ::grpc::Service::MarkMethodStreamed(52, new ::grpc::internal::StreamedUnaryHandler< ::google::protobuf::StringValue, ::google::protobuf::Empty>( [this](::grpc::ServerContext* context, @@ -8655,7 +8969,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithStreamedUnaryMethod_RemoveUser() { - ::grpc::Service::MarkMethodStreamed(51, + ::grpc::Service::MarkMethodStreamed(53, new ::grpc::internal::StreamedUnaryHandler< ::google::protobuf::StringValue, ::google::protobuf::Empty>( [this](::grpc::ServerContext* context, @@ -8682,7 +8996,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithStreamedUnaryMethod_ConfigureUserAppleMail() { - ::grpc::Service::MarkMethodStreamed(52, + ::grpc::Service::MarkMethodStreamed(54, new ::grpc::internal::StreamedUnaryHandler< ::grpc::ConfigureAppleMailRequest, ::google::protobuf::Empty>( [this](::grpc::ServerContext* context, @@ -8709,7 +9023,7 @@ class Bridge final { void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithStreamedUnaryMethod_StopEventStream() { - ::grpc::Service::MarkMethodStreamed(54, + ::grpc::Service::MarkMethodStreamed(56, new ::grpc::internal::StreamedUnaryHandler< ::google::protobuf::Empty, ::google::protobuf::Empty>( [this](::grpc::ServerContext* context, @@ -8730,14 +9044,14 @@ class Bridge final { // replace default version of method with streamed unary virtual ::grpc::Status StreamedStopEventStream(::grpc::ServerContext* context, ::grpc::ServerUnaryStreamer< ::google::protobuf::Empty,::google::protobuf::Empty>* server_unary_streamer) = 0; }; - typedef WithStreamedUnaryMethod_CheckTokens > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > StreamedUnaryService; + typedef WithStreamedUnaryMethod_CheckTokens > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > StreamedUnaryService; template class WithSplitStreamingMethod_RunEventStream : public BaseClass { private: void BaseClassMustBeDerivedFromService(const Service* /*service*/) {} public: WithSplitStreamingMethod_RunEventStream() { - ::grpc::Service::MarkMethodStreamed(53, + ::grpc::Service::MarkMethodStreamed(55, new ::grpc::internal::SplitServerStreamingHandler< ::grpc::EventStreamRequest, ::grpc::StreamEvent>( [this](::grpc::ServerContext* context, @@ -8759,7 +9073,7 @@ class Bridge final { virtual ::grpc::Status StreamedRunEventStream(::grpc::ServerContext* context, ::grpc::ServerSplitStreamer< ::grpc::EventStreamRequest,::grpc::StreamEvent>* server_split_streamer) = 0; }; typedef WithSplitStreamingMethod_RunEventStream SplitStreamedService; - typedef WithStreamedUnaryMethod_CheckTokens > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > StreamedService; + typedef WithStreamedUnaryMethod_CheckTokens > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > StreamedService; }; } // namespace grpc diff --git a/internal/frontend/bridge-gui/bridgepp/bridgepp/GRPC/bridge.pb.cc b/internal/frontend/bridge-gui/bridgepp/bridgepp/GRPC/bridge.pb.cc index eabd0aae..9d8a5043 100644 --- a/internal/frontend/bridge-gui/bridgepp/bridgepp/GRPC/bridge.pb.cc +++ b/internal/frontend/bridge-gui/bridgepp/bridgepp/GRPC/bridge.pb.cc @@ -1673,7 +1673,7 @@ const char descriptor_table_protodef_bridge_2eproto[] PROTOBUF_SECTION_VARIABLE( "!SMTP_CONNECTION_MODE_CHANGE_ERROR\020\005*S\n\t" "ErrorCode\022\021\n\rUNKNOWN_ERROR\020\000\022\031\n\025TLS_CERT" "_EXPORT_ERROR\020\001\022\030\n\024TLS_KEY_EXPORT_ERROR\020" - "\0022\360\035\n\006Bridge\022I\n\013CheckTokens\022\034.google.pro" + "\0022\211\037\n\006Bridge\022I\n\013CheckTokens\022\034.google.pro" "tobuf.StringValue\032\034.google.protobuf.Stri" "ngValue\022\?\n\013AddLogEntry\022\030.grpc.AddLogEntr" "yRequest\032\026.google.protobuf.Empty\022:\n\010GuiR" @@ -1693,84 +1693,88 @@ const char descriptor_table_protodef_bridge_2eproto[] PROTOBUF_SECTION_VARIABLE( "\n\023SetIsAllMailVisible\022\032.google.protobuf." "BoolValue\032\026.google.protobuf.Empty\022F\n\020IsA" "llMailVisible\022\026.google.protobuf.Empty\032\032." - "google.protobuf.BoolValue\022<\n\004GoOs\022\026.goog" - "le.protobuf.Empty\032\034.google.protobuf.Stri" - "ngValue\022>\n\014TriggerReset\022\026.google.protobu" - "f.Empty\032\026.google.protobuf.Empty\022\?\n\007Versi" - "on\022\026.google.protobuf.Empty\032\034.google.prot" - "obuf.StringValue\022@\n\010LogsPath\022\026.google.pr" - "otobuf.Empty\032\034.google.protobuf.StringVal" - "ue\022C\n\013LicensePath\022\026.google.protobuf.Empt" - "y\032\034.google.protobuf.StringValue\022L\n\024Relea" - "seNotesPageLink\022\026.google.protobuf.Empty\032" - "\034.google.protobuf.StringValue\022N\n\026Depende" - "ncyLicensesLink\022\026.google.protobuf.Empty\032" - "\034.google.protobuf.StringValue\022G\n\017Landing" - "PageLink\022\026.google.protobuf.Empty\032\034.googl" - "e.protobuf.StringValue\022J\n\022SetColorScheme" - "Name\022\034.google.protobuf.StringValue\032\026.goo" - "gle.protobuf.Empty\022G\n\017ColorSchemeName\022\026." - "google.protobuf.Empty\032\034.google.protobuf." - "StringValue\022J\n\022CurrentEmailClient\022\026.goog" - "le.protobuf.Empty\032\034.google.protobuf.Stri" - "ngValue\022;\n\tReportBug\022\026.grpc.ReportBugReq" - "uest\032\026.google.protobuf.Empty\022M\n\025ExportTL" - "SCertificates\022\034.google.protobuf.StringVa" - "lue\032\026.google.protobuf.Empty\022E\n\rForceLaun" - "cher\022\034.google.protobuf.StringValue\032\026.goo" - "gle.protobuf.Empty\022I\n\021SetMainExecutable\022" - "\034.google.protobuf.StringValue\032\026.google.p" - "rotobuf.Empty\0223\n\005Login\022\022.grpc.LoginReque" - "st\032\026.google.protobuf.Empty\0226\n\010Login2FA\022\022" - ".grpc.LoginRequest\032\026.google.protobuf.Emp" - "ty\022=\n\017Login2Passwords\022\022.grpc.LoginReques" - "t\032\026.google.protobuf.Empty\022=\n\nLoginAbort\022" - "\027.grpc.LoginAbortRequest\032\026.google.protob" - "uf.Empty\022=\n\013CheckUpdate\022\026.google.protobu" - "f.Empty\032\026.google.protobuf.Empty\022\?\n\rInsta" - "llUpdate\022\026.google.protobuf.Empty\032\026.googl" - "e.protobuf.Empty\022L\n\026SetIsAutomaticUpdate" - "On\022\032.google.protobuf.BoolValue\032\026.google." - "protobuf.Empty\022I\n\023IsAutomaticUpdateOn\022\026." - "google.protobuf.Empty\032\032.google.protobuf." - "BoolValue\022E\n\rDiskCachePath\022\026.google.prot" + "google.protobuf.BoolValue\022L\n\026SetIsTeleme" + "tryDisabled\022\032.google.protobuf.BoolValue\032" + "\026.google.protobuf.Empty\022I\n\023IsTelemetryDi" + "sabled\022\026.google.protobuf.Empty\032\032.google." + "protobuf.BoolValue\022<\n\004GoOs\022\026.google.prot" "obuf.Empty\032\034.google.protobuf.StringValue" - "\022H\n\020SetDiskCachePath\022\034.google.protobuf.S" - "tringValue\032\026.google.protobuf.Empty\022E\n\017Se" - "tIsDoHEnabled\022\032.google.protobuf.BoolValu" - "e\032\026.google.protobuf.Empty\022B\n\014IsDoHEnable" - "d\022\026.google.protobuf.Empty\032\032.google.proto" - "buf.BoolValue\022D\n\022MailServerSettings\022\026.go" - "ogle.protobuf.Empty\032\026.grpc.ImapSmtpSetti" - "ngs\022G\n\025SetMailServerSettings\022\026.grpc.Imap" - "SmtpSettings\032\026.google.protobuf.Empty\022@\n\010" - "Hostname\022\026.google.protobuf.Empty\032\034.googl" - "e.protobuf.StringValue\022E\n\nIsPortFree\022\033.g" - "oogle.protobuf.Int32Value\032\032.google.proto" - "buf.BoolValue\022N\n\022AvailableKeychains\022\026.go" - "ogle.protobuf.Empty\032 .grpc.AvailableKeyc" - "hainsResponse\022J\n\022SetCurrentKeychain\022\034.go" - "ogle.protobuf.StringValue\032\026.google.proto" - "buf.Empty\022G\n\017CurrentKeychain\022\026.google.pr" - "otobuf.Empty\032\034.google.protobuf.StringVal" - "ue\022=\n\013GetUserList\022\026.google.protobuf.Empt" - "y\032\026.grpc.UserListResponse\0223\n\007GetUser\022\034.g" - "oogle.protobuf.StringValue\032\n.grpc.User\022F" - "\n\020SetUserSplitMode\022\032.grpc.UserSplitModeR" - "equest\032\026.google.protobuf.Empty\022U\n\030SendBa" - "dEventUserFeedback\022!.grpc.UserBadEventFe" - "edbackRequest\032\026.google.protobuf.Empty\022B\n" - "\nLogoutUser\022\034.google.protobuf.StringValu" - "e\032\026.google.protobuf.Empty\022B\n\nRemoveUser\022" - "\034.google.protobuf.StringValue\032\026.google.p" - "rotobuf.Empty\022Q\n\026ConfigureUserAppleMail\022" - "\037.grpc.ConfigureAppleMailRequest\032\026.googl" - "e.protobuf.Empty\022\?\n\016RunEventStream\022\030.grp" - "c.EventStreamRequest\032\021.grpc.StreamEvent0" - "\001\022A\n\017StopEventStream\022\026.google.protobuf.E" - "mpty\032\026.google.protobuf.EmptyB6Z4github.c" - "om/ProtonMail/proton-bridge/v3/internal/" - "grpcb\006proto3" + "\022>\n\014TriggerReset\022\026.google.protobuf.Empty" + "\032\026.google.protobuf.Empty\022\?\n\007Version\022\026.go" + "ogle.protobuf.Empty\032\034.google.protobuf.St" + "ringValue\022@\n\010LogsPath\022\026.google.protobuf." + "Empty\032\034.google.protobuf.StringValue\022C\n\013L" + "icensePath\022\026.google.protobuf.Empty\032\034.goo" + "gle.protobuf.StringValue\022L\n\024ReleaseNotes" + "PageLink\022\026.google.protobuf.Empty\032\034.googl" + "e.protobuf.StringValue\022N\n\026DependencyLice" + "nsesLink\022\026.google.protobuf.Empty\032\034.googl" + "e.protobuf.StringValue\022G\n\017LandingPageLin" + "k\022\026.google.protobuf.Empty\032\034.google.proto" + "buf.StringValue\022J\n\022SetColorSchemeName\022\034." + "google.protobuf.StringValue\032\026.google.pro" + "tobuf.Empty\022G\n\017ColorSchemeName\022\026.google." + "protobuf.Empty\032\034.google.protobuf.StringV" + "alue\022J\n\022CurrentEmailClient\022\026.google.prot" + "obuf.Empty\032\034.google.protobuf.StringValue" + "\022;\n\tReportBug\022\026.grpc.ReportBugRequest\032\026." + "google.protobuf.Empty\022M\n\025ExportTLSCertif" + "icates\022\034.google.protobuf.StringValue\032\026.g" + "oogle.protobuf.Empty\022E\n\rForceLauncher\022\034." + "google.protobuf.StringValue\032\026.google.pro" + "tobuf.Empty\022I\n\021SetMainExecutable\022\034.googl" + "e.protobuf.StringValue\032\026.google.protobuf" + ".Empty\0223\n\005Login\022\022.grpc.LoginRequest\032\026.go" + "ogle.protobuf.Empty\0226\n\010Login2FA\022\022.grpc.L" + "oginRequest\032\026.google.protobuf.Empty\022=\n\017L" + "ogin2Passwords\022\022.grpc.LoginRequest\032\026.goo" + "gle.protobuf.Empty\022=\n\nLoginAbort\022\027.grpc." + "LoginAbortRequest\032\026.google.protobuf.Empt" + "y\022=\n\013CheckUpdate\022\026.google.protobuf.Empty" + "\032\026.google.protobuf.Empty\022\?\n\rInstallUpdat" + "e\022\026.google.protobuf.Empty\032\026.google.proto" + "buf.Empty\022L\n\026SetIsAutomaticUpdateOn\022\032.go" + "ogle.protobuf.BoolValue\032\026.google.protobu" + "f.Empty\022I\n\023IsAutomaticUpdateOn\022\026.google." + "protobuf.Empty\032\032.google.protobuf.BoolVal" + "ue\022E\n\rDiskCachePath\022\026.google.protobuf.Em" + "pty\032\034.google.protobuf.StringValue\022H\n\020Set" + "DiskCachePath\022\034.google.protobuf.StringVa" + "lue\032\026.google.protobuf.Empty\022E\n\017SetIsDoHE" + "nabled\022\032.google.protobuf.BoolValue\032\026.goo" + "gle.protobuf.Empty\022B\n\014IsDoHEnabled\022\026.goo" + "gle.protobuf.Empty\032\032.google.protobuf.Boo" + "lValue\022D\n\022MailServerSettings\022\026.google.pr" + "otobuf.Empty\032\026.grpc.ImapSmtpSettings\022G\n\025" + "SetMailServerSettings\022\026.grpc.ImapSmtpSet" + "tings\032\026.google.protobuf.Empty\022@\n\010Hostnam" + "e\022\026.google.protobuf.Empty\032\034.google.proto" + "buf.StringValue\022E\n\nIsPortFree\022\033.google.p" + "rotobuf.Int32Value\032\032.google.protobuf.Boo" + "lValue\022N\n\022AvailableKeychains\022\026.google.pr" + "otobuf.Empty\032 .grpc.AvailableKeychainsRe" + "sponse\022J\n\022SetCurrentKeychain\022\034.google.pr" + "otobuf.StringValue\032\026.google.protobuf.Emp" + "ty\022G\n\017CurrentKeychain\022\026.google.protobuf." + "Empty\032\034.google.protobuf.StringValue\022=\n\013G" + "etUserList\022\026.google.protobuf.Empty\032\026.grp" + "c.UserListResponse\0223\n\007GetUser\022\034.google.p" + "rotobuf.StringValue\032\n.grpc.User\022F\n\020SetUs" + "erSplitMode\022\032.grpc.UserSplitModeRequest\032" + "\026.google.protobuf.Empty\022U\n\030SendBadEventU" + "serFeedback\022!.grpc.UserBadEventFeedbackR" + "equest\032\026.google.protobuf.Empty\022B\n\nLogout" + "User\022\034.google.protobuf.StringValue\032\026.goo" + "gle.protobuf.Empty\022B\n\nRemoveUser\022\034.googl" + "e.protobuf.StringValue\032\026.google.protobuf" + ".Empty\022Q\n\026ConfigureUserAppleMail\022\037.grpc." + "ConfigureAppleMailRequest\032\026.google.proto" + "buf.Empty\022\?\n\016RunEventStream\022\030.grpc.Event" + "StreamRequest\032\021.grpc.StreamEvent0\001\022A\n\017St" + "opEventStream\022\026.google.protobuf.Empty\032\026." + "google.protobuf.EmptyB6Z4github.com/Prot" + "onMail/proton-bridge/v3/internal/grpcb\006p" + "roto3" ; static const ::_pbi::DescriptorTable* const descriptor_table_bridge_2eproto_deps[2] = { &::descriptor_table_google_2fprotobuf_2fempty_2eproto, @@ -1778,7 +1782,7 @@ static const ::_pbi::DescriptorTable* const descriptor_table_bridge_2eproto_deps }; static ::_pbi::once_flag descriptor_table_bridge_2eproto_once; const ::_pbi::DescriptorTable descriptor_table_bridge_2eproto = { - false, false, 10532, descriptor_table_protodef_bridge_2eproto, + false, false, 10685, descriptor_table_protodef_bridge_2eproto, "bridge.proto", &descriptor_table_bridge_2eproto_once, descriptor_table_bridge_2eproto_deps, 2, 64, schemas, file_default_instances, TableStruct_bridge_2eproto::offsets, diff --git a/internal/frontend/bridge-gui/bridgepp/bridgepp/Log/LogUtils.cpp b/internal/frontend/bridge-gui/bridgepp/bridgepp/Log/LogUtils.cpp index ee3780b2..eb825792 100644 --- a/internal/frontend/bridge-gui/bridgepp/bridgepp/Log/LogUtils.cpp +++ b/internal/frontend/bridge-gui/bridgepp/bridgepp/Log/LogUtils.cpp @@ -17,8 +17,8 @@ #include "LogUtils.h" -#include -#include +#include "../BridgeUtils.h" +#include "../Exception/Exception.h" namespace bridgepp { diff --git a/internal/frontend/cli/frontend.go b/internal/frontend/cli/frontend.go index bd08cc00..4422e427 100644 --- a/internal/frontend/cli/frontend.go +++ b/internal/frontend/cli/frontend.go @@ -289,6 +289,23 @@ func New( }) fe.AddCmd(badEventCmd) + // Telemetry commands + telemetryCmd := &ishell.Cmd{ + Name: "telemetry", + Help: "choose whether usage diagnostics are collected or not", + } + telemetryCmd.AddCmd(&ishell.Cmd{ + Name: "enable", + Help: "Usage diagnostics collection will be enabled", + Func: fe.enableTelemetry, + }) + telemetryCmd.AddCmd(&ishell.Cmd{ + Name: "disable", + Help: "Usage diagnostics collection will be disabled", + Func: fe.disableTelemetry, + }) + fe.AddCmd(telemetryCmd) + go fe.watchEvents(eventCh) go func() { diff --git a/internal/frontend/cli/system.go b/internal/frontend/cli/system.go index dc1b12ca..1290d0fa 100644 --- a/internal/frontend/cli/system.go +++ b/internal/frontend/cli/system.go @@ -40,7 +40,7 @@ func (f *frontendCLI) printLogDir(c *ishell.Context) { } func (f *frontendCLI) printManual(c *ishell.Context) { - f.Println("More instructions about the Bridge can be found at\n\n https://protonmail.com/bridge") + f.Println("More instructions about the Bridge can be found at\n\n https://proton.me/mail/bridge") } func (f *frontendCLI) printCredits(c *ishell.Context) { @@ -195,6 +195,38 @@ func (f *frontendCLI) showAllMail(c *ishell.Context) { } } +func (f *frontendCLI) enableTelemetry(_ *ishell.Context) { + if !f.bridge.GetTelemetryDisabled() { + f.Println("Usage diagnostics collection is enabled.") + return + } + + f.Println("Usage diagnostics collection is disabled right now.") + + if f.yesNoQuestion("Do you want to enable usage diagnostics collection") { + if err := f.bridge.SetTelemetryDisabled(false); err != nil { + f.printAndLogError(err) + return + } + } +} + +func (f *frontendCLI) disableTelemetry(_ *ishell.Context) { + if f.bridge.GetTelemetryDisabled() { + f.Println("Usage diagnostics collection is disabled.") + return + } + + f.Println("Usage diagnostics collection is enabled right now.") + + if f.yesNoQuestion("Do you want to disable usage diagnostics collection") { + if err := f.bridge.SetTelemetryDisabled(true); err != nil { + f.printAndLogError(err) + return + } + } +} + func (f *frontendCLI) setGluonLocation(c *ishell.Context) { if gluonDir := f.bridge.GetGluonCacheDir(); gluonDir != "" { f.Println("The current message cache location is:", gluonDir) diff --git a/internal/frontend/grpc/bridge.pb.go b/internal/frontend/grpc/bridge.pb.go index 5a4680e2..9ccae52b 100644 --- a/internal/frontend/grpc/bridge.pb.go +++ b/internal/frontend/grpc/bridge.pb.go @@ -17,8 +17,8 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.28.1 -// protoc v3.21.12 +// protoc-gen-go v1.28.0 +// protoc v3.21.3 // source: bridge.proto package grpc @@ -4803,8 +4803,8 @@ var file_bridge_proto_rawDesc = []byte{ 0x4e, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x10, 0x00, 0x12, 0x19, 0x0a, 0x15, 0x54, 0x4c, 0x53, 0x5f, 0x43, 0x45, 0x52, 0x54, 0x5f, 0x45, 0x58, 0x50, 0x4f, 0x52, 0x54, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x10, 0x01, 0x12, 0x18, 0x0a, 0x14, 0x54, 0x4c, 0x53, 0x5f, 0x4b, 0x45, 0x59, 0x5f, - 0x45, 0x58, 0x50, 0x4f, 0x52, 0x54, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x10, 0x02, 0x32, 0xf0, - 0x1d, 0x0a, 0x06, 0x42, 0x72, 0x69, 0x64, 0x67, 0x65, 0x12, 0x49, 0x0a, 0x0b, 0x43, 0x68, 0x65, + 0x45, 0x58, 0x50, 0x4f, 0x52, 0x54, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x10, 0x02, 0x32, 0x89, + 0x1f, 0x0a, 0x06, 0x42, 0x72, 0x69, 0x64, 0x67, 0x65, 0x12, 0x49, 0x0a, 0x0b, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x73, 0x12, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x1a, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, @@ -4855,199 +4855,208 @@ var file_bridge_proto_rawDesc = []byte{ 0x6c, 0x65, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x42, 0x6f, 0x6f, - 0x6c, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x3c, 0x0a, 0x04, 0x47, 0x6f, 0x4f, 0x73, 0x12, 0x16, - 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, - 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, - 0x61, 0x6c, 0x75, 0x65, 0x12, 0x3e, 0x0a, 0x0c, 0x54, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x52, - 0x65, 0x73, 0x65, 0x74, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x16, 0x2e, 0x67, + 0x6c, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x4c, 0x0a, 0x16, 0x53, 0x65, 0x74, 0x49, 0x73, 0x54, + 0x65, 0x6c, 0x65, 0x6d, 0x65, 0x74, 0x72, 0x79, 0x44, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x64, + 0x12, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, + 0x75, 0x66, 0x2e, 0x42, 0x6f, 0x6f, 0x6c, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, - 0x6d, 0x70, 0x74, 0x79, 0x12, 0x3f, 0x0a, 0x07, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, + 0x6d, 0x70, 0x74, 0x79, 0x12, 0x49, 0x0a, 0x13, 0x49, 0x73, 0x54, 0x65, 0x6c, 0x65, 0x6d, 0x65, + 0x74, 0x72, 0x79, 0x44, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x12, 0x16, 0x2e, 0x67, 0x6f, + 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, + 0x70, 0x74, 0x79, 0x1a, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x42, 0x6f, 0x6f, 0x6c, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, + 0x3c, 0x0a, 0x04, 0x47, 0x6f, 0x4f, 0x73, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, + 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, + 0x66, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x3e, 0x0a, + 0x0c, 0x54, 0x72, 0x69, 0x67, 0x67, 0x65, 0x72, 0x52, 0x65, 0x73, 0x65, 0x74, 0x12, 0x16, 0x2e, + 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, + 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x3f, 0x0a, + 0x07, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, + 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, + 0x1a, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, + 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x40, + 0x0a, 0x08, 0x4c, 0x6f, 0x67, 0x73, 0x50, 0x61, 0x74, 0x68, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, + 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, + 0x74, 0x79, 0x1a, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, + 0x12, 0x43, 0x0a, 0x0b, 0x4c, 0x69, 0x63, 0x65, 0x6e, 0x73, 0x65, 0x50, 0x61, 0x74, 0x68, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, - 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x40, 0x0a, 0x08, 0x4c, 0x6f, 0x67, 0x73, 0x50, 0x61, 0x74, - 0x68, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, - 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x69, - 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x43, 0x0a, 0x0b, 0x4c, 0x69, 0x63, 0x65, 0x6e, - 0x73, 0x65, 0x50, 0x61, 0x74, 0x68, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x1c, - 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, - 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x4c, 0x0a, 0x14, - 0x52, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, 0x4e, 0x6f, 0x74, 0x65, 0x73, 0x50, 0x61, 0x67, 0x65, - 0x4c, 0x69, 0x6e, 0x6b, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x1c, 0x2e, 0x67, - 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, - 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x4e, 0x0a, 0x16, 0x44, 0x65, - 0x70, 0x65, 0x6e, 0x64, 0x65, 0x6e, 0x63, 0x79, 0x4c, 0x69, 0x63, 0x65, 0x6e, 0x73, 0x65, 0x73, - 0x4c, 0x69, 0x6e, 0x6b, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x1c, 0x2e, 0x67, - 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, - 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x47, 0x0a, 0x0f, 0x4c, 0x61, - 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x50, 0x61, 0x67, 0x65, 0x4c, 0x69, 0x6e, 0x6b, 0x12, 0x16, 0x2e, + 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x4c, 0x0a, 0x14, 0x52, 0x65, 0x6c, 0x65, 0x61, 0x73, 0x65, + 0x4e, 0x6f, 0x74, 0x65, 0x73, 0x50, 0x61, 0x67, 0x65, 0x4c, 0x69, 0x6e, 0x6b, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, 0x61, - 0x6c, 0x75, 0x65, 0x12, 0x4a, 0x0a, 0x12, 0x53, 0x65, 0x74, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x53, - 0x63, 0x68, 0x65, 0x6d, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, - 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x69, - 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, - 0x47, 0x0a, 0x0f, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x65, 0x4e, 0x61, - 0x6d, 0x65, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, - 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, - 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x4a, 0x0a, 0x12, 0x43, 0x75, 0x72, 0x72, - 0x65, 0x6e, 0x74, 0x45, 0x6d, 0x61, 0x69, 0x6c, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x12, 0x16, + 0x6c, 0x75, 0x65, 0x12, 0x4e, 0x0a, 0x16, 0x44, 0x65, 0x70, 0x65, 0x6e, 0x64, 0x65, 0x6e, 0x63, + 0x79, 0x4c, 0x69, 0x63, 0x65, 0x6e, 0x73, 0x65, 0x73, 0x4c, 0x69, 0x6e, 0x6b, 0x12, 0x16, 0x2e, + 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, + 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, 0x61, + 0x6c, 0x75, 0x65, 0x12, 0x47, 0x0a, 0x0f, 0x4c, 0x61, 0x6e, 0x64, 0x69, 0x6e, 0x67, 0x50, 0x61, + 0x67, 0x65, 0x4c, 0x69, 0x6e, 0x6b, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, - 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, - 0x61, 0x6c, 0x75, 0x65, 0x12, 0x3b, 0x0a, 0x09, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x42, 0x75, - 0x67, 0x12, 0x16, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x42, - 0x75, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, - 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, - 0x79, 0x12, 0x4d, 0x0a, 0x15, 0x45, 0x78, 0x70, 0x6f, 0x72, 0x74, 0x54, 0x4c, 0x53, 0x43, 0x65, - 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x73, 0x12, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, + 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x4a, 0x0a, 0x12, + 0x53, 0x65, 0x74, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x65, 0x4e, 0x61, + 0x6d, 0x65, 0x12, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, + 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, + 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x47, 0x0a, 0x0f, 0x43, 0x6f, 0x6c, 0x6f, + 0x72, 0x53, 0x63, 0x68, 0x65, 0x6d, 0x65, 0x4e, 0x61, 0x6d, 0x65, 0x12, 0x16, 0x2e, 0x67, 0x6f, + 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, + 0x70, 0x74, 0x79, 0x1a, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75, + 0x65, 0x12, 0x4a, 0x0a, 0x12, 0x43, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x45, 0x6d, 0x61, 0x69, + 0x6c, 0x43, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, + 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, + 0x66, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x3b, 0x0a, + 0x09, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x42, 0x75, 0x67, 0x12, 0x16, 0x2e, 0x67, 0x72, 0x70, + 0x63, 0x2e, 0x52, 0x65, 0x70, 0x6f, 0x72, 0x74, 0x42, 0x75, 0x67, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x4d, 0x0a, 0x15, 0x45, 0x78, + 0x70, 0x6f, 0x72, 0x74, 0x54, 0x4c, 0x53, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, + 0x74, 0x65, 0x73, 0x12, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75, + 0x65, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x45, 0x0a, 0x0d, 0x46, 0x6f, 0x72, + 0x63, 0x65, 0x4c, 0x61, 0x75, 0x6e, 0x63, 0x68, 0x65, 0x72, 0x12, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, - 0x12, 0x45, 0x0a, 0x0d, 0x46, 0x6f, 0x72, 0x63, 0x65, 0x4c, 0x61, 0x75, 0x6e, 0x63, 0x68, 0x65, - 0x72, 0x12, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x1a, - 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, - 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x49, 0x0a, 0x11, 0x53, 0x65, 0x74, 0x4d, 0x61, - 0x69, 0x6e, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x61, 0x62, 0x6c, 0x65, 0x12, 0x1c, 0x2e, 0x67, - 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, - 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, - 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, - 0x74, 0x79, 0x12, 0x33, 0x0a, 0x05, 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x12, 0x12, 0x2e, 0x67, 0x72, + 0x12, 0x49, 0x0a, 0x11, 0x53, 0x65, 0x74, 0x4d, 0x61, 0x69, 0x6e, 0x45, 0x78, 0x65, 0x63, 0x75, + 0x74, 0x61, 0x62, 0x6c, 0x65, 0x12, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, 0x61, + 0x6c, 0x75, 0x65, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x33, 0x0a, 0x05, 0x4c, + 0x6f, 0x67, 0x69, 0x6e, 0x12, 0x12, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x6f, 0x67, 0x69, + 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, + 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, + 0x12, 0x36, 0x0a, 0x08, 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x32, 0x46, 0x41, 0x12, 0x12, 0x2e, 0x67, + 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, + 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x3d, 0x0a, 0x0f, 0x4c, 0x6f, 0x67, 0x69, + 0x6e, 0x32, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x73, 0x12, 0x12, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, - 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x36, 0x0a, 0x08, 0x4c, 0x6f, 0x67, 0x69, 0x6e, - 0x32, 0x46, 0x41, 0x12, 0x12, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x6f, 0x67, 0x69, 0x6e, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, - 0x3d, 0x0a, 0x0f, 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x32, 0x50, 0x61, 0x73, 0x73, 0x77, 0x6f, 0x72, - 0x64, 0x73, 0x12, 0x12, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x3d, - 0x0a, 0x0a, 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x41, 0x62, 0x6f, 0x72, 0x74, 0x12, 0x17, 0x2e, 0x67, - 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x41, 0x62, 0x6f, 0x72, 0x74, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x3d, 0x0a, - 0x0b, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x12, 0x16, 0x2e, 0x67, + 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x3d, 0x0a, 0x0a, 0x4c, 0x6f, 0x67, 0x69, 0x6e, + 0x41, 0x62, 0x6f, 0x72, 0x74, 0x12, 0x17, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x4c, 0x6f, 0x67, + 0x69, 0x6e, 0x41, 0x62, 0x6f, 0x72, 0x74, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, + 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, + 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x3d, 0x0a, 0x0b, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x55, + 0x70, 0x64, 0x61, 0x74, 0x65, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x16, 0x2e, + 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, + 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x3f, 0x0a, 0x0d, 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, + 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x16, + 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, + 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x4c, 0x0a, 0x16, 0x53, 0x65, 0x74, 0x49, 0x73, 0x41, + 0x75, 0x74, 0x6f, 0x6d, 0x61, 0x74, 0x69, 0x63, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4f, 0x6e, + 0x12, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, + 0x75, 0x66, 0x2e, 0x42, 0x6f, 0x6f, 0x6c, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, - 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x3f, 0x0a, 0x0d, - 0x49, 0x6e, 0x73, 0x74, 0x61, 0x6c, 0x6c, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x12, 0x16, 0x2e, - 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, - 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x4c, 0x0a, - 0x16, 0x53, 0x65, 0x74, 0x49, 0x73, 0x41, 0x75, 0x74, 0x6f, 0x6d, 0x61, 0x74, 0x69, 0x63, 0x55, - 0x70, 0x64, 0x61, 0x74, 0x65, 0x4f, 0x6e, 0x12, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x42, 0x6f, 0x6f, 0x6c, 0x56, 0x61, - 0x6c, 0x75, 0x65, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x49, 0x0a, 0x13, 0x49, - 0x73, 0x41, 0x75, 0x74, 0x6f, 0x6d, 0x61, 0x74, 0x69, 0x63, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, - 0x4f, 0x6e, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, - 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x42, 0x6f, 0x6f, - 0x6c, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x45, 0x0a, 0x0d, 0x44, 0x69, 0x73, 0x6b, 0x43, 0x61, - 0x63, 0x68, 0x65, 0x50, 0x61, 0x74, 0x68, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, - 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, - 0x66, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x48, 0x0a, - 0x10, 0x53, 0x65, 0x74, 0x44, 0x69, 0x73, 0x6b, 0x43, 0x61, 0x63, 0x68, 0x65, 0x50, 0x61, 0x74, - 0x68, 0x12, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x1a, - 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, - 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x45, 0x0a, 0x0f, 0x53, 0x65, 0x74, 0x49, 0x73, - 0x44, 0x6f, 0x48, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x12, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, - 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x42, 0x6f, 0x6f, - 0x6c, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x42, - 0x0a, 0x0c, 0x49, 0x73, 0x44, 0x6f, 0x48, 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x12, 0x16, - 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, - 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x42, 0x6f, 0x6f, 0x6c, 0x56, 0x61, 0x6c, - 0x75, 0x65, 0x12, 0x44, 0x0a, 0x12, 0x4d, 0x61, 0x69, 0x6c, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, - 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, - 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, - 0x1a, 0x16, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x49, 0x6d, 0x61, 0x70, 0x53, 0x6d, 0x74, 0x70, - 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x12, 0x47, 0x0a, 0x15, 0x53, 0x65, 0x74, 0x4d, - 0x61, 0x69, 0x6c, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, - 0x73, 0x12, 0x16, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x49, 0x6d, 0x61, 0x70, 0x53, 0x6d, 0x74, - 0x70, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, - 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, - 0x79, 0x12, 0x40, 0x0a, 0x08, 0x48, 0x6f, 0x73, 0x74, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x16, 0x2e, - 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, - 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, 0x61, - 0x6c, 0x75, 0x65, 0x12, 0x45, 0x0a, 0x0a, 0x49, 0x73, 0x50, 0x6f, 0x72, 0x74, 0x46, 0x72, 0x65, - 0x65, 0x12, 0x1b, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x62, 0x75, 0x66, 0x2e, 0x49, 0x6e, 0x74, 0x33, 0x32, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x1a, 0x1a, - 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, - 0x2e, 0x42, 0x6f, 0x6f, 0x6c, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x4e, 0x0a, 0x12, 0x41, 0x76, - 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x4b, 0x65, 0x79, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x73, + 0x6d, 0x70, 0x74, 0x79, 0x12, 0x49, 0x0a, 0x13, 0x49, 0x73, 0x41, 0x75, 0x74, 0x6f, 0x6d, 0x61, + 0x74, 0x69, 0x63, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x4f, 0x6e, 0x12, 0x16, 0x2e, 0x67, 0x6f, + 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, + 0x70, 0x74, 0x79, 0x1a, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x42, 0x6f, 0x6f, 0x6c, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, + 0x45, 0x0a, 0x0d, 0x44, 0x69, 0x73, 0x6b, 0x43, 0x61, 0x63, 0x68, 0x65, 0x50, 0x61, 0x74, 0x68, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, - 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x20, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, - 0x41, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, 0x65, 0x4b, 0x65, 0x79, 0x63, 0x68, 0x61, 0x69, - 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4a, 0x0a, 0x12, 0x53, 0x65, - 0x74, 0x43, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x4b, 0x65, 0x79, 0x63, 0x68, 0x61, 0x69, 0x6e, - 0x12, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, - 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x1a, 0x16, + 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, + 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, + 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x48, 0x0a, 0x10, 0x53, 0x65, 0x74, 0x44, 0x69, 0x73, + 0x6b, 0x43, 0x61, 0x63, 0x68, 0x65, 0x50, 0x61, 0x74, 0x68, 0x12, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, + 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, + 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, + 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, + 0x12, 0x45, 0x0a, 0x0f, 0x53, 0x65, 0x74, 0x49, 0x73, 0x44, 0x6f, 0x48, 0x45, 0x6e, 0x61, 0x62, + 0x6c, 0x65, 0x64, 0x12, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x42, 0x6f, 0x6f, 0x6c, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x1a, + 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, + 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x42, 0x0a, 0x0c, 0x49, 0x73, 0x44, 0x6f, 0x48, + 0x45, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x64, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, + 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, + 0x66, 0x2e, 0x42, 0x6f, 0x6f, 0x6c, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x44, 0x0a, 0x12, 0x4d, + 0x61, 0x69, 0x6c, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, + 0x73, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, + 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x16, 0x2e, 0x67, 0x72, 0x70, 0x63, + 0x2e, 0x49, 0x6d, 0x61, 0x70, 0x53, 0x6d, 0x74, 0x70, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, + 0x73, 0x12, 0x47, 0x0a, 0x15, 0x53, 0x65, 0x74, 0x4d, 0x61, 0x69, 0x6c, 0x53, 0x65, 0x72, 0x76, + 0x65, 0x72, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, 0x67, 0x73, 0x12, 0x16, 0x2e, 0x67, 0x72, 0x70, + 0x63, 0x2e, 0x49, 0x6d, 0x61, 0x70, 0x53, 0x6d, 0x74, 0x70, 0x53, 0x65, 0x74, 0x74, 0x69, 0x6e, + 0x67, 0x73, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x40, 0x0a, 0x08, 0x48, 0x6f, + 0x73, 0x74, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, - 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x47, 0x0a, 0x0f, 0x43, 0x75, 0x72, 0x72, 0x65, 0x6e, - 0x74, 0x4b, 0x65, 0x79, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, + 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x45, 0x0a, 0x0a, + 0x49, 0x73, 0x50, 0x6f, 0x72, 0x74, 0x46, 0x72, 0x65, 0x65, 0x12, 0x1b, 0x2e, 0x67, 0x6f, 0x6f, + 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x49, 0x6e, 0x74, + 0x33, 0x32, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x1a, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x42, 0x6f, 0x6f, 0x6c, 0x56, 0x61, + 0x6c, 0x75, 0x65, 0x12, 0x4e, 0x0a, 0x12, 0x41, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, 0x6c, 0x65, + 0x4b, 0x65, 0x79, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x73, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, - 0x79, 0x1a, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, - 0x3d, 0x0a, 0x0b, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x16, - 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, - 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x16, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x55, 0x73, - 0x65, 0x72, 0x4c, 0x69, 0x73, 0x74, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x33, - 0x0a, 0x07, 0x47, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x12, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, + 0x79, 0x1a, 0x20, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x41, 0x76, 0x61, 0x69, 0x6c, 0x61, 0x62, + 0x6c, 0x65, 0x4b, 0x65, 0x79, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x12, 0x4a, 0x0a, 0x12, 0x53, 0x65, 0x74, 0x43, 0x75, 0x72, 0x72, 0x65, 0x6e, + 0x74, 0x4b, 0x65, 0x79, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x12, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x69, - 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x1a, 0x0a, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x55, - 0x73, 0x65, 0x72, 0x12, 0x46, 0x0a, 0x10, 0x53, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x53, 0x70, - 0x6c, 0x69, 0x74, 0x4d, 0x6f, 0x64, 0x65, 0x12, 0x1a, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x55, - 0x73, 0x65, 0x72, 0x53, 0x70, 0x6c, 0x69, 0x74, 0x4d, 0x6f, 0x64, 0x65, 0x52, 0x65, 0x71, 0x75, + 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, + 0x47, 0x0a, 0x0f, 0x43, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x4b, 0x65, 0x79, 0x63, 0x68, 0x61, + 0x69, 0x6e, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, + 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, + 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x3d, 0x0a, 0x0b, 0x47, 0x65, 0x74, 0x55, + 0x73, 0x65, 0x72, 0x4c, 0x69, 0x73, 0x74, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, + 0x16, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x4c, 0x69, 0x73, 0x74, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x33, 0x0a, 0x07, 0x47, 0x65, 0x74, 0x55, 0x73, + 0x65, 0x72, 0x12, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, + 0x1a, 0x0a, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x12, 0x46, 0x0a, 0x10, + 0x53, 0x65, 0x74, 0x55, 0x73, 0x65, 0x72, 0x53, 0x70, 0x6c, 0x69, 0x74, 0x4d, 0x6f, 0x64, 0x65, + 0x12, 0x1a, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x53, 0x70, 0x6c, 0x69, + 0x74, 0x4d, 0x6f, 0x64, 0x65, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, + 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, + 0x6d, 0x70, 0x74, 0x79, 0x12, 0x55, 0x0a, 0x18, 0x53, 0x65, 0x6e, 0x64, 0x42, 0x61, 0x64, 0x45, + 0x76, 0x65, 0x6e, 0x74, 0x55, 0x73, 0x65, 0x72, 0x46, 0x65, 0x65, 0x64, 0x62, 0x61, 0x63, 0x6b, + 0x12, 0x21, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x55, 0x73, 0x65, 0x72, 0x42, 0x61, 0x64, 0x45, + 0x76, 0x65, 0x6e, 0x74, 0x46, 0x65, 0x65, 0x64, 0x62, 0x61, 0x63, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x55, 0x0a, 0x18, 0x53, - 0x65, 0x6e, 0x64, 0x42, 0x61, 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x55, 0x73, 0x65, 0x72, 0x46, - 0x65, 0x65, 0x64, 0x62, 0x61, 0x63, 0x6b, 0x12, 0x21, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x55, - 0x73, 0x65, 0x72, 0x42, 0x61, 0x64, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x46, 0x65, 0x65, 0x64, 0x62, - 0x61, 0x63, 0x6b, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, - 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, - 0x74, 0x79, 0x12, 0x42, 0x0a, 0x0a, 0x4c, 0x6f, 0x67, 0x6f, 0x75, 0x74, 0x55, 0x73, 0x65, 0x72, - 0x12, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, - 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x1a, 0x16, + 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x42, 0x0a, 0x0a, 0x4c, + 0x6f, 0x67, 0x6f, 0x75, 0x74, 0x55, 0x73, 0x65, 0x72, 0x12, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, + 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x69, + 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, + 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, + 0x42, 0x0a, 0x0a, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, 0x55, 0x73, 0x65, 0x72, 0x12, 0x1c, 0x2e, + 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, + 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x1a, 0x16, 0x2e, 0x67, 0x6f, + 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, + 0x70, 0x74, 0x79, 0x12, 0x51, 0x0a, 0x16, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x65, + 0x55, 0x73, 0x65, 0x72, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x4d, 0x61, 0x69, 0x6c, 0x12, 0x1f, 0x2e, + 0x67, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x65, 0x41, 0x70, + 0x70, 0x6c, 0x65, 0x4d, 0x61, 0x69, 0x6c, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, - 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x42, 0x0a, 0x0a, 0x52, 0x65, 0x6d, 0x6f, 0x76, 0x65, - 0x55, 0x73, 0x65, 0x72, 0x12, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, - 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c, - 0x75, 0x65, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x51, 0x0a, 0x16, 0x43, 0x6f, - 0x6e, 0x66, 0x69, 0x67, 0x75, 0x72, 0x65, 0x55, 0x73, 0x65, 0x72, 0x41, 0x70, 0x70, 0x6c, 0x65, - 0x4d, 0x61, 0x69, 0x6c, 0x12, 0x1f, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x43, 0x6f, 0x6e, 0x66, - 0x69, 0x67, 0x75, 0x72, 0x65, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x4d, 0x61, 0x69, 0x6c, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x3f, 0x0a, - 0x0e, 0x52, 0x75, 0x6e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x12, - 0x18, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x53, 0x74, 0x72, 0x65, - 0x61, 0x6d, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x11, 0x2e, 0x67, 0x72, 0x70, 0x63, - 0x2e, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x30, 0x01, 0x12, 0x41, - 0x0a, 0x0f, 0x53, 0x74, 0x6f, 0x70, 0x45, 0x76, 0x65, 0x6e, 0x74, 0x53, 0x74, 0x72, 0x65, 0x61, - 0x6d, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, - 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, - 0x79, 0x42, 0x36, 0x5a, 0x34, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, - 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x6e, 0x4d, 0x61, 0x69, 0x6c, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x6e, 0x2d, 0x62, 0x72, 0x69, 0x64, 0x67, 0x65, 0x2f, 0x76, 0x33, 0x2f, 0x69, 0x6e, 0x74, 0x65, - 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x67, 0x72, 0x70, 0x63, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x33, + 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x12, 0x3f, 0x0a, 0x0e, 0x52, 0x75, 0x6e, 0x45, 0x76, 0x65, + 0x6e, 0x74, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x12, 0x18, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, + 0x45, 0x76, 0x65, 0x6e, 0x74, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x52, 0x65, 0x71, 0x75, 0x65, + 0x73, 0x74, 0x1a, 0x11, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, + 0x45, 0x76, 0x65, 0x6e, 0x74, 0x30, 0x01, 0x12, 0x41, 0x0a, 0x0f, 0x53, 0x74, 0x6f, 0x70, 0x45, + 0x76, 0x65, 0x6e, 0x74, 0x53, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, + 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, + 0x74, 0x79, 0x1a, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, + 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x42, 0x36, 0x5a, 0x34, 0x67, 0x69, + 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x6e, 0x4d, + 0x61, 0x69, 0x6c, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x6e, 0x2d, 0x62, 0x72, 0x69, 0x64, 0x67, + 0x65, 0x2f, 0x76, 0x33, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x67, 0x72, + 0x70, 0x63, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -5214,106 +5223,110 @@ var file_bridge_proto_depIdxs = []int32{ 72, // 69: grpc.Bridge.IsBetaEnabled:input_type -> google.protobuf.Empty 73, // 70: grpc.Bridge.SetIsAllMailVisible:input_type -> google.protobuf.BoolValue 72, // 71: grpc.Bridge.IsAllMailVisible:input_type -> google.protobuf.Empty - 72, // 72: grpc.Bridge.GoOs:input_type -> google.protobuf.Empty - 72, // 73: grpc.Bridge.TriggerReset:input_type -> google.protobuf.Empty - 72, // 74: grpc.Bridge.Version:input_type -> google.protobuf.Empty - 72, // 75: grpc.Bridge.LogsPath:input_type -> google.protobuf.Empty - 72, // 76: grpc.Bridge.LicensePath:input_type -> google.protobuf.Empty - 72, // 77: grpc.Bridge.ReleaseNotesPageLink:input_type -> google.protobuf.Empty - 72, // 78: grpc.Bridge.DependencyLicensesLink:input_type -> google.protobuf.Empty - 72, // 79: grpc.Bridge.LandingPageLink:input_type -> google.protobuf.Empty - 71, // 80: grpc.Bridge.SetColorSchemeName:input_type -> google.protobuf.StringValue - 72, // 81: grpc.Bridge.ColorSchemeName:input_type -> google.protobuf.Empty - 72, // 82: grpc.Bridge.CurrentEmailClient:input_type -> google.protobuf.Empty - 9, // 83: grpc.Bridge.ReportBug:input_type -> grpc.ReportBugRequest - 71, // 84: grpc.Bridge.ExportTLSCertificates:input_type -> google.protobuf.StringValue - 71, // 85: grpc.Bridge.ForceLauncher:input_type -> google.protobuf.StringValue - 71, // 86: grpc.Bridge.SetMainExecutable:input_type -> google.protobuf.StringValue - 10, // 87: grpc.Bridge.Login:input_type -> grpc.LoginRequest - 10, // 88: grpc.Bridge.Login2FA:input_type -> grpc.LoginRequest - 10, // 89: grpc.Bridge.Login2Passwords:input_type -> grpc.LoginRequest - 11, // 90: grpc.Bridge.LoginAbort:input_type -> grpc.LoginAbortRequest - 72, // 91: grpc.Bridge.CheckUpdate:input_type -> google.protobuf.Empty - 72, // 92: grpc.Bridge.InstallUpdate:input_type -> google.protobuf.Empty - 73, // 93: grpc.Bridge.SetIsAutomaticUpdateOn:input_type -> google.protobuf.BoolValue - 72, // 94: grpc.Bridge.IsAutomaticUpdateOn:input_type -> google.protobuf.Empty - 72, // 95: grpc.Bridge.DiskCachePath:input_type -> google.protobuf.Empty - 71, // 96: grpc.Bridge.SetDiskCachePath:input_type -> google.protobuf.StringValue - 73, // 97: grpc.Bridge.SetIsDoHEnabled:input_type -> google.protobuf.BoolValue - 72, // 98: grpc.Bridge.IsDoHEnabled:input_type -> google.protobuf.Empty - 72, // 99: grpc.Bridge.MailServerSettings:input_type -> google.protobuf.Empty - 12, // 100: grpc.Bridge.SetMailServerSettings:input_type -> grpc.ImapSmtpSettings - 72, // 101: grpc.Bridge.Hostname:input_type -> google.protobuf.Empty - 74, // 102: grpc.Bridge.IsPortFree:input_type -> google.protobuf.Int32Value - 72, // 103: grpc.Bridge.AvailableKeychains:input_type -> google.protobuf.Empty - 71, // 104: grpc.Bridge.SetCurrentKeychain:input_type -> google.protobuf.StringValue - 72, // 105: grpc.Bridge.CurrentKeychain:input_type -> google.protobuf.Empty - 72, // 106: grpc.Bridge.GetUserList:input_type -> google.protobuf.Empty - 71, // 107: grpc.Bridge.GetUser:input_type -> google.protobuf.StringValue - 15, // 108: grpc.Bridge.SetUserSplitMode:input_type -> grpc.UserSplitModeRequest - 16, // 109: grpc.Bridge.SendBadEventUserFeedback:input_type -> grpc.UserBadEventFeedbackRequest - 71, // 110: grpc.Bridge.LogoutUser:input_type -> google.protobuf.StringValue - 71, // 111: grpc.Bridge.RemoveUser:input_type -> google.protobuf.StringValue - 18, // 112: grpc.Bridge.ConfigureUserAppleMail:input_type -> grpc.ConfigureAppleMailRequest - 19, // 113: grpc.Bridge.RunEventStream:input_type -> grpc.EventStreamRequest - 72, // 114: grpc.Bridge.StopEventStream:input_type -> google.protobuf.Empty - 71, // 115: grpc.Bridge.CheckTokens:output_type -> google.protobuf.StringValue - 72, // 116: grpc.Bridge.AddLogEntry:output_type -> google.protobuf.Empty - 8, // 117: grpc.Bridge.GuiReady:output_type -> grpc.GuiReadyResponse - 72, // 118: grpc.Bridge.Quit:output_type -> google.protobuf.Empty - 72, // 119: grpc.Bridge.Restart:output_type -> google.protobuf.Empty - 73, // 120: grpc.Bridge.ShowOnStartup:output_type -> google.protobuf.BoolValue - 72, // 121: grpc.Bridge.SetIsAutostartOn:output_type -> google.protobuf.Empty - 73, // 122: grpc.Bridge.IsAutostartOn:output_type -> google.protobuf.BoolValue - 72, // 123: grpc.Bridge.SetIsBetaEnabled:output_type -> google.protobuf.Empty - 73, // 124: grpc.Bridge.IsBetaEnabled:output_type -> google.protobuf.BoolValue - 72, // 125: grpc.Bridge.SetIsAllMailVisible:output_type -> google.protobuf.Empty - 73, // 126: grpc.Bridge.IsAllMailVisible:output_type -> google.protobuf.BoolValue - 71, // 127: grpc.Bridge.GoOs:output_type -> google.protobuf.StringValue - 72, // 128: grpc.Bridge.TriggerReset:output_type -> google.protobuf.Empty - 71, // 129: grpc.Bridge.Version:output_type -> google.protobuf.StringValue - 71, // 130: grpc.Bridge.LogsPath:output_type -> google.protobuf.StringValue - 71, // 131: grpc.Bridge.LicensePath:output_type -> google.protobuf.StringValue - 71, // 132: grpc.Bridge.ReleaseNotesPageLink:output_type -> google.protobuf.StringValue - 71, // 133: grpc.Bridge.DependencyLicensesLink:output_type -> google.protobuf.StringValue - 71, // 134: grpc.Bridge.LandingPageLink:output_type -> google.protobuf.StringValue - 72, // 135: grpc.Bridge.SetColorSchemeName:output_type -> google.protobuf.Empty - 71, // 136: grpc.Bridge.ColorSchemeName:output_type -> google.protobuf.StringValue - 71, // 137: grpc.Bridge.CurrentEmailClient:output_type -> google.protobuf.StringValue - 72, // 138: grpc.Bridge.ReportBug:output_type -> google.protobuf.Empty - 72, // 139: grpc.Bridge.ExportTLSCertificates:output_type -> google.protobuf.Empty - 72, // 140: grpc.Bridge.ForceLauncher:output_type -> google.protobuf.Empty - 72, // 141: grpc.Bridge.SetMainExecutable:output_type -> google.protobuf.Empty - 72, // 142: grpc.Bridge.Login:output_type -> google.protobuf.Empty - 72, // 143: grpc.Bridge.Login2FA:output_type -> google.protobuf.Empty - 72, // 144: grpc.Bridge.Login2Passwords:output_type -> google.protobuf.Empty - 72, // 145: grpc.Bridge.LoginAbort:output_type -> google.protobuf.Empty - 72, // 146: grpc.Bridge.CheckUpdate:output_type -> google.protobuf.Empty - 72, // 147: grpc.Bridge.InstallUpdate:output_type -> google.protobuf.Empty - 72, // 148: grpc.Bridge.SetIsAutomaticUpdateOn:output_type -> google.protobuf.Empty - 73, // 149: grpc.Bridge.IsAutomaticUpdateOn:output_type -> google.protobuf.BoolValue - 71, // 150: grpc.Bridge.DiskCachePath:output_type -> google.protobuf.StringValue - 72, // 151: grpc.Bridge.SetDiskCachePath:output_type -> google.protobuf.Empty - 72, // 152: grpc.Bridge.SetIsDoHEnabled:output_type -> google.protobuf.Empty - 73, // 153: grpc.Bridge.IsDoHEnabled:output_type -> google.protobuf.BoolValue - 12, // 154: grpc.Bridge.MailServerSettings:output_type -> grpc.ImapSmtpSettings - 72, // 155: grpc.Bridge.SetMailServerSettings:output_type -> google.protobuf.Empty - 71, // 156: grpc.Bridge.Hostname:output_type -> google.protobuf.StringValue - 73, // 157: grpc.Bridge.IsPortFree:output_type -> google.protobuf.BoolValue - 13, // 158: grpc.Bridge.AvailableKeychains:output_type -> grpc.AvailableKeychainsResponse - 72, // 159: grpc.Bridge.SetCurrentKeychain:output_type -> google.protobuf.Empty - 71, // 160: grpc.Bridge.CurrentKeychain:output_type -> google.protobuf.StringValue - 17, // 161: grpc.Bridge.GetUserList:output_type -> grpc.UserListResponse - 14, // 162: grpc.Bridge.GetUser:output_type -> grpc.User - 72, // 163: grpc.Bridge.SetUserSplitMode:output_type -> google.protobuf.Empty - 72, // 164: grpc.Bridge.SendBadEventUserFeedback:output_type -> google.protobuf.Empty - 72, // 165: grpc.Bridge.LogoutUser:output_type -> google.protobuf.Empty - 72, // 166: grpc.Bridge.RemoveUser:output_type -> google.protobuf.Empty - 72, // 167: grpc.Bridge.ConfigureUserAppleMail:output_type -> google.protobuf.Empty - 20, // 168: grpc.Bridge.RunEventStream:output_type -> grpc.StreamEvent - 72, // 169: grpc.Bridge.StopEventStream:output_type -> google.protobuf.Empty - 115, // [115:170] is the sub-list for method output_type - 60, // [60:115] is the sub-list for method input_type + 73, // 72: grpc.Bridge.SetIsTelemetryDisabled:input_type -> google.protobuf.BoolValue + 72, // 73: grpc.Bridge.IsTelemetryDisabled:input_type -> google.protobuf.Empty + 72, // 74: grpc.Bridge.GoOs:input_type -> google.protobuf.Empty + 72, // 75: grpc.Bridge.TriggerReset:input_type -> google.protobuf.Empty + 72, // 76: grpc.Bridge.Version:input_type -> google.protobuf.Empty + 72, // 77: grpc.Bridge.LogsPath:input_type -> google.protobuf.Empty + 72, // 78: grpc.Bridge.LicensePath:input_type -> google.protobuf.Empty + 72, // 79: grpc.Bridge.ReleaseNotesPageLink:input_type -> google.protobuf.Empty + 72, // 80: grpc.Bridge.DependencyLicensesLink:input_type -> google.protobuf.Empty + 72, // 81: grpc.Bridge.LandingPageLink:input_type -> google.protobuf.Empty + 71, // 82: grpc.Bridge.SetColorSchemeName:input_type -> google.protobuf.StringValue + 72, // 83: grpc.Bridge.ColorSchemeName:input_type -> google.protobuf.Empty + 72, // 84: grpc.Bridge.CurrentEmailClient:input_type -> google.protobuf.Empty + 9, // 85: grpc.Bridge.ReportBug:input_type -> grpc.ReportBugRequest + 71, // 86: grpc.Bridge.ExportTLSCertificates:input_type -> google.protobuf.StringValue + 71, // 87: grpc.Bridge.ForceLauncher:input_type -> google.protobuf.StringValue + 71, // 88: grpc.Bridge.SetMainExecutable:input_type -> google.protobuf.StringValue + 10, // 89: grpc.Bridge.Login:input_type -> grpc.LoginRequest + 10, // 90: grpc.Bridge.Login2FA:input_type -> grpc.LoginRequest + 10, // 91: grpc.Bridge.Login2Passwords:input_type -> grpc.LoginRequest + 11, // 92: grpc.Bridge.LoginAbort:input_type -> grpc.LoginAbortRequest + 72, // 93: grpc.Bridge.CheckUpdate:input_type -> google.protobuf.Empty + 72, // 94: grpc.Bridge.InstallUpdate:input_type -> google.protobuf.Empty + 73, // 95: grpc.Bridge.SetIsAutomaticUpdateOn:input_type -> google.protobuf.BoolValue + 72, // 96: grpc.Bridge.IsAutomaticUpdateOn:input_type -> google.protobuf.Empty + 72, // 97: grpc.Bridge.DiskCachePath:input_type -> google.protobuf.Empty + 71, // 98: grpc.Bridge.SetDiskCachePath:input_type -> google.protobuf.StringValue + 73, // 99: grpc.Bridge.SetIsDoHEnabled:input_type -> google.protobuf.BoolValue + 72, // 100: grpc.Bridge.IsDoHEnabled:input_type -> google.protobuf.Empty + 72, // 101: grpc.Bridge.MailServerSettings:input_type -> google.protobuf.Empty + 12, // 102: grpc.Bridge.SetMailServerSettings:input_type -> grpc.ImapSmtpSettings + 72, // 103: grpc.Bridge.Hostname:input_type -> google.protobuf.Empty + 74, // 104: grpc.Bridge.IsPortFree:input_type -> google.protobuf.Int32Value + 72, // 105: grpc.Bridge.AvailableKeychains:input_type -> google.protobuf.Empty + 71, // 106: grpc.Bridge.SetCurrentKeychain:input_type -> google.protobuf.StringValue + 72, // 107: grpc.Bridge.CurrentKeychain:input_type -> google.protobuf.Empty + 72, // 108: grpc.Bridge.GetUserList:input_type -> google.protobuf.Empty + 71, // 109: grpc.Bridge.GetUser:input_type -> google.protobuf.StringValue + 15, // 110: grpc.Bridge.SetUserSplitMode:input_type -> grpc.UserSplitModeRequest + 16, // 111: grpc.Bridge.SendBadEventUserFeedback:input_type -> grpc.UserBadEventFeedbackRequest + 71, // 112: grpc.Bridge.LogoutUser:input_type -> google.protobuf.StringValue + 71, // 113: grpc.Bridge.RemoveUser:input_type -> google.protobuf.StringValue + 18, // 114: grpc.Bridge.ConfigureUserAppleMail:input_type -> grpc.ConfigureAppleMailRequest + 19, // 115: grpc.Bridge.RunEventStream:input_type -> grpc.EventStreamRequest + 72, // 116: grpc.Bridge.StopEventStream:input_type -> google.protobuf.Empty + 71, // 117: grpc.Bridge.CheckTokens:output_type -> google.protobuf.StringValue + 72, // 118: grpc.Bridge.AddLogEntry:output_type -> google.protobuf.Empty + 8, // 119: grpc.Bridge.GuiReady:output_type -> grpc.GuiReadyResponse + 72, // 120: grpc.Bridge.Quit:output_type -> google.protobuf.Empty + 72, // 121: grpc.Bridge.Restart:output_type -> google.protobuf.Empty + 73, // 122: grpc.Bridge.ShowOnStartup:output_type -> google.protobuf.BoolValue + 72, // 123: grpc.Bridge.SetIsAutostartOn:output_type -> google.protobuf.Empty + 73, // 124: grpc.Bridge.IsAutostartOn:output_type -> google.protobuf.BoolValue + 72, // 125: grpc.Bridge.SetIsBetaEnabled:output_type -> google.protobuf.Empty + 73, // 126: grpc.Bridge.IsBetaEnabled:output_type -> google.protobuf.BoolValue + 72, // 127: grpc.Bridge.SetIsAllMailVisible:output_type -> google.protobuf.Empty + 73, // 128: grpc.Bridge.IsAllMailVisible:output_type -> google.protobuf.BoolValue + 72, // 129: grpc.Bridge.SetIsTelemetryDisabled:output_type -> google.protobuf.Empty + 73, // 130: grpc.Bridge.IsTelemetryDisabled:output_type -> google.protobuf.BoolValue + 71, // 131: grpc.Bridge.GoOs:output_type -> google.protobuf.StringValue + 72, // 132: grpc.Bridge.TriggerReset:output_type -> google.protobuf.Empty + 71, // 133: grpc.Bridge.Version:output_type -> google.protobuf.StringValue + 71, // 134: grpc.Bridge.LogsPath:output_type -> google.protobuf.StringValue + 71, // 135: grpc.Bridge.LicensePath:output_type -> google.protobuf.StringValue + 71, // 136: grpc.Bridge.ReleaseNotesPageLink:output_type -> google.protobuf.StringValue + 71, // 137: grpc.Bridge.DependencyLicensesLink:output_type -> google.protobuf.StringValue + 71, // 138: grpc.Bridge.LandingPageLink:output_type -> google.protobuf.StringValue + 72, // 139: grpc.Bridge.SetColorSchemeName:output_type -> google.protobuf.Empty + 71, // 140: grpc.Bridge.ColorSchemeName:output_type -> google.protobuf.StringValue + 71, // 141: grpc.Bridge.CurrentEmailClient:output_type -> google.protobuf.StringValue + 72, // 142: grpc.Bridge.ReportBug:output_type -> google.protobuf.Empty + 72, // 143: grpc.Bridge.ExportTLSCertificates:output_type -> google.protobuf.Empty + 72, // 144: grpc.Bridge.ForceLauncher:output_type -> google.protobuf.Empty + 72, // 145: grpc.Bridge.SetMainExecutable:output_type -> google.protobuf.Empty + 72, // 146: grpc.Bridge.Login:output_type -> google.protobuf.Empty + 72, // 147: grpc.Bridge.Login2FA:output_type -> google.protobuf.Empty + 72, // 148: grpc.Bridge.Login2Passwords:output_type -> google.protobuf.Empty + 72, // 149: grpc.Bridge.LoginAbort:output_type -> google.protobuf.Empty + 72, // 150: grpc.Bridge.CheckUpdate:output_type -> google.protobuf.Empty + 72, // 151: grpc.Bridge.InstallUpdate:output_type -> google.protobuf.Empty + 72, // 152: grpc.Bridge.SetIsAutomaticUpdateOn:output_type -> google.protobuf.Empty + 73, // 153: grpc.Bridge.IsAutomaticUpdateOn:output_type -> google.protobuf.BoolValue + 71, // 154: grpc.Bridge.DiskCachePath:output_type -> google.protobuf.StringValue + 72, // 155: grpc.Bridge.SetDiskCachePath:output_type -> google.protobuf.Empty + 72, // 156: grpc.Bridge.SetIsDoHEnabled:output_type -> google.protobuf.Empty + 73, // 157: grpc.Bridge.IsDoHEnabled:output_type -> google.protobuf.BoolValue + 12, // 158: grpc.Bridge.MailServerSettings:output_type -> grpc.ImapSmtpSettings + 72, // 159: grpc.Bridge.SetMailServerSettings:output_type -> google.protobuf.Empty + 71, // 160: grpc.Bridge.Hostname:output_type -> google.protobuf.StringValue + 73, // 161: grpc.Bridge.IsPortFree:output_type -> google.protobuf.BoolValue + 13, // 162: grpc.Bridge.AvailableKeychains:output_type -> grpc.AvailableKeychainsResponse + 72, // 163: grpc.Bridge.SetCurrentKeychain:output_type -> google.protobuf.Empty + 71, // 164: grpc.Bridge.CurrentKeychain:output_type -> google.protobuf.StringValue + 17, // 165: grpc.Bridge.GetUserList:output_type -> grpc.UserListResponse + 14, // 166: grpc.Bridge.GetUser:output_type -> grpc.User + 72, // 167: grpc.Bridge.SetUserSplitMode:output_type -> google.protobuf.Empty + 72, // 168: grpc.Bridge.SendBadEventUserFeedback:output_type -> google.protobuf.Empty + 72, // 169: grpc.Bridge.LogoutUser:output_type -> google.protobuf.Empty + 72, // 170: grpc.Bridge.RemoveUser:output_type -> google.protobuf.Empty + 72, // 171: grpc.Bridge.ConfigureUserAppleMail:output_type -> google.protobuf.Empty + 20, // 172: grpc.Bridge.RunEventStream:output_type -> grpc.StreamEvent + 72, // 173: grpc.Bridge.StopEventStream:output_type -> google.protobuf.Empty + 117, // [117:174] is the sub-list for method output_type + 60, // [60:117] is the sub-list for method input_type 60, // [60:60] is the sub-list for extension type_name 60, // [60:60] is the sub-list for extension extendee 0, // [0:60] is the sub-list for field type_name diff --git a/internal/frontend/grpc/bridge.proto b/internal/frontend/grpc/bridge.proto index e0a9ae9c..2a3e024b 100644 --- a/internal/frontend/grpc/bridge.proto +++ b/internal/frontend/grpc/bridge.proto @@ -42,6 +42,8 @@ service Bridge { rpc IsBetaEnabled(google.protobuf.Empty) returns (google.protobuf.BoolValue); rpc SetIsAllMailVisible(google.protobuf.BoolValue) returns (google.protobuf.Empty); rpc IsAllMailVisible(google.protobuf.Empty) returns (google.protobuf.BoolValue); + rpc SetIsTelemetryDisabled(google.protobuf.BoolValue) returns (google.protobuf.Empty); + rpc IsTelemetryDisabled(google.protobuf.Empty) returns (google.protobuf.BoolValue); rpc GoOs(google.protobuf.Empty) returns (google.protobuf.StringValue); rpc TriggerReset(google.protobuf.Empty) returns (google.protobuf.Empty); rpc Version(google.protobuf.Empty) returns (google.protobuf.StringValue); diff --git a/internal/frontend/grpc/bridge_grpc.pb.go b/internal/frontend/grpc/bridge_grpc.pb.go index 0b6a3d4f..fdddee0e 100644 --- a/internal/frontend/grpc/bridge_grpc.pb.go +++ b/internal/frontend/grpc/bridge_grpc.pb.go @@ -1,24 +1,7 @@ -// Copyright (c) 2022 Proton Technologies AG -// -// This file is part of ProtonMail Bridge. -// -// ProtonMail Bridge is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// ProtonMail Bridge is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with ProtonMail Bridge. If not, see . - // Code generated by protoc-gen-go-grpc. DO NOT EDIT. // versions: -// - protoc-gen-go-grpc v1.3.0 -// - protoc v3.21.12 +// - protoc-gen-go-grpc v1.2.0 +// - protoc v3.21.3 // source: bridge.proto package grpc @@ -37,64 +20,6 @@ import ( // Requires gRPC-Go v1.32.0 or later. const _ = grpc.SupportPackageIsVersion7 -const ( - Bridge_CheckTokens_FullMethodName = "/grpc.Bridge/CheckTokens" - Bridge_AddLogEntry_FullMethodName = "/grpc.Bridge/AddLogEntry" - Bridge_GuiReady_FullMethodName = "/grpc.Bridge/GuiReady" - Bridge_Quit_FullMethodName = "/grpc.Bridge/Quit" - Bridge_Restart_FullMethodName = "/grpc.Bridge/Restart" - Bridge_ShowOnStartup_FullMethodName = "/grpc.Bridge/ShowOnStartup" - Bridge_SetIsAutostartOn_FullMethodName = "/grpc.Bridge/SetIsAutostartOn" - Bridge_IsAutostartOn_FullMethodName = "/grpc.Bridge/IsAutostartOn" - Bridge_SetIsBetaEnabled_FullMethodName = "/grpc.Bridge/SetIsBetaEnabled" - Bridge_IsBetaEnabled_FullMethodName = "/grpc.Bridge/IsBetaEnabled" - Bridge_SetIsAllMailVisible_FullMethodName = "/grpc.Bridge/SetIsAllMailVisible" - Bridge_IsAllMailVisible_FullMethodName = "/grpc.Bridge/IsAllMailVisible" - Bridge_GoOs_FullMethodName = "/grpc.Bridge/GoOs" - Bridge_TriggerReset_FullMethodName = "/grpc.Bridge/TriggerReset" - Bridge_Version_FullMethodName = "/grpc.Bridge/Version" - Bridge_LogsPath_FullMethodName = "/grpc.Bridge/LogsPath" - Bridge_LicensePath_FullMethodName = "/grpc.Bridge/LicensePath" - Bridge_ReleaseNotesPageLink_FullMethodName = "/grpc.Bridge/ReleaseNotesPageLink" - Bridge_DependencyLicensesLink_FullMethodName = "/grpc.Bridge/DependencyLicensesLink" - Bridge_LandingPageLink_FullMethodName = "/grpc.Bridge/LandingPageLink" - Bridge_SetColorSchemeName_FullMethodName = "/grpc.Bridge/SetColorSchemeName" - Bridge_ColorSchemeName_FullMethodName = "/grpc.Bridge/ColorSchemeName" - Bridge_CurrentEmailClient_FullMethodName = "/grpc.Bridge/CurrentEmailClient" - Bridge_ReportBug_FullMethodName = "/grpc.Bridge/ReportBug" - Bridge_ExportTLSCertificates_FullMethodName = "/grpc.Bridge/ExportTLSCertificates" - Bridge_ForceLauncher_FullMethodName = "/grpc.Bridge/ForceLauncher" - Bridge_SetMainExecutable_FullMethodName = "/grpc.Bridge/SetMainExecutable" - Bridge_Login_FullMethodName = "/grpc.Bridge/Login" - Bridge_Login2FA_FullMethodName = "/grpc.Bridge/Login2FA" - Bridge_Login2Passwords_FullMethodName = "/grpc.Bridge/Login2Passwords" - Bridge_LoginAbort_FullMethodName = "/grpc.Bridge/LoginAbort" - Bridge_CheckUpdate_FullMethodName = "/grpc.Bridge/CheckUpdate" - Bridge_InstallUpdate_FullMethodName = "/grpc.Bridge/InstallUpdate" - Bridge_SetIsAutomaticUpdateOn_FullMethodName = "/grpc.Bridge/SetIsAutomaticUpdateOn" - Bridge_IsAutomaticUpdateOn_FullMethodName = "/grpc.Bridge/IsAutomaticUpdateOn" - Bridge_DiskCachePath_FullMethodName = "/grpc.Bridge/DiskCachePath" - Bridge_SetDiskCachePath_FullMethodName = "/grpc.Bridge/SetDiskCachePath" - Bridge_SetIsDoHEnabled_FullMethodName = "/grpc.Bridge/SetIsDoHEnabled" - Bridge_IsDoHEnabled_FullMethodName = "/grpc.Bridge/IsDoHEnabled" - Bridge_MailServerSettings_FullMethodName = "/grpc.Bridge/MailServerSettings" - Bridge_SetMailServerSettings_FullMethodName = "/grpc.Bridge/SetMailServerSettings" - Bridge_Hostname_FullMethodName = "/grpc.Bridge/Hostname" - Bridge_IsPortFree_FullMethodName = "/grpc.Bridge/IsPortFree" - Bridge_AvailableKeychains_FullMethodName = "/grpc.Bridge/AvailableKeychains" - Bridge_SetCurrentKeychain_FullMethodName = "/grpc.Bridge/SetCurrentKeychain" - Bridge_CurrentKeychain_FullMethodName = "/grpc.Bridge/CurrentKeychain" - Bridge_GetUserList_FullMethodName = "/grpc.Bridge/GetUserList" - Bridge_GetUser_FullMethodName = "/grpc.Bridge/GetUser" - Bridge_SetUserSplitMode_FullMethodName = "/grpc.Bridge/SetUserSplitMode" - Bridge_SendBadEventUserFeedback_FullMethodName = "/grpc.Bridge/SendBadEventUserFeedback" - Bridge_LogoutUser_FullMethodName = "/grpc.Bridge/LogoutUser" - Bridge_RemoveUser_FullMethodName = "/grpc.Bridge/RemoveUser" - Bridge_ConfigureUserAppleMail_FullMethodName = "/grpc.Bridge/ConfigureUserAppleMail" - Bridge_RunEventStream_FullMethodName = "/grpc.Bridge/RunEventStream" - Bridge_StopEventStream_FullMethodName = "/grpc.Bridge/StopEventStream" -) - // BridgeClient is the client API for Bridge service. // // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. @@ -112,6 +37,8 @@ type BridgeClient interface { IsBetaEnabled(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*wrapperspb.BoolValue, error) SetIsAllMailVisible(ctx context.Context, in *wrapperspb.BoolValue, opts ...grpc.CallOption) (*emptypb.Empty, error) IsAllMailVisible(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*wrapperspb.BoolValue, error) + SetIsTelemetryDisabled(ctx context.Context, in *wrapperspb.BoolValue, opts ...grpc.CallOption) (*emptypb.Empty, error) + IsTelemetryDisabled(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*wrapperspb.BoolValue, error) GoOs(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*wrapperspb.StringValue, error) TriggerReset(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*emptypb.Empty, error) Version(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*wrapperspb.StringValue, error) @@ -174,7 +101,7 @@ func NewBridgeClient(cc grpc.ClientConnInterface) BridgeClient { func (c *bridgeClient) CheckTokens(ctx context.Context, in *wrapperspb.StringValue, opts ...grpc.CallOption) (*wrapperspb.StringValue, error) { out := new(wrapperspb.StringValue) - err := c.cc.Invoke(ctx, Bridge_CheckTokens_FullMethodName, in, out, opts...) + err := c.cc.Invoke(ctx, "/grpc.Bridge/CheckTokens", in, out, opts...) if err != nil { return nil, err } @@ -183,7 +110,7 @@ func (c *bridgeClient) CheckTokens(ctx context.Context, in *wrapperspb.StringVal func (c *bridgeClient) AddLogEntry(ctx context.Context, in *AddLogEntryRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) { out := new(emptypb.Empty) - err := c.cc.Invoke(ctx, Bridge_AddLogEntry_FullMethodName, in, out, opts...) + err := c.cc.Invoke(ctx, "/grpc.Bridge/AddLogEntry", in, out, opts...) if err != nil { return nil, err } @@ -192,7 +119,7 @@ func (c *bridgeClient) AddLogEntry(ctx context.Context, in *AddLogEntryRequest, func (c *bridgeClient) GuiReady(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*GuiReadyResponse, error) { out := new(GuiReadyResponse) - err := c.cc.Invoke(ctx, Bridge_GuiReady_FullMethodName, in, out, opts...) + err := c.cc.Invoke(ctx, "/grpc.Bridge/GuiReady", in, out, opts...) if err != nil { return nil, err } @@ -201,7 +128,7 @@ func (c *bridgeClient) GuiReady(ctx context.Context, in *emptypb.Empty, opts ... func (c *bridgeClient) Quit(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*emptypb.Empty, error) { out := new(emptypb.Empty) - err := c.cc.Invoke(ctx, Bridge_Quit_FullMethodName, in, out, opts...) + err := c.cc.Invoke(ctx, "/grpc.Bridge/Quit", in, out, opts...) if err != nil { return nil, err } @@ -210,7 +137,7 @@ func (c *bridgeClient) Quit(ctx context.Context, in *emptypb.Empty, opts ...grpc func (c *bridgeClient) Restart(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*emptypb.Empty, error) { out := new(emptypb.Empty) - err := c.cc.Invoke(ctx, Bridge_Restart_FullMethodName, in, out, opts...) + err := c.cc.Invoke(ctx, "/grpc.Bridge/Restart", in, out, opts...) if err != nil { return nil, err } @@ -219,7 +146,7 @@ func (c *bridgeClient) Restart(ctx context.Context, in *emptypb.Empty, opts ...g func (c *bridgeClient) ShowOnStartup(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*wrapperspb.BoolValue, error) { out := new(wrapperspb.BoolValue) - err := c.cc.Invoke(ctx, Bridge_ShowOnStartup_FullMethodName, in, out, opts...) + err := c.cc.Invoke(ctx, "/grpc.Bridge/ShowOnStartup", in, out, opts...) if err != nil { return nil, err } @@ -228,7 +155,7 @@ func (c *bridgeClient) ShowOnStartup(ctx context.Context, in *emptypb.Empty, opt func (c *bridgeClient) SetIsAutostartOn(ctx context.Context, in *wrapperspb.BoolValue, opts ...grpc.CallOption) (*emptypb.Empty, error) { out := new(emptypb.Empty) - err := c.cc.Invoke(ctx, Bridge_SetIsAutostartOn_FullMethodName, in, out, opts...) + err := c.cc.Invoke(ctx, "/grpc.Bridge/SetIsAutostartOn", in, out, opts...) if err != nil { return nil, err } @@ -237,7 +164,7 @@ func (c *bridgeClient) SetIsAutostartOn(ctx context.Context, in *wrapperspb.Bool func (c *bridgeClient) IsAutostartOn(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*wrapperspb.BoolValue, error) { out := new(wrapperspb.BoolValue) - err := c.cc.Invoke(ctx, Bridge_IsAutostartOn_FullMethodName, in, out, opts...) + err := c.cc.Invoke(ctx, "/grpc.Bridge/IsAutostartOn", in, out, opts...) if err != nil { return nil, err } @@ -246,7 +173,7 @@ func (c *bridgeClient) IsAutostartOn(ctx context.Context, in *emptypb.Empty, opt func (c *bridgeClient) SetIsBetaEnabled(ctx context.Context, in *wrapperspb.BoolValue, opts ...grpc.CallOption) (*emptypb.Empty, error) { out := new(emptypb.Empty) - err := c.cc.Invoke(ctx, Bridge_SetIsBetaEnabled_FullMethodName, in, out, opts...) + err := c.cc.Invoke(ctx, "/grpc.Bridge/SetIsBetaEnabled", in, out, opts...) if err != nil { return nil, err } @@ -255,7 +182,7 @@ func (c *bridgeClient) SetIsBetaEnabled(ctx context.Context, in *wrapperspb.Bool func (c *bridgeClient) IsBetaEnabled(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*wrapperspb.BoolValue, error) { out := new(wrapperspb.BoolValue) - err := c.cc.Invoke(ctx, Bridge_IsBetaEnabled_FullMethodName, in, out, opts...) + err := c.cc.Invoke(ctx, "/grpc.Bridge/IsBetaEnabled", in, out, opts...) if err != nil { return nil, err } @@ -264,7 +191,7 @@ func (c *bridgeClient) IsBetaEnabled(ctx context.Context, in *emptypb.Empty, opt func (c *bridgeClient) SetIsAllMailVisible(ctx context.Context, in *wrapperspb.BoolValue, opts ...grpc.CallOption) (*emptypb.Empty, error) { out := new(emptypb.Empty) - err := c.cc.Invoke(ctx, Bridge_SetIsAllMailVisible_FullMethodName, in, out, opts...) + err := c.cc.Invoke(ctx, "/grpc.Bridge/SetIsAllMailVisible", in, out, opts...) if err != nil { return nil, err } @@ -273,7 +200,25 @@ func (c *bridgeClient) SetIsAllMailVisible(ctx context.Context, in *wrapperspb.B func (c *bridgeClient) IsAllMailVisible(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*wrapperspb.BoolValue, error) { out := new(wrapperspb.BoolValue) - err := c.cc.Invoke(ctx, Bridge_IsAllMailVisible_FullMethodName, in, out, opts...) + err := c.cc.Invoke(ctx, "/grpc.Bridge/IsAllMailVisible", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *bridgeClient) SetIsTelemetryDisabled(ctx context.Context, in *wrapperspb.BoolValue, opts ...grpc.CallOption) (*emptypb.Empty, error) { + out := new(emptypb.Empty) + err := c.cc.Invoke(ctx, "/grpc.Bridge/SetIsTelemetryDisabled", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *bridgeClient) IsTelemetryDisabled(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*wrapperspb.BoolValue, error) { + out := new(wrapperspb.BoolValue) + err := c.cc.Invoke(ctx, "/grpc.Bridge/IsTelemetryDisabled", in, out, opts...) if err != nil { return nil, err } @@ -282,7 +227,7 @@ func (c *bridgeClient) IsAllMailVisible(ctx context.Context, in *emptypb.Empty, func (c *bridgeClient) GoOs(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*wrapperspb.StringValue, error) { out := new(wrapperspb.StringValue) - err := c.cc.Invoke(ctx, Bridge_GoOs_FullMethodName, in, out, opts...) + err := c.cc.Invoke(ctx, "/grpc.Bridge/GoOs", in, out, opts...) if err != nil { return nil, err } @@ -291,7 +236,7 @@ func (c *bridgeClient) GoOs(ctx context.Context, in *emptypb.Empty, opts ...grpc func (c *bridgeClient) TriggerReset(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*emptypb.Empty, error) { out := new(emptypb.Empty) - err := c.cc.Invoke(ctx, Bridge_TriggerReset_FullMethodName, in, out, opts...) + err := c.cc.Invoke(ctx, "/grpc.Bridge/TriggerReset", in, out, opts...) if err != nil { return nil, err } @@ -300,7 +245,7 @@ func (c *bridgeClient) TriggerReset(ctx context.Context, in *emptypb.Empty, opts func (c *bridgeClient) Version(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*wrapperspb.StringValue, error) { out := new(wrapperspb.StringValue) - err := c.cc.Invoke(ctx, Bridge_Version_FullMethodName, in, out, opts...) + err := c.cc.Invoke(ctx, "/grpc.Bridge/Version", in, out, opts...) if err != nil { return nil, err } @@ -309,7 +254,7 @@ func (c *bridgeClient) Version(ctx context.Context, in *emptypb.Empty, opts ...g func (c *bridgeClient) LogsPath(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*wrapperspb.StringValue, error) { out := new(wrapperspb.StringValue) - err := c.cc.Invoke(ctx, Bridge_LogsPath_FullMethodName, in, out, opts...) + err := c.cc.Invoke(ctx, "/grpc.Bridge/LogsPath", in, out, opts...) if err != nil { return nil, err } @@ -318,7 +263,7 @@ func (c *bridgeClient) LogsPath(ctx context.Context, in *emptypb.Empty, opts ... func (c *bridgeClient) LicensePath(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*wrapperspb.StringValue, error) { out := new(wrapperspb.StringValue) - err := c.cc.Invoke(ctx, Bridge_LicensePath_FullMethodName, in, out, opts...) + err := c.cc.Invoke(ctx, "/grpc.Bridge/LicensePath", in, out, opts...) if err != nil { return nil, err } @@ -327,7 +272,7 @@ func (c *bridgeClient) LicensePath(ctx context.Context, in *emptypb.Empty, opts func (c *bridgeClient) ReleaseNotesPageLink(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*wrapperspb.StringValue, error) { out := new(wrapperspb.StringValue) - err := c.cc.Invoke(ctx, Bridge_ReleaseNotesPageLink_FullMethodName, in, out, opts...) + err := c.cc.Invoke(ctx, "/grpc.Bridge/ReleaseNotesPageLink", in, out, opts...) if err != nil { return nil, err } @@ -336,7 +281,7 @@ func (c *bridgeClient) ReleaseNotesPageLink(ctx context.Context, in *emptypb.Emp func (c *bridgeClient) DependencyLicensesLink(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*wrapperspb.StringValue, error) { out := new(wrapperspb.StringValue) - err := c.cc.Invoke(ctx, Bridge_DependencyLicensesLink_FullMethodName, in, out, opts...) + err := c.cc.Invoke(ctx, "/grpc.Bridge/DependencyLicensesLink", in, out, opts...) if err != nil { return nil, err } @@ -345,7 +290,7 @@ func (c *bridgeClient) DependencyLicensesLink(ctx context.Context, in *emptypb.E func (c *bridgeClient) LandingPageLink(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*wrapperspb.StringValue, error) { out := new(wrapperspb.StringValue) - err := c.cc.Invoke(ctx, Bridge_LandingPageLink_FullMethodName, in, out, opts...) + err := c.cc.Invoke(ctx, "/grpc.Bridge/LandingPageLink", in, out, opts...) if err != nil { return nil, err } @@ -354,7 +299,7 @@ func (c *bridgeClient) LandingPageLink(ctx context.Context, in *emptypb.Empty, o func (c *bridgeClient) SetColorSchemeName(ctx context.Context, in *wrapperspb.StringValue, opts ...grpc.CallOption) (*emptypb.Empty, error) { out := new(emptypb.Empty) - err := c.cc.Invoke(ctx, Bridge_SetColorSchemeName_FullMethodName, in, out, opts...) + err := c.cc.Invoke(ctx, "/grpc.Bridge/SetColorSchemeName", in, out, opts...) if err != nil { return nil, err } @@ -363,7 +308,7 @@ func (c *bridgeClient) SetColorSchemeName(ctx context.Context, in *wrapperspb.St func (c *bridgeClient) ColorSchemeName(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*wrapperspb.StringValue, error) { out := new(wrapperspb.StringValue) - err := c.cc.Invoke(ctx, Bridge_ColorSchemeName_FullMethodName, in, out, opts...) + err := c.cc.Invoke(ctx, "/grpc.Bridge/ColorSchemeName", in, out, opts...) if err != nil { return nil, err } @@ -372,7 +317,7 @@ func (c *bridgeClient) ColorSchemeName(ctx context.Context, in *emptypb.Empty, o func (c *bridgeClient) CurrentEmailClient(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*wrapperspb.StringValue, error) { out := new(wrapperspb.StringValue) - err := c.cc.Invoke(ctx, Bridge_CurrentEmailClient_FullMethodName, in, out, opts...) + err := c.cc.Invoke(ctx, "/grpc.Bridge/CurrentEmailClient", in, out, opts...) if err != nil { return nil, err } @@ -381,7 +326,7 @@ func (c *bridgeClient) CurrentEmailClient(ctx context.Context, in *emptypb.Empty func (c *bridgeClient) ReportBug(ctx context.Context, in *ReportBugRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) { out := new(emptypb.Empty) - err := c.cc.Invoke(ctx, Bridge_ReportBug_FullMethodName, in, out, opts...) + err := c.cc.Invoke(ctx, "/grpc.Bridge/ReportBug", in, out, opts...) if err != nil { return nil, err } @@ -390,7 +335,7 @@ func (c *bridgeClient) ReportBug(ctx context.Context, in *ReportBugRequest, opts func (c *bridgeClient) ExportTLSCertificates(ctx context.Context, in *wrapperspb.StringValue, opts ...grpc.CallOption) (*emptypb.Empty, error) { out := new(emptypb.Empty) - err := c.cc.Invoke(ctx, Bridge_ExportTLSCertificates_FullMethodName, in, out, opts...) + err := c.cc.Invoke(ctx, "/grpc.Bridge/ExportTLSCertificates", in, out, opts...) if err != nil { return nil, err } @@ -399,7 +344,7 @@ func (c *bridgeClient) ExportTLSCertificates(ctx context.Context, in *wrapperspb func (c *bridgeClient) ForceLauncher(ctx context.Context, in *wrapperspb.StringValue, opts ...grpc.CallOption) (*emptypb.Empty, error) { out := new(emptypb.Empty) - err := c.cc.Invoke(ctx, Bridge_ForceLauncher_FullMethodName, in, out, opts...) + err := c.cc.Invoke(ctx, "/grpc.Bridge/ForceLauncher", in, out, opts...) if err != nil { return nil, err } @@ -408,7 +353,7 @@ func (c *bridgeClient) ForceLauncher(ctx context.Context, in *wrapperspb.StringV func (c *bridgeClient) SetMainExecutable(ctx context.Context, in *wrapperspb.StringValue, opts ...grpc.CallOption) (*emptypb.Empty, error) { out := new(emptypb.Empty) - err := c.cc.Invoke(ctx, Bridge_SetMainExecutable_FullMethodName, in, out, opts...) + err := c.cc.Invoke(ctx, "/grpc.Bridge/SetMainExecutable", in, out, opts...) if err != nil { return nil, err } @@ -417,7 +362,7 @@ func (c *bridgeClient) SetMainExecutable(ctx context.Context, in *wrapperspb.Str func (c *bridgeClient) Login(ctx context.Context, in *LoginRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) { out := new(emptypb.Empty) - err := c.cc.Invoke(ctx, Bridge_Login_FullMethodName, in, out, opts...) + err := c.cc.Invoke(ctx, "/grpc.Bridge/Login", in, out, opts...) if err != nil { return nil, err } @@ -426,7 +371,7 @@ func (c *bridgeClient) Login(ctx context.Context, in *LoginRequest, opts ...grpc func (c *bridgeClient) Login2FA(ctx context.Context, in *LoginRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) { out := new(emptypb.Empty) - err := c.cc.Invoke(ctx, Bridge_Login2FA_FullMethodName, in, out, opts...) + err := c.cc.Invoke(ctx, "/grpc.Bridge/Login2FA", in, out, opts...) if err != nil { return nil, err } @@ -435,7 +380,7 @@ func (c *bridgeClient) Login2FA(ctx context.Context, in *LoginRequest, opts ...g func (c *bridgeClient) Login2Passwords(ctx context.Context, in *LoginRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) { out := new(emptypb.Empty) - err := c.cc.Invoke(ctx, Bridge_Login2Passwords_FullMethodName, in, out, opts...) + err := c.cc.Invoke(ctx, "/grpc.Bridge/Login2Passwords", in, out, opts...) if err != nil { return nil, err } @@ -444,7 +389,7 @@ func (c *bridgeClient) Login2Passwords(ctx context.Context, in *LoginRequest, op func (c *bridgeClient) LoginAbort(ctx context.Context, in *LoginAbortRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) { out := new(emptypb.Empty) - err := c.cc.Invoke(ctx, Bridge_LoginAbort_FullMethodName, in, out, opts...) + err := c.cc.Invoke(ctx, "/grpc.Bridge/LoginAbort", in, out, opts...) if err != nil { return nil, err } @@ -453,7 +398,7 @@ func (c *bridgeClient) LoginAbort(ctx context.Context, in *LoginAbortRequest, op func (c *bridgeClient) CheckUpdate(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*emptypb.Empty, error) { out := new(emptypb.Empty) - err := c.cc.Invoke(ctx, Bridge_CheckUpdate_FullMethodName, in, out, opts...) + err := c.cc.Invoke(ctx, "/grpc.Bridge/CheckUpdate", in, out, opts...) if err != nil { return nil, err } @@ -462,7 +407,7 @@ func (c *bridgeClient) CheckUpdate(ctx context.Context, in *emptypb.Empty, opts func (c *bridgeClient) InstallUpdate(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*emptypb.Empty, error) { out := new(emptypb.Empty) - err := c.cc.Invoke(ctx, Bridge_InstallUpdate_FullMethodName, in, out, opts...) + err := c.cc.Invoke(ctx, "/grpc.Bridge/InstallUpdate", in, out, opts...) if err != nil { return nil, err } @@ -471,7 +416,7 @@ func (c *bridgeClient) InstallUpdate(ctx context.Context, in *emptypb.Empty, opt func (c *bridgeClient) SetIsAutomaticUpdateOn(ctx context.Context, in *wrapperspb.BoolValue, opts ...grpc.CallOption) (*emptypb.Empty, error) { out := new(emptypb.Empty) - err := c.cc.Invoke(ctx, Bridge_SetIsAutomaticUpdateOn_FullMethodName, in, out, opts...) + err := c.cc.Invoke(ctx, "/grpc.Bridge/SetIsAutomaticUpdateOn", in, out, opts...) if err != nil { return nil, err } @@ -480,7 +425,7 @@ func (c *bridgeClient) SetIsAutomaticUpdateOn(ctx context.Context, in *wrappersp func (c *bridgeClient) IsAutomaticUpdateOn(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*wrapperspb.BoolValue, error) { out := new(wrapperspb.BoolValue) - err := c.cc.Invoke(ctx, Bridge_IsAutomaticUpdateOn_FullMethodName, in, out, opts...) + err := c.cc.Invoke(ctx, "/grpc.Bridge/IsAutomaticUpdateOn", in, out, opts...) if err != nil { return nil, err } @@ -489,7 +434,7 @@ func (c *bridgeClient) IsAutomaticUpdateOn(ctx context.Context, in *emptypb.Empt func (c *bridgeClient) DiskCachePath(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*wrapperspb.StringValue, error) { out := new(wrapperspb.StringValue) - err := c.cc.Invoke(ctx, Bridge_DiskCachePath_FullMethodName, in, out, opts...) + err := c.cc.Invoke(ctx, "/grpc.Bridge/DiskCachePath", in, out, opts...) if err != nil { return nil, err } @@ -498,7 +443,7 @@ func (c *bridgeClient) DiskCachePath(ctx context.Context, in *emptypb.Empty, opt func (c *bridgeClient) SetDiskCachePath(ctx context.Context, in *wrapperspb.StringValue, opts ...grpc.CallOption) (*emptypb.Empty, error) { out := new(emptypb.Empty) - err := c.cc.Invoke(ctx, Bridge_SetDiskCachePath_FullMethodName, in, out, opts...) + err := c.cc.Invoke(ctx, "/grpc.Bridge/SetDiskCachePath", in, out, opts...) if err != nil { return nil, err } @@ -507,7 +452,7 @@ func (c *bridgeClient) SetDiskCachePath(ctx context.Context, in *wrapperspb.Stri func (c *bridgeClient) SetIsDoHEnabled(ctx context.Context, in *wrapperspb.BoolValue, opts ...grpc.CallOption) (*emptypb.Empty, error) { out := new(emptypb.Empty) - err := c.cc.Invoke(ctx, Bridge_SetIsDoHEnabled_FullMethodName, in, out, opts...) + err := c.cc.Invoke(ctx, "/grpc.Bridge/SetIsDoHEnabled", in, out, opts...) if err != nil { return nil, err } @@ -516,7 +461,7 @@ func (c *bridgeClient) SetIsDoHEnabled(ctx context.Context, in *wrapperspb.BoolV func (c *bridgeClient) IsDoHEnabled(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*wrapperspb.BoolValue, error) { out := new(wrapperspb.BoolValue) - err := c.cc.Invoke(ctx, Bridge_IsDoHEnabled_FullMethodName, in, out, opts...) + err := c.cc.Invoke(ctx, "/grpc.Bridge/IsDoHEnabled", in, out, opts...) if err != nil { return nil, err } @@ -525,7 +470,7 @@ func (c *bridgeClient) IsDoHEnabled(ctx context.Context, in *emptypb.Empty, opts func (c *bridgeClient) MailServerSettings(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*ImapSmtpSettings, error) { out := new(ImapSmtpSettings) - err := c.cc.Invoke(ctx, Bridge_MailServerSettings_FullMethodName, in, out, opts...) + err := c.cc.Invoke(ctx, "/grpc.Bridge/MailServerSettings", in, out, opts...) if err != nil { return nil, err } @@ -534,7 +479,7 @@ func (c *bridgeClient) MailServerSettings(ctx context.Context, in *emptypb.Empty func (c *bridgeClient) SetMailServerSettings(ctx context.Context, in *ImapSmtpSettings, opts ...grpc.CallOption) (*emptypb.Empty, error) { out := new(emptypb.Empty) - err := c.cc.Invoke(ctx, Bridge_SetMailServerSettings_FullMethodName, in, out, opts...) + err := c.cc.Invoke(ctx, "/grpc.Bridge/SetMailServerSettings", in, out, opts...) if err != nil { return nil, err } @@ -543,7 +488,7 @@ func (c *bridgeClient) SetMailServerSettings(ctx context.Context, in *ImapSmtpSe func (c *bridgeClient) Hostname(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*wrapperspb.StringValue, error) { out := new(wrapperspb.StringValue) - err := c.cc.Invoke(ctx, Bridge_Hostname_FullMethodName, in, out, opts...) + err := c.cc.Invoke(ctx, "/grpc.Bridge/Hostname", in, out, opts...) if err != nil { return nil, err } @@ -552,7 +497,7 @@ func (c *bridgeClient) Hostname(ctx context.Context, in *emptypb.Empty, opts ... func (c *bridgeClient) IsPortFree(ctx context.Context, in *wrapperspb.Int32Value, opts ...grpc.CallOption) (*wrapperspb.BoolValue, error) { out := new(wrapperspb.BoolValue) - err := c.cc.Invoke(ctx, Bridge_IsPortFree_FullMethodName, in, out, opts...) + err := c.cc.Invoke(ctx, "/grpc.Bridge/IsPortFree", in, out, opts...) if err != nil { return nil, err } @@ -561,7 +506,7 @@ func (c *bridgeClient) IsPortFree(ctx context.Context, in *wrapperspb.Int32Value func (c *bridgeClient) AvailableKeychains(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*AvailableKeychainsResponse, error) { out := new(AvailableKeychainsResponse) - err := c.cc.Invoke(ctx, Bridge_AvailableKeychains_FullMethodName, in, out, opts...) + err := c.cc.Invoke(ctx, "/grpc.Bridge/AvailableKeychains", in, out, opts...) if err != nil { return nil, err } @@ -570,7 +515,7 @@ func (c *bridgeClient) AvailableKeychains(ctx context.Context, in *emptypb.Empty func (c *bridgeClient) SetCurrentKeychain(ctx context.Context, in *wrapperspb.StringValue, opts ...grpc.CallOption) (*emptypb.Empty, error) { out := new(emptypb.Empty) - err := c.cc.Invoke(ctx, Bridge_SetCurrentKeychain_FullMethodName, in, out, opts...) + err := c.cc.Invoke(ctx, "/grpc.Bridge/SetCurrentKeychain", in, out, opts...) if err != nil { return nil, err } @@ -579,7 +524,7 @@ func (c *bridgeClient) SetCurrentKeychain(ctx context.Context, in *wrapperspb.St func (c *bridgeClient) CurrentKeychain(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*wrapperspb.StringValue, error) { out := new(wrapperspb.StringValue) - err := c.cc.Invoke(ctx, Bridge_CurrentKeychain_FullMethodName, in, out, opts...) + err := c.cc.Invoke(ctx, "/grpc.Bridge/CurrentKeychain", in, out, opts...) if err != nil { return nil, err } @@ -588,7 +533,7 @@ func (c *bridgeClient) CurrentKeychain(ctx context.Context, in *emptypb.Empty, o func (c *bridgeClient) GetUserList(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*UserListResponse, error) { out := new(UserListResponse) - err := c.cc.Invoke(ctx, Bridge_GetUserList_FullMethodName, in, out, opts...) + err := c.cc.Invoke(ctx, "/grpc.Bridge/GetUserList", in, out, opts...) if err != nil { return nil, err } @@ -597,7 +542,7 @@ func (c *bridgeClient) GetUserList(ctx context.Context, in *emptypb.Empty, opts func (c *bridgeClient) GetUser(ctx context.Context, in *wrapperspb.StringValue, opts ...grpc.CallOption) (*User, error) { out := new(User) - err := c.cc.Invoke(ctx, Bridge_GetUser_FullMethodName, in, out, opts...) + err := c.cc.Invoke(ctx, "/grpc.Bridge/GetUser", in, out, opts...) if err != nil { return nil, err } @@ -606,7 +551,7 @@ func (c *bridgeClient) GetUser(ctx context.Context, in *wrapperspb.StringValue, func (c *bridgeClient) SetUserSplitMode(ctx context.Context, in *UserSplitModeRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) { out := new(emptypb.Empty) - err := c.cc.Invoke(ctx, Bridge_SetUserSplitMode_FullMethodName, in, out, opts...) + err := c.cc.Invoke(ctx, "/grpc.Bridge/SetUserSplitMode", in, out, opts...) if err != nil { return nil, err } @@ -615,7 +560,7 @@ func (c *bridgeClient) SetUserSplitMode(ctx context.Context, in *UserSplitModeRe func (c *bridgeClient) SendBadEventUserFeedback(ctx context.Context, in *UserBadEventFeedbackRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) { out := new(emptypb.Empty) - err := c.cc.Invoke(ctx, Bridge_SendBadEventUserFeedback_FullMethodName, in, out, opts...) + err := c.cc.Invoke(ctx, "/grpc.Bridge/SendBadEventUserFeedback", in, out, opts...) if err != nil { return nil, err } @@ -624,7 +569,7 @@ func (c *bridgeClient) SendBadEventUserFeedback(ctx context.Context, in *UserBad func (c *bridgeClient) LogoutUser(ctx context.Context, in *wrapperspb.StringValue, opts ...grpc.CallOption) (*emptypb.Empty, error) { out := new(emptypb.Empty) - err := c.cc.Invoke(ctx, Bridge_LogoutUser_FullMethodName, in, out, opts...) + err := c.cc.Invoke(ctx, "/grpc.Bridge/LogoutUser", in, out, opts...) if err != nil { return nil, err } @@ -633,7 +578,7 @@ func (c *bridgeClient) LogoutUser(ctx context.Context, in *wrapperspb.StringValu func (c *bridgeClient) RemoveUser(ctx context.Context, in *wrapperspb.StringValue, opts ...grpc.CallOption) (*emptypb.Empty, error) { out := new(emptypb.Empty) - err := c.cc.Invoke(ctx, Bridge_RemoveUser_FullMethodName, in, out, opts...) + err := c.cc.Invoke(ctx, "/grpc.Bridge/RemoveUser", in, out, opts...) if err != nil { return nil, err } @@ -642,7 +587,7 @@ func (c *bridgeClient) RemoveUser(ctx context.Context, in *wrapperspb.StringValu func (c *bridgeClient) ConfigureUserAppleMail(ctx context.Context, in *ConfigureAppleMailRequest, opts ...grpc.CallOption) (*emptypb.Empty, error) { out := new(emptypb.Empty) - err := c.cc.Invoke(ctx, Bridge_ConfigureUserAppleMail_FullMethodName, in, out, opts...) + err := c.cc.Invoke(ctx, "/grpc.Bridge/ConfigureUserAppleMail", in, out, opts...) if err != nil { return nil, err } @@ -650,7 +595,7 @@ func (c *bridgeClient) ConfigureUserAppleMail(ctx context.Context, in *Configure } func (c *bridgeClient) RunEventStream(ctx context.Context, in *EventStreamRequest, opts ...grpc.CallOption) (Bridge_RunEventStreamClient, error) { - stream, err := c.cc.NewStream(ctx, &Bridge_ServiceDesc.Streams[0], Bridge_RunEventStream_FullMethodName, opts...) + stream, err := c.cc.NewStream(ctx, &Bridge_ServiceDesc.Streams[0], "/grpc.Bridge/RunEventStream", opts...) if err != nil { return nil, err } @@ -683,7 +628,7 @@ func (x *bridgeRunEventStreamClient) Recv() (*StreamEvent, error) { func (c *bridgeClient) StopEventStream(ctx context.Context, in *emptypb.Empty, opts ...grpc.CallOption) (*emptypb.Empty, error) { out := new(emptypb.Empty) - err := c.cc.Invoke(ctx, Bridge_StopEventStream_FullMethodName, in, out, opts...) + err := c.cc.Invoke(ctx, "/grpc.Bridge/StopEventStream", in, out, opts...) if err != nil { return nil, err } @@ -707,6 +652,8 @@ type BridgeServer interface { IsBetaEnabled(context.Context, *emptypb.Empty) (*wrapperspb.BoolValue, error) SetIsAllMailVisible(context.Context, *wrapperspb.BoolValue) (*emptypb.Empty, error) IsAllMailVisible(context.Context, *emptypb.Empty) (*wrapperspb.BoolValue, error) + SetIsTelemetryDisabled(context.Context, *wrapperspb.BoolValue) (*emptypb.Empty, error) + IsTelemetryDisabled(context.Context, *emptypb.Empty) (*wrapperspb.BoolValue, error) GoOs(context.Context, *emptypb.Empty) (*wrapperspb.StringValue, error) TriggerReset(context.Context, *emptypb.Empty) (*emptypb.Empty, error) Version(context.Context, *emptypb.Empty) (*wrapperspb.StringValue, error) @@ -800,6 +747,12 @@ func (UnimplementedBridgeServer) SetIsAllMailVisible(context.Context, *wrappersp func (UnimplementedBridgeServer) IsAllMailVisible(context.Context, *emptypb.Empty) (*wrapperspb.BoolValue, error) { return nil, status.Errorf(codes.Unimplemented, "method IsAllMailVisible not implemented") } +func (UnimplementedBridgeServer) SetIsTelemetryDisabled(context.Context, *wrapperspb.BoolValue) (*emptypb.Empty, error) { + return nil, status.Errorf(codes.Unimplemented, "method SetIsTelemetryDisabled not implemented") +} +func (UnimplementedBridgeServer) IsTelemetryDisabled(context.Context, *emptypb.Empty) (*wrapperspb.BoolValue, error) { + return nil, status.Errorf(codes.Unimplemented, "method IsTelemetryDisabled not implemented") +} func (UnimplementedBridgeServer) GoOs(context.Context, *emptypb.Empty) (*wrapperspb.StringValue, error) { return nil, status.Errorf(codes.Unimplemented, "method GoOs not implemented") } @@ -952,7 +905,7 @@ func _Bridge_CheckTokens_Handler(srv interface{}, ctx context.Context, dec func( } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: Bridge_CheckTokens_FullMethodName, + FullMethod: "/grpc.Bridge/CheckTokens", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(BridgeServer).CheckTokens(ctx, req.(*wrapperspb.StringValue)) @@ -970,7 +923,7 @@ func _Bridge_AddLogEntry_Handler(srv interface{}, ctx context.Context, dec func( } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: Bridge_AddLogEntry_FullMethodName, + FullMethod: "/grpc.Bridge/AddLogEntry", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(BridgeServer).AddLogEntry(ctx, req.(*AddLogEntryRequest)) @@ -988,7 +941,7 @@ func _Bridge_GuiReady_Handler(srv interface{}, ctx context.Context, dec func(int } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: Bridge_GuiReady_FullMethodName, + FullMethod: "/grpc.Bridge/GuiReady", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(BridgeServer).GuiReady(ctx, req.(*emptypb.Empty)) @@ -1006,7 +959,7 @@ func _Bridge_Quit_Handler(srv interface{}, ctx context.Context, dec func(interfa } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: Bridge_Quit_FullMethodName, + FullMethod: "/grpc.Bridge/Quit", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(BridgeServer).Quit(ctx, req.(*emptypb.Empty)) @@ -1024,7 +977,7 @@ func _Bridge_Restart_Handler(srv interface{}, ctx context.Context, dec func(inte } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: Bridge_Restart_FullMethodName, + FullMethod: "/grpc.Bridge/Restart", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(BridgeServer).Restart(ctx, req.(*emptypb.Empty)) @@ -1042,7 +995,7 @@ func _Bridge_ShowOnStartup_Handler(srv interface{}, ctx context.Context, dec fun } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: Bridge_ShowOnStartup_FullMethodName, + FullMethod: "/grpc.Bridge/ShowOnStartup", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(BridgeServer).ShowOnStartup(ctx, req.(*emptypb.Empty)) @@ -1060,7 +1013,7 @@ func _Bridge_SetIsAutostartOn_Handler(srv interface{}, ctx context.Context, dec } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: Bridge_SetIsAutostartOn_FullMethodName, + FullMethod: "/grpc.Bridge/SetIsAutostartOn", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(BridgeServer).SetIsAutostartOn(ctx, req.(*wrapperspb.BoolValue)) @@ -1078,7 +1031,7 @@ func _Bridge_IsAutostartOn_Handler(srv interface{}, ctx context.Context, dec fun } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: Bridge_IsAutostartOn_FullMethodName, + FullMethod: "/grpc.Bridge/IsAutostartOn", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(BridgeServer).IsAutostartOn(ctx, req.(*emptypb.Empty)) @@ -1096,7 +1049,7 @@ func _Bridge_SetIsBetaEnabled_Handler(srv interface{}, ctx context.Context, dec } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: Bridge_SetIsBetaEnabled_FullMethodName, + FullMethod: "/grpc.Bridge/SetIsBetaEnabled", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(BridgeServer).SetIsBetaEnabled(ctx, req.(*wrapperspb.BoolValue)) @@ -1114,7 +1067,7 @@ func _Bridge_IsBetaEnabled_Handler(srv interface{}, ctx context.Context, dec fun } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: Bridge_IsBetaEnabled_FullMethodName, + FullMethod: "/grpc.Bridge/IsBetaEnabled", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(BridgeServer).IsBetaEnabled(ctx, req.(*emptypb.Empty)) @@ -1132,7 +1085,7 @@ func _Bridge_SetIsAllMailVisible_Handler(srv interface{}, ctx context.Context, d } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: Bridge_SetIsAllMailVisible_FullMethodName, + FullMethod: "/grpc.Bridge/SetIsAllMailVisible", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(BridgeServer).SetIsAllMailVisible(ctx, req.(*wrapperspb.BoolValue)) @@ -1150,7 +1103,7 @@ func _Bridge_IsAllMailVisible_Handler(srv interface{}, ctx context.Context, dec } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: Bridge_IsAllMailVisible_FullMethodName, + FullMethod: "/grpc.Bridge/IsAllMailVisible", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(BridgeServer).IsAllMailVisible(ctx, req.(*emptypb.Empty)) @@ -1158,6 +1111,42 @@ func _Bridge_IsAllMailVisible_Handler(srv interface{}, ctx context.Context, dec return interceptor(ctx, in, info, handler) } +func _Bridge_SetIsTelemetryDisabled_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(wrapperspb.BoolValue) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(BridgeServer).SetIsTelemetryDisabled(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/grpc.Bridge/SetIsTelemetryDisabled", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(BridgeServer).SetIsTelemetryDisabled(ctx, req.(*wrapperspb.BoolValue)) + } + return interceptor(ctx, in, info, handler) +} + +func _Bridge_IsTelemetryDisabled_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(emptypb.Empty) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(BridgeServer).IsTelemetryDisabled(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/grpc.Bridge/IsTelemetryDisabled", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(BridgeServer).IsTelemetryDisabled(ctx, req.(*emptypb.Empty)) + } + return interceptor(ctx, in, info, handler) +} + func _Bridge_GoOs_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { in := new(emptypb.Empty) if err := dec(in); err != nil { @@ -1168,7 +1157,7 @@ func _Bridge_GoOs_Handler(srv interface{}, ctx context.Context, dec func(interfa } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: Bridge_GoOs_FullMethodName, + FullMethod: "/grpc.Bridge/GoOs", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(BridgeServer).GoOs(ctx, req.(*emptypb.Empty)) @@ -1186,7 +1175,7 @@ func _Bridge_TriggerReset_Handler(srv interface{}, ctx context.Context, dec func } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: Bridge_TriggerReset_FullMethodName, + FullMethod: "/grpc.Bridge/TriggerReset", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(BridgeServer).TriggerReset(ctx, req.(*emptypb.Empty)) @@ -1204,7 +1193,7 @@ func _Bridge_Version_Handler(srv interface{}, ctx context.Context, dec func(inte } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: Bridge_Version_FullMethodName, + FullMethod: "/grpc.Bridge/Version", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(BridgeServer).Version(ctx, req.(*emptypb.Empty)) @@ -1222,7 +1211,7 @@ func _Bridge_LogsPath_Handler(srv interface{}, ctx context.Context, dec func(int } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: Bridge_LogsPath_FullMethodName, + FullMethod: "/grpc.Bridge/LogsPath", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(BridgeServer).LogsPath(ctx, req.(*emptypb.Empty)) @@ -1240,7 +1229,7 @@ func _Bridge_LicensePath_Handler(srv interface{}, ctx context.Context, dec func( } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: Bridge_LicensePath_FullMethodName, + FullMethod: "/grpc.Bridge/LicensePath", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(BridgeServer).LicensePath(ctx, req.(*emptypb.Empty)) @@ -1258,7 +1247,7 @@ func _Bridge_ReleaseNotesPageLink_Handler(srv interface{}, ctx context.Context, } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: Bridge_ReleaseNotesPageLink_FullMethodName, + FullMethod: "/grpc.Bridge/ReleaseNotesPageLink", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(BridgeServer).ReleaseNotesPageLink(ctx, req.(*emptypb.Empty)) @@ -1276,7 +1265,7 @@ func _Bridge_DependencyLicensesLink_Handler(srv interface{}, ctx context.Context } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: Bridge_DependencyLicensesLink_FullMethodName, + FullMethod: "/grpc.Bridge/DependencyLicensesLink", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(BridgeServer).DependencyLicensesLink(ctx, req.(*emptypb.Empty)) @@ -1294,7 +1283,7 @@ func _Bridge_LandingPageLink_Handler(srv interface{}, ctx context.Context, dec f } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: Bridge_LandingPageLink_FullMethodName, + FullMethod: "/grpc.Bridge/LandingPageLink", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(BridgeServer).LandingPageLink(ctx, req.(*emptypb.Empty)) @@ -1312,7 +1301,7 @@ func _Bridge_SetColorSchemeName_Handler(srv interface{}, ctx context.Context, de } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: Bridge_SetColorSchemeName_FullMethodName, + FullMethod: "/grpc.Bridge/SetColorSchemeName", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(BridgeServer).SetColorSchemeName(ctx, req.(*wrapperspb.StringValue)) @@ -1330,7 +1319,7 @@ func _Bridge_ColorSchemeName_Handler(srv interface{}, ctx context.Context, dec f } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: Bridge_ColorSchemeName_FullMethodName, + FullMethod: "/grpc.Bridge/ColorSchemeName", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(BridgeServer).ColorSchemeName(ctx, req.(*emptypb.Empty)) @@ -1348,7 +1337,7 @@ func _Bridge_CurrentEmailClient_Handler(srv interface{}, ctx context.Context, de } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: Bridge_CurrentEmailClient_FullMethodName, + FullMethod: "/grpc.Bridge/CurrentEmailClient", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(BridgeServer).CurrentEmailClient(ctx, req.(*emptypb.Empty)) @@ -1366,7 +1355,7 @@ func _Bridge_ReportBug_Handler(srv interface{}, ctx context.Context, dec func(in } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: Bridge_ReportBug_FullMethodName, + FullMethod: "/grpc.Bridge/ReportBug", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(BridgeServer).ReportBug(ctx, req.(*ReportBugRequest)) @@ -1384,7 +1373,7 @@ func _Bridge_ExportTLSCertificates_Handler(srv interface{}, ctx context.Context, } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: Bridge_ExportTLSCertificates_FullMethodName, + FullMethod: "/grpc.Bridge/ExportTLSCertificates", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(BridgeServer).ExportTLSCertificates(ctx, req.(*wrapperspb.StringValue)) @@ -1402,7 +1391,7 @@ func _Bridge_ForceLauncher_Handler(srv interface{}, ctx context.Context, dec fun } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: Bridge_ForceLauncher_FullMethodName, + FullMethod: "/grpc.Bridge/ForceLauncher", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(BridgeServer).ForceLauncher(ctx, req.(*wrapperspb.StringValue)) @@ -1420,7 +1409,7 @@ func _Bridge_SetMainExecutable_Handler(srv interface{}, ctx context.Context, dec } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: Bridge_SetMainExecutable_FullMethodName, + FullMethod: "/grpc.Bridge/SetMainExecutable", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(BridgeServer).SetMainExecutable(ctx, req.(*wrapperspb.StringValue)) @@ -1438,7 +1427,7 @@ func _Bridge_Login_Handler(srv interface{}, ctx context.Context, dec func(interf } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: Bridge_Login_FullMethodName, + FullMethod: "/grpc.Bridge/Login", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(BridgeServer).Login(ctx, req.(*LoginRequest)) @@ -1456,7 +1445,7 @@ func _Bridge_Login2FA_Handler(srv interface{}, ctx context.Context, dec func(int } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: Bridge_Login2FA_FullMethodName, + FullMethod: "/grpc.Bridge/Login2FA", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(BridgeServer).Login2FA(ctx, req.(*LoginRequest)) @@ -1474,7 +1463,7 @@ func _Bridge_Login2Passwords_Handler(srv interface{}, ctx context.Context, dec f } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: Bridge_Login2Passwords_FullMethodName, + FullMethod: "/grpc.Bridge/Login2Passwords", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(BridgeServer).Login2Passwords(ctx, req.(*LoginRequest)) @@ -1492,7 +1481,7 @@ func _Bridge_LoginAbort_Handler(srv interface{}, ctx context.Context, dec func(i } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: Bridge_LoginAbort_FullMethodName, + FullMethod: "/grpc.Bridge/LoginAbort", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(BridgeServer).LoginAbort(ctx, req.(*LoginAbortRequest)) @@ -1510,7 +1499,7 @@ func _Bridge_CheckUpdate_Handler(srv interface{}, ctx context.Context, dec func( } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: Bridge_CheckUpdate_FullMethodName, + FullMethod: "/grpc.Bridge/CheckUpdate", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(BridgeServer).CheckUpdate(ctx, req.(*emptypb.Empty)) @@ -1528,7 +1517,7 @@ func _Bridge_InstallUpdate_Handler(srv interface{}, ctx context.Context, dec fun } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: Bridge_InstallUpdate_FullMethodName, + FullMethod: "/grpc.Bridge/InstallUpdate", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(BridgeServer).InstallUpdate(ctx, req.(*emptypb.Empty)) @@ -1546,7 +1535,7 @@ func _Bridge_SetIsAutomaticUpdateOn_Handler(srv interface{}, ctx context.Context } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: Bridge_SetIsAutomaticUpdateOn_FullMethodName, + FullMethod: "/grpc.Bridge/SetIsAutomaticUpdateOn", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(BridgeServer).SetIsAutomaticUpdateOn(ctx, req.(*wrapperspb.BoolValue)) @@ -1564,7 +1553,7 @@ func _Bridge_IsAutomaticUpdateOn_Handler(srv interface{}, ctx context.Context, d } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: Bridge_IsAutomaticUpdateOn_FullMethodName, + FullMethod: "/grpc.Bridge/IsAutomaticUpdateOn", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(BridgeServer).IsAutomaticUpdateOn(ctx, req.(*emptypb.Empty)) @@ -1582,7 +1571,7 @@ func _Bridge_DiskCachePath_Handler(srv interface{}, ctx context.Context, dec fun } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: Bridge_DiskCachePath_FullMethodName, + FullMethod: "/grpc.Bridge/DiskCachePath", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(BridgeServer).DiskCachePath(ctx, req.(*emptypb.Empty)) @@ -1600,7 +1589,7 @@ func _Bridge_SetDiskCachePath_Handler(srv interface{}, ctx context.Context, dec } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: Bridge_SetDiskCachePath_FullMethodName, + FullMethod: "/grpc.Bridge/SetDiskCachePath", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(BridgeServer).SetDiskCachePath(ctx, req.(*wrapperspb.StringValue)) @@ -1618,7 +1607,7 @@ func _Bridge_SetIsDoHEnabled_Handler(srv interface{}, ctx context.Context, dec f } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: Bridge_SetIsDoHEnabled_FullMethodName, + FullMethod: "/grpc.Bridge/SetIsDoHEnabled", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(BridgeServer).SetIsDoHEnabled(ctx, req.(*wrapperspb.BoolValue)) @@ -1636,7 +1625,7 @@ func _Bridge_IsDoHEnabled_Handler(srv interface{}, ctx context.Context, dec func } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: Bridge_IsDoHEnabled_FullMethodName, + FullMethod: "/grpc.Bridge/IsDoHEnabled", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(BridgeServer).IsDoHEnabled(ctx, req.(*emptypb.Empty)) @@ -1654,7 +1643,7 @@ func _Bridge_MailServerSettings_Handler(srv interface{}, ctx context.Context, de } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: Bridge_MailServerSettings_FullMethodName, + FullMethod: "/grpc.Bridge/MailServerSettings", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(BridgeServer).MailServerSettings(ctx, req.(*emptypb.Empty)) @@ -1672,7 +1661,7 @@ func _Bridge_SetMailServerSettings_Handler(srv interface{}, ctx context.Context, } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: Bridge_SetMailServerSettings_FullMethodName, + FullMethod: "/grpc.Bridge/SetMailServerSettings", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(BridgeServer).SetMailServerSettings(ctx, req.(*ImapSmtpSettings)) @@ -1690,7 +1679,7 @@ func _Bridge_Hostname_Handler(srv interface{}, ctx context.Context, dec func(int } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: Bridge_Hostname_FullMethodName, + FullMethod: "/grpc.Bridge/Hostname", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(BridgeServer).Hostname(ctx, req.(*emptypb.Empty)) @@ -1708,7 +1697,7 @@ func _Bridge_IsPortFree_Handler(srv interface{}, ctx context.Context, dec func(i } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: Bridge_IsPortFree_FullMethodName, + FullMethod: "/grpc.Bridge/IsPortFree", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(BridgeServer).IsPortFree(ctx, req.(*wrapperspb.Int32Value)) @@ -1726,7 +1715,7 @@ func _Bridge_AvailableKeychains_Handler(srv interface{}, ctx context.Context, de } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: Bridge_AvailableKeychains_FullMethodName, + FullMethod: "/grpc.Bridge/AvailableKeychains", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(BridgeServer).AvailableKeychains(ctx, req.(*emptypb.Empty)) @@ -1744,7 +1733,7 @@ func _Bridge_SetCurrentKeychain_Handler(srv interface{}, ctx context.Context, de } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: Bridge_SetCurrentKeychain_FullMethodName, + FullMethod: "/grpc.Bridge/SetCurrentKeychain", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(BridgeServer).SetCurrentKeychain(ctx, req.(*wrapperspb.StringValue)) @@ -1762,7 +1751,7 @@ func _Bridge_CurrentKeychain_Handler(srv interface{}, ctx context.Context, dec f } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: Bridge_CurrentKeychain_FullMethodName, + FullMethod: "/grpc.Bridge/CurrentKeychain", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(BridgeServer).CurrentKeychain(ctx, req.(*emptypb.Empty)) @@ -1780,7 +1769,7 @@ func _Bridge_GetUserList_Handler(srv interface{}, ctx context.Context, dec func( } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: Bridge_GetUserList_FullMethodName, + FullMethod: "/grpc.Bridge/GetUserList", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(BridgeServer).GetUserList(ctx, req.(*emptypb.Empty)) @@ -1798,7 +1787,7 @@ func _Bridge_GetUser_Handler(srv interface{}, ctx context.Context, dec func(inte } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: Bridge_GetUser_FullMethodName, + FullMethod: "/grpc.Bridge/GetUser", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(BridgeServer).GetUser(ctx, req.(*wrapperspb.StringValue)) @@ -1816,7 +1805,7 @@ func _Bridge_SetUserSplitMode_Handler(srv interface{}, ctx context.Context, dec } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: Bridge_SetUserSplitMode_FullMethodName, + FullMethod: "/grpc.Bridge/SetUserSplitMode", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(BridgeServer).SetUserSplitMode(ctx, req.(*UserSplitModeRequest)) @@ -1834,7 +1823,7 @@ func _Bridge_SendBadEventUserFeedback_Handler(srv interface{}, ctx context.Conte } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: Bridge_SendBadEventUserFeedback_FullMethodName, + FullMethod: "/grpc.Bridge/SendBadEventUserFeedback", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(BridgeServer).SendBadEventUserFeedback(ctx, req.(*UserBadEventFeedbackRequest)) @@ -1852,7 +1841,7 @@ func _Bridge_LogoutUser_Handler(srv interface{}, ctx context.Context, dec func(i } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: Bridge_LogoutUser_FullMethodName, + FullMethod: "/grpc.Bridge/LogoutUser", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(BridgeServer).LogoutUser(ctx, req.(*wrapperspb.StringValue)) @@ -1870,7 +1859,7 @@ func _Bridge_RemoveUser_Handler(srv interface{}, ctx context.Context, dec func(i } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: Bridge_RemoveUser_FullMethodName, + FullMethod: "/grpc.Bridge/RemoveUser", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(BridgeServer).RemoveUser(ctx, req.(*wrapperspb.StringValue)) @@ -1888,7 +1877,7 @@ func _Bridge_ConfigureUserAppleMail_Handler(srv interface{}, ctx context.Context } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: Bridge_ConfigureUserAppleMail_FullMethodName, + FullMethod: "/grpc.Bridge/ConfigureUserAppleMail", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(BridgeServer).ConfigureUserAppleMail(ctx, req.(*ConfigureAppleMailRequest)) @@ -1927,7 +1916,7 @@ func _Bridge_StopEventStream_Handler(srv interface{}, ctx context.Context, dec f } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: Bridge_StopEventStream_FullMethodName, + FullMethod: "/grpc.Bridge/StopEventStream", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { return srv.(BridgeServer).StopEventStream(ctx, req.(*emptypb.Empty)) @@ -1990,6 +1979,14 @@ var Bridge_ServiceDesc = grpc.ServiceDesc{ MethodName: "IsAllMailVisible", Handler: _Bridge_IsAllMailVisible_Handler, }, + { + MethodName: "SetIsTelemetryDisabled", + Handler: _Bridge_SetIsTelemetryDisabled_Handler, + }, + { + MethodName: "IsTelemetryDisabled", + Handler: _Bridge_IsTelemetryDisabled_Handler, + }, { MethodName: "GoOs", Handler: _Bridge_GoOs_Handler, diff --git a/internal/frontend/grpc/service_methods.go b/internal/frontend/grpc/service_methods.go index 0a4321ec..a49e698a 100644 --- a/internal/frontend/grpc/service_methods.go +++ b/internal/frontend/grpc/service_methods.go @@ -214,6 +214,23 @@ func (s *Service) IsAllMailVisible(ctx context.Context, _ *emptypb.Empty) (*wrap return wrapperspb.Bool(s.bridge.GetShowAllMail()), nil } +func (s *Service) SetIsTelemetryDisabled(_ context.Context, isDisabled *wrapperspb.BoolValue) (*emptypb.Empty, error) { + s.log.WithField("isEnabled", isDisabled.Value).Debug("SetIsTelemetryDisabled") + + if err := s.bridge.SetTelemetryDisabled(isDisabled.Value); err != nil { + s.log.WithError(err).Error("Failed to set telemetry status") + return nil, status.Errorf(codes.Internal, "failed to set telemetry status: %v", err) + } + + return &emptypb.Empty{}, nil +} + +func (s *Service) IsTelemetryDisabled(_ context.Context, _ *emptypb.Empty) (*wrapperspb.BoolValue, error) { + s.log.Debug("IsTelemetryDisabled") + + return wrapperspb.Bool(s.bridge.GetTelemetryDisabled()), nil +} + func (s *Service) GoOs(ctx context.Context, _ *emptypb.Empty) (*wrapperspb.StringValue, error) { s.log.Debug("GoOs") // TO-DO We can probably get rid of this and use QSysInfo::product name diff --git a/internal/frontend/bridge-gui/bridge-gui/qml/BridgeTest/UserModel.qml b/internal/sentry/lang_default.go similarity index 73% rename from internal/frontend/bridge-gui/bridge-gui/qml/BridgeTest/UserModel.qml rename to internal/sentry/lang_default.go index a8099aa7..a0ae29ec 100644 --- a/internal/frontend/bridge-gui/bridge-gui/qml/BridgeTest/UserModel.qml +++ b/internal/sentry/lang_default.go @@ -15,14 +15,18 @@ // You should have received a copy of the GNU General Public License // along with Proton Mail Bridge. If not, see . -import QtQml.Models +//go:build !windows +// +build !windows -ListModel { - // overriding get method to ignore any role and return directly object itself - function get(row) { - if (row < 0 || row >= count) { - return undefined - } - return data(index(row, 0), Qt.DisplayRole) - } +package sentry + +import "os" + +func GetSystemLang() string { + lang := os.Getenv("LC_ALL") + if lang == "" { + lang = os.Getenv("LANG") + } + + return lang } diff --git a/internal/sentry/lang_windows.go b/internal/sentry/lang_windows.go new file mode 100644 index 00000000..55abba85 --- /dev/null +++ b/internal/sentry/lang_windows.go @@ -0,0 +1,67 @@ +// Copyright (c) 2023 Proton AG +// +// This file is part of Proton Mail Bridge. +// +// Proton Mail Bridge is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Proton Mail Bridge is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Proton Mail Bridge. If not, see . + +//go:build windows +// +build windows + +package sentry + +import ( + "syscall" + "unsafe" +) + +const ( + defaultLocaleUser = "GetUserDefaultLocaleName" // https://learn.microsoft.com/en-us/windows/win32/api/winnls/nf-winnls-getuserdefaultlocalename + defaultLocaleSystem = "GetSystemDefaultLocaleName" // https://learn.microsoft.com/en-us/windows/win32/api/winnls/nf-winnls-getsystemdefaultlocalename + localeNameMaxLength = 85 // https://learn.microsoft.com/en-us/windows/win32/intl/locale-name-constants +) + +func getLocale(dll *syscall.DLL, procName string) (string, error) { + proc, err := dll.FindProc(procName) + if err != nil { + return "errProc", err + } + + b := make([]uint16, localeNameMaxLength) + + r, _, err := proc.Call(uintptr(unsafe.Pointer(&b[0])), uintptr(localeNameMaxLength)) + if r == 0 || err != nil { + return "errCall", err + } + + return syscall.UTF16ToString(b), nil +} + +func GetSystemLang() string { + dll, err := syscall.LoadDLL("kernel32") + if err != nil { + return "errDll" + } + + defer func() { + _ = dll.Release() + }() + + if lang, err := getLocale(dll, defaultLocaleUser); err == nil { + return lang + } + + lang, _ := getLocale(dll, defaultLocaleSystem) + + return lang +} diff --git a/internal/sentry/reporter.go b/internal/sentry/reporter.go index 055e55b7..1ceb084c 100644 --- a/internal/sentry/reporter.go +++ b/internal/sentry/reporter.go @@ -18,7 +18,6 @@ package sentry import ( - "crypto/sha256" "errors" "fmt" "log" @@ -29,6 +28,7 @@ import ( "github.com/Masterminds/semver/v3" "github.com/ProtonMail/gluon/reporter" "github.com/ProtonMail/proton-bridge/v3/internal/constants" + "github.com/ProtonMail/proton-bridge/v3/pkg/algo" "github.com/ProtonMail/proton-bridge/v3/pkg/restarter" "github.com/getsentry/sentry-go" "github.com/sirupsen/logrus" @@ -50,7 +50,7 @@ func init() { //nolint:gochecknoinits Release: constants.AppVersion(appVersion), BeforeSend: EnhanceSentryEvent, Transport: sentrySyncTransport, - ServerName: getProtectedHostname(), + ServerName: GetProtectedHostname(), Environment: constants.BuildEnv, MaxBreadcrumbs: 50, } @@ -61,7 +61,7 @@ func init() { //nolint:gochecknoinits sentry.ConfigureScope(func(scope *sentry.Scope) { scope.SetFingerprint([]string{"{{ default }}"}) - scope.SetUser(sentry.User{ID: getProtectedHostname()}) + scope.SetUser(sentry.User{ID: GetProtectedHostname()}) }) sentry.Logger = log.New( @@ -81,12 +81,17 @@ type Identifier interface { GetUserAgent() string } -func getProtectedHostname() string { +func GetProtectedHostname() string { hostname, err := os.Hostname() if err != nil { return "Unknown" } - return fmt.Sprintf("%x", sha256.Sum256([]byte(hostname))) + return algo.HashBase64SHA256(hostname) +} + +func GetTimeZone() string { + zone, offset := time.Now().Zone() + return fmt.Sprintf("%s%+d", zone, offset/3600) } // NewReporter creates new sentry reporter with appName and appVersion to report. diff --git a/internal/telemetry/heartbeat.go b/internal/telemetry/heartbeat.go new file mode 100644 index 00000000..00036e05 --- /dev/null +++ b/internal/telemetry/heartbeat.go @@ -0,0 +1,172 @@ +// Copyright (c) 2023 Proton AG +// +// This file is part of Proton Mail Bridge. +// +// Proton Mail Bridge is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Proton Mail Bridge is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Proton Mail Bridge. If not, see . + +package telemetry + +import ( + "strconv" + "time" + + "github.com/ProtonMail/proton-bridge/v3/internal/updater" + "github.com/sirupsen/logrus" +) + +func NewHeartbeat(manager HeartbeatManager, imapPort, smtpPort int, cacheDir, keychain string) Heartbeat { + heartbeat := Heartbeat{ + log: logrus.WithField("pkg", "telemetry"), + manager: manager, + metrics: HeartbeatData{ + MeasurementGroup: "bridge.any.usage", + Event: "bridge_heartbeat", + }, + defaultIMAPPort: imapPort, + defaultSMTPPort: smtpPort, + defaultCache: cacheDir, + defaultKeychain: keychain, + } + return heartbeat +} + +func (heartbeat *Heartbeat) SetRollout(val float64) { + heartbeat.metrics.Dimensions.Rollout = strconv.Itoa(int(val * 100)) +} + +func (heartbeat *Heartbeat) SetNbAccount(val int) { + heartbeat.metrics.Values.NbAccount = val +} + +func (heartbeat *Heartbeat) SetAutoUpdate(val bool) { + if val { + heartbeat.metrics.Dimensions.AutoUpdate = dimensionON + } else { + heartbeat.metrics.Dimensions.AutoUpdate = dimensionOFF + } +} + +func (heartbeat *Heartbeat) SetAutoStart(val bool) { + if val { + heartbeat.metrics.Dimensions.AutoStart = dimensionON + } else { + heartbeat.metrics.Dimensions.AutoStart = dimensionOFF + } +} + +func (heartbeat *Heartbeat) SetBeta(val updater.Channel) { + if val == updater.EarlyChannel { + heartbeat.metrics.Dimensions.Beta = dimensionON + } else { + heartbeat.metrics.Dimensions.Beta = dimensionOFF + } +} + +func (heartbeat *Heartbeat) SetDoh(val bool) { + if val { + heartbeat.metrics.Dimensions.Doh = dimensionON + } else { + heartbeat.metrics.Dimensions.Doh = dimensionOFF + } +} + +func (heartbeat *Heartbeat) SetSplitMode(val bool) { + if val { + heartbeat.metrics.Dimensions.SplitMode = dimensionON + } else { + heartbeat.metrics.Dimensions.SplitMode = dimensionOFF + } +} + +func (heartbeat *Heartbeat) SetShowAllMail(val bool) { + if val { + heartbeat.metrics.Dimensions.ShowAllMail = dimensionON + } else { + heartbeat.metrics.Dimensions.ShowAllMail = dimensionOFF + } +} + +func (heartbeat *Heartbeat) SetIMAPConnectionMode(val bool) { + if val { + heartbeat.metrics.Dimensions.IMAPConnectionMode = dimensionSSL + } else { + heartbeat.metrics.Dimensions.IMAPConnectionMode = dimensionStartTLS + } +} + +func (heartbeat *Heartbeat) SetSMTPConnectionMode(val bool) { + if val { + heartbeat.metrics.Dimensions.SMTPConnectionMode = dimensionSSL + } else { + heartbeat.metrics.Dimensions.SMTPConnectionMode = dimensionStartTLS + } +} + +func (heartbeat *Heartbeat) SetIMAPPort(val int) { + if val == heartbeat.defaultIMAPPort { + heartbeat.metrics.Dimensions.IMAPPort = dimensionDefault + } else { + heartbeat.metrics.Dimensions.IMAPPort = dimensionCustom + } +} + +func (heartbeat *Heartbeat) SetSMTPPort(val int) { + if val == heartbeat.defaultSMTPPort { + heartbeat.metrics.Dimensions.SMTPPort = dimensionDefault + } else { + heartbeat.metrics.Dimensions.SMTPPort = dimensionCustom + } +} + +func (heartbeat *Heartbeat) SetCacheLocation(val string) { + if val == heartbeat.defaultCache { + heartbeat.metrics.Dimensions.CacheLocation = dimensionDefault + } else { + heartbeat.metrics.Dimensions.CacheLocation = dimensionCustom + } +} + +func (heartbeat *Heartbeat) SetKeyChainPref(val string) { + if val == heartbeat.defaultKeychain { + heartbeat.metrics.Dimensions.KeychainPref = dimensionDefault + } else { + heartbeat.metrics.Dimensions.KeychainPref = dimensionCustom + } +} + +func (heartbeat *Heartbeat) SetPrevVersion(val string) { + heartbeat.metrics.Dimensions.PrevVersion = val +} + +func (heartbeat *Heartbeat) TrySending() { + if heartbeat.manager.IsTelemetryAvailable() { + lastSent := heartbeat.manager.GetLastHeartbeatSent() + now := time.Now() + if now.Year() > lastSent.Year() || (now.Year() == lastSent.Year() && now.YearDay() > lastSent.YearDay()) { + if !heartbeat.manager.SendHeartbeat(&heartbeat.metrics) { + heartbeat.log.WithFields(logrus.Fields{ + "metrics": heartbeat.metrics, + }).Error("Failed to send heartbeat") + return + } + heartbeat.log.WithFields(logrus.Fields{ + "metrics": heartbeat.metrics, + }).Info("Heartbeat sent") + + if err := heartbeat.manager.SetLastHeartbeatSent(now); err != nil { + heartbeat.log.WithError(err).Warn("Cannot save last heartbeat sent to the vault.") + } + } + } +} diff --git a/internal/telemetry/heartbeat_test.go b/internal/telemetry/heartbeat_test.go new file mode 100644 index 00000000..046b0d18 --- /dev/null +++ b/internal/telemetry/heartbeat_test.go @@ -0,0 +1,97 @@ +// Copyright (c) 2023 Proton AG +// +// This file is part of Proton Mail Bridge. +// +// Proton Mail Bridge is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Proton Mail Bridge is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Proton Mail Bridge. If not, see . + +package telemetry_test + +import ( + "testing" + "time" + + "github.com/ProtonMail/proton-bridge/v3/internal/telemetry" + "github.com/ProtonMail/proton-bridge/v3/internal/telemetry/mocks" + "github.com/golang/mock/gomock" +) + +func TestHeartbeat_default_heartbeat(t *testing.T) { + withHeartbeat(t, 1143, 1025, "/tmp", "defaultKeychain", func(hb *telemetry.Heartbeat, mock *mocks.MockHeartbeatManager) { + data := telemetry.HeartbeatData{ + MeasurementGroup: "bridge.any.usage", + Event: "bridge_heartbeat", + Values: telemetry.HeartbeatValues{ + NbAccount: 1, + }, + Dimensions: telemetry.HeartbeatDimensions{ + AutoUpdate: "on", + AutoStart: "on", + Beta: "off", + Doh: "off", + SplitMode: "off", + ShowAllMail: "off", + IMAPConnectionMode: "ssl", + SMTPConnectionMode: "ssl", + IMAPPort: "default", + SMTPPort: "default", + CacheLocation: "default", + KeychainPref: "default", + PrevVersion: "1.2.3", + Rollout: "10", + }, + } + + mock.EXPECT().IsTelemetryAvailable().Return(true) + mock.EXPECT().GetLastHeartbeatSent().Return(time.Date(2022, 6, 4, 0, 0, 0, 0, time.UTC)) + mock.EXPECT().SendHeartbeat(&data).Return(true) + mock.EXPECT().SetLastHeartbeatSent(gomock.Any()).Return(nil) + + hb.TrySending() + }) +} + +func TestHeartbeat_already_sent_heartbeat(t *testing.T) { + withHeartbeat(t, 1143, 1025, "/tmp", "defaultKeychain", func(hb *telemetry.Heartbeat, mock *mocks.MockHeartbeatManager) { + mock.EXPECT().IsTelemetryAvailable().Return(true) + mock.EXPECT().GetLastHeartbeatSent().Return(time.Now().Truncate(24 * time.Hour)) + + hb.TrySending() + }) +} + +func withHeartbeat(t *testing.T, imap, smtp int, cache, keychain string, tests func(hb *telemetry.Heartbeat, mock *mocks.MockHeartbeatManager)) { + ctl := gomock.NewController(t) + defer ctl.Finish() + + manager := mocks.NewMockHeartbeatManager(ctl) + heartbeat := telemetry.NewHeartbeat(manager, imap, smtp, cache, keychain) + + heartbeat.SetRollout(0.1) + heartbeat.SetNbAccount(1) + heartbeat.SetSplitMode(false) + heartbeat.SetAutoStart(true) + heartbeat.SetAutoUpdate(true) + heartbeat.SetBeta("stable") + heartbeat.SetDoh(false) + heartbeat.SetShowAllMail(false) + heartbeat.SetIMAPConnectionMode(true) + heartbeat.SetSMTPConnectionMode(true) + heartbeat.SetIMAPPort(1143) + heartbeat.SetSMTPPort(1025) + heartbeat.SetCacheLocation("/tmp") + heartbeat.SetKeyChainPref("defaultKeychain") + heartbeat.SetPrevVersion("1.2.3") + + tests(&heartbeat, manager) +} diff --git a/internal/telemetry/mocks/mocks.go b/internal/telemetry/mocks/mocks.go new file mode 100644 index 00000000..be5251e2 --- /dev/null +++ b/internal/telemetry/mocks/mocks.go @@ -0,0 +1,92 @@ +// Code generated by MockGen. DO NOT EDIT. +// Source: github.com/ProtonMail/proton-bridge/v3/internal/telemetry (interfaces: HeartbeatManager) + +// Package mocks is a generated GoMock package. +package mocks + +import ( + reflect "reflect" + time "time" + + telemetry "github.com/ProtonMail/proton-bridge/v3/internal/telemetry" + gomock "github.com/golang/mock/gomock" +) + +// MockHeartbeatManager is a mock of HeartbeatManager interface. +type MockHeartbeatManager struct { + ctrl *gomock.Controller + recorder *MockHeartbeatManagerMockRecorder +} + +// MockHeartbeatManagerMockRecorder is the mock recorder for MockHeartbeatManager. +type MockHeartbeatManagerMockRecorder struct { + mock *MockHeartbeatManager +} + +// NewMockHeartbeatManager creates a new mock instance. +func NewMockHeartbeatManager(ctrl *gomock.Controller) *MockHeartbeatManager { + mock := &MockHeartbeatManager{ctrl: ctrl} + mock.recorder = &MockHeartbeatManagerMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use. +func (m *MockHeartbeatManager) EXPECT() *MockHeartbeatManagerMockRecorder { + return m.recorder +} + +// GetLastHeartbeatSent mocks base method. +func (m *MockHeartbeatManager) GetLastHeartbeatSent() time.Time { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "GetLastHeartbeatSent") + ret0, _ := ret[0].(time.Time) + return ret0 +} + +// GetLastHeartbeatSent indicates an expected call of GetLastHeartbeatSent. +func (mr *MockHeartbeatManagerMockRecorder) GetLastHeartbeatSent() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetLastHeartbeatSent", reflect.TypeOf((*MockHeartbeatManager)(nil).GetLastHeartbeatSent)) +} + +// IsTelemetryAvailable mocks base method. +func (m *MockHeartbeatManager) IsTelemetryAvailable() bool { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "IsTelemetryAvailable") + ret0, _ := ret[0].(bool) + return ret0 +} + +// IsTelemetryAvailable indicates an expected call of IsTelemetryAvailable. +func (mr *MockHeartbeatManagerMockRecorder) IsTelemetryAvailable() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "IsTelemetryAvailable", reflect.TypeOf((*MockHeartbeatManager)(nil).IsTelemetryAvailable)) +} + +// SendHeartbeat mocks base method. +func (m *MockHeartbeatManager) SendHeartbeat(arg0 *telemetry.HeartbeatData) bool { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "SendHeartbeat", arg0) + ret0, _ := ret[0].(bool) + return ret0 +} + +// SendHeartbeat indicates an expected call of SendHeartbeat. +func (mr *MockHeartbeatManagerMockRecorder) SendHeartbeat(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SendHeartbeat", reflect.TypeOf((*MockHeartbeatManager)(nil).SendHeartbeat), arg0) +} + +// SetLastHeartbeatSent mocks base method. +func (m *MockHeartbeatManager) SetLastHeartbeatSent(arg0 time.Time) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "SetLastHeartbeatSent", arg0) + ret0, _ := ret[0].(error) + return ret0 +} + +// SetLastHeartbeatSent indicates an expected call of SetLastHeartbeatSent. +func (mr *MockHeartbeatManagerMockRecorder) SetLastHeartbeatSent(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetLastHeartbeatSent", reflect.TypeOf((*MockHeartbeatManager)(nil).SetLastHeartbeatSent), arg0) +} diff --git a/internal/telemetry/types_heartbeat.go b/internal/telemetry/types_heartbeat.go new file mode 100644 index 00000000..a10f42b1 --- /dev/null +++ b/internal/telemetry/types_heartbeat.go @@ -0,0 +1,79 @@ +// Copyright (c) 2023 Proton AG +// +// This file is part of Proton Mail Bridge. +// +// Proton Mail Bridge is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Proton Mail Bridge is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Proton Mail Bridge. If not, see . + +package telemetry + +import ( + "time" + + "github.com/sirupsen/logrus" +) + +const ( + dimensionON = "on" + dimensionOFF = "off" + dimensionDefault = "default" + dimensionCustom = "custom" + dimensionSSL = "ssl" + dimensionStartTLS = "starttls" +) + +type HeartbeatManager interface { + IsTelemetryAvailable() bool + SendHeartbeat(heartbeat *HeartbeatData) bool + GetLastHeartbeatSent() time.Time + SetLastHeartbeatSent(time.Time) error +} + +type HeartbeatValues struct { + NbAccount int `json:"nb_account"` +} + +type HeartbeatDimensions struct { + AutoUpdate string `json:"auto_update"` + AutoStart string `json:"auto_start"` + Beta string `json:"beta"` + Doh string `json:"doh"` + SplitMode string `json:"split_mode"` + ShowAllMail string `json:"show_all_mail"` + IMAPConnectionMode string `json:"imap_connection_mode"` + SMTPConnectionMode string `json:"smtp_connection_mode"` + IMAPPort string `json:"imap_port"` + SMTPPort string `json:"smtp_port"` + CacheLocation string `json:"cache_location"` + KeychainPref string `json:"keychain_pref"` + PrevVersion string `json:"prev_version"` + Rollout string `json:"rollout"` +} + +type HeartbeatData struct { + MeasurementGroup string + Event string + Values HeartbeatValues + Dimensions HeartbeatDimensions +} + +type Heartbeat struct { + log *logrus.Entry + manager HeartbeatManager + metrics HeartbeatData + + defaultIMAPPort int + defaultSMTPPort int + defaultCache string + defaultKeychain string +} diff --git a/internal/user/imap.go b/internal/user/imap.go index 6e607ddb..6d329e95 100644 --- a/internal/user/imap.go +++ b/internal/user/imap.go @@ -400,32 +400,8 @@ func (conn *imapConnector) RemoveMessagesFromMailbox(ctx context.Context, messag } if mailboxID == proton.TrashLabel || mailboxID == proton.DraftsLabel { - var metadata []proton.MessageMetadata - - // There's currently no limit on how many IDs we can filter on, - // but to be nice to API, let's chunk it by 150. - for _, messageIDs := range xslices.Chunk(messageIDs, 150) { - m, err := conn.client.GetMessageMetadata(ctx, proton.MessageFilter{ - ID: mapTo[imap.MessageID, string](messageIDs), - }) - if err != nil { - return err - } - - // If a message is not preset in any other label other than AllMail, AllDrafts and AllSent, it can be - // permanently deleted. - m = xslices.Filter(m, func(m proton.MessageMetadata) bool { - labelsThatMatter := xslices.Filter(m.LabelIDs, func(id string) bool { - return id != proton.AllDraftsLabel && id != proton.AllMailLabel && id != proton.AllSentLabel - }) - return len(labelsThatMatter) == 0 - }) - - metadata = append(metadata, m...) - } - - if err := conn.client.DeleteMessage(ctx, xslices.Map(metadata, func(m proton.MessageMetadata) string { - return m.ID + if err := conn.client.DeleteMessage(ctx, xslices.Map(messageIDs, func(m imap.MessageID) string { + return string(m) })...); err != nil { return err } @@ -626,7 +602,7 @@ func (conn *imapConnector) createDraft(ctx context.Context, literal []byte, addr return proton.Message{}, fmt.Errorf("failed to create parser: %w", err) } - message, err := message.ParseWithParser(parser) + message, err := message.ParseWithParser(parser, true) if err != nil { return proton.Message{}, fmt.Errorf("failed to parse message: %w", err) } diff --git a/internal/user/smtp.go b/internal/user/smtp.go index 9e237474..ce42fb23 100644 --- a/internal/user/smtp.go +++ b/internal/user/smtp.go @@ -140,7 +140,7 @@ func (user *User) sendMail(authID string, from string, to []string, r io.Reader) } // Parse the message we want to send (after we have attached the public key). - message, err := message.ParseWithParser(parser) + message, err := message.ParseWithParser(parser, false) if err != nil { return fmt.Errorf("failed to parse message: %w", err) } diff --git a/internal/user/sync.go b/internal/user/sync.go index 03515645..d3da5d8f 100644 --- a/internal/user/sync.go +++ b/internal/user/sync.go @@ -262,7 +262,7 @@ func (user *User) syncMessages( syncStartTime := time.Now() defer func() { logrus.WithField("duration", time.Since(syncStartTime)).Info("Message sync completed") }() - logrus.WithFields(logrus.Fields{ + user.log.WithFields(logrus.Fields{ "messages": len(messageIDs), "numCPU": runtime.NumCPU(), }).Info("Starting message sync") diff --git a/internal/user/user.go b/internal/user/user.go index 71a46236..d8418330 100644 --- a/internal/user/user.go +++ b/internal/user/user.go @@ -119,6 +119,12 @@ func New( return nil, fmt.Errorf("failed to get labels: %w", err) } + logrus.WithFields(logrus.Fields{ + "userID": apiUser.ID, + "numAddr": len(apiAddrs), + "numLabels": len(apiLabels), + }).Info("Creating user object") + // Create the user object. user := &User{ log: logrus.WithField("userID", apiUser.ID), @@ -591,6 +597,36 @@ func (user *User) Close() { } } +// IsTelemetryEnabled check if the telemetry is enabled or disabled for this user. +func (user *User) IsTelemetryEnabled(ctx context.Context) bool { + settings, err := user.client.GetUserSettings(ctx) + if err != nil { + user.log.WithError(err).Error("Failed to retrieve API user Settings") + return false + } + return settings.Telemetry == proton.SettingEnabled +} + +// SendTelemetry send telemetry request. +func (user *User) SendTelemetry(ctx context.Context, data []byte) error { + var req proton.SendStatsReq + if err := json.Unmarshal(data, &req); err != nil { + user.log.WithError(err).Error("Failed to build telemetry request.") + if err := user.reporter.ReportMessageWithContext("Failed to build telemetry request.", reporter.Context{ + "error": err, + }); err != nil { + logrus.WithError(err).Error("Failed to report telemetry request build error") + } + return err + } + err := user.client.SendDataEvent(ctx, req) + if err != nil { + user.log.WithError(err).Error("Failed to send telemetry.") + return err + } + return nil +} + // initUpdateCh initializes the user's update channels in the given address mode. // It is assumed that user.apiAddrs and user.updateCh are already locked. func (user *User) initUpdateCh(mode vault.AddressMode) { diff --git a/internal/user/user_test.go b/internal/user/user_test.go index c0888147..cf3388d5 100644 --- a/internal/user/user_test.go +++ b/internal/user/user_test.go @@ -80,6 +80,23 @@ func TestUser_AddressMode(t *testing.T) { }) } +func TestUser_Telemetry(t *testing.T) { + withAPI(t, context.Background(), func(ctx context.Context, s *server.Server, m *proton.Manager) { + withAccount(t, s, "username", "password", []string{}, func(string, []string) { + withUser(t, ctx, s, m, "username", "password", func(user *User) { + // By default, user should have Telemetry enabled. + telemetry := user.IsTelemetryEnabled(ctx) + require.Equal(t, true, telemetry) + + user.client.Close() + // If telemetry cannot be retrieved it is disabled. + telemetry = user.IsTelemetryEnabled(ctx) + require.Equal(t, false, telemetry) + }) + }) + }) +} + func withAPI(_ testing.TB, ctx context.Context, fn func(context.Context, *server.Server, *proton.Manager)) { //nolint:revive server := server.New() defer server.Close() diff --git a/internal/useragent/useragent.go b/internal/useragent/useragent.go index 12dc8a32..1e8b87bc 100644 --- a/internal/useragent/useragent.go +++ b/internal/useragent/useragent.go @@ -44,6 +44,20 @@ func (ua *UserAgent) SetClient(name, version string) { ua.client = fmt.Sprintf("%v/%v", name, regexp.MustCompile(`(.*) \((.*)\)`).ReplaceAllString(version, "$1-$2")) } +func (ua *UserAgent) SetClientString(client string) { + ua.lock.Lock() + defer ua.lock.Unlock() + + ua.client = client +} + +func (ua *UserAgent) GetClientString() string { + ua.lock.RLock() + defer ua.lock.RUnlock() + + return ua.client +} + func (ua *UserAgent) HasClient() bool { ua.lock.RLock() defer ua.lock.RUnlock() diff --git a/internal/vault/settings.go b/internal/vault/settings.go index 9967e307..f625825e 100644 --- a/internal/vault/settings.go +++ b/internal/vault/settings.go @@ -20,6 +20,7 @@ package vault import ( "math" "math/rand" + "time" "github.com/Masterminds/semver/v3" "github.com/ProtonMail/proton-bridge/v3/internal/updater" @@ -184,6 +185,18 @@ func (vault *Vault) SetAutoUpdate(autoUpdate bool) error { }) } +// GetTelemetryDisabled checks whether telemetry is disabled. +func (vault *Vault) GetTelemetryDisabled() bool { + return vault.get().Settings.TelemetryDisabled +} + +// SetTelemetryDisabled sets whether telemetry is disabled. +func (vault *Vault) SetTelemetryDisabled(telemetryDisabled bool) error { + return vault.mod(func(data *Data) { + data.Settings.TelemetryDisabled = telemetryDisabled + }) +} + // GetLastVersion returns the last version of the bridge that was run. func (vault *Vault) GetLastVersion() *semver.Version { return semver.MustParse(vault.get().Settings.LastVersion) @@ -225,3 +238,34 @@ func (vault *Vault) SetMaxSyncMemory(maxMemory uint64) error { data.Settings.MaxSyncMemory = maxMemory }) } + +// GetLastUserAgent returns the last user agent recorded by bridge. +func (vault *Vault) GetLastUserAgent() string { + v := vault.get().Settings.LastUserAgent + + // Handle case where there may be no value. + if len(v) == 0 { + v = DefaultUserAgent + } + + return v +} + +// SetLastUserAgent store the last user agent recorded by bridge. +func (vault *Vault) SetLastUserAgent(userAgent string) error { + return vault.mod(func(data *Data) { + data.Settings.LastUserAgent = userAgent + }) +} + +// GetLastHeartbeatSent returns the last time heartbeat was sent. +func (vault *Vault) GetLastHeartbeatSent() time.Time { + return vault.get().Settings.LastHeartbeatSent +} + +// SetLastHeartbeatSent store the last time heartbeat was sent. +func (vault *Vault) SetLastHeartbeatSent(timestamp time.Time) error { + return vault.mod(func(data *Data) { + data.Settings.LastHeartbeatSent = timestamp + }) +} diff --git a/internal/vault/settings_test.go b/internal/vault/settings_test.go index cc4e1b77..3996b9ae 100644 --- a/internal/vault/settings_test.go +++ b/internal/vault/settings_test.go @@ -153,6 +153,20 @@ func TestVault_Settings_ShowAllMail(t *testing.T) { require.Equal(t, false, s.GetShowAllMail()) } +func TestVault_Settings_TelemetryDisabled(t *testing.T) { + // create a new test vault. + s := newVault(t) + + // Check the default show all mail setting. + require.Equal(t, false, s.GetTelemetryDisabled()) + + // Modify the show all mail setting. + require.NoError(t, s.SetTelemetryDisabled(true)) + + // Check the new show all mail setting. + require.Equal(t, true, s.GetTelemetryDisabled()) +} + func TestVault_Settings_Autostart(t *testing.T) { // create a new test vault. s := newVault(t) @@ -216,3 +230,11 @@ func TestVault_Settings_MaxSyncMemory(t *testing.T) { // Check the default first start value. require.Equal(t, vault.DefaultMaxSyncMemory, s.GetMaxSyncMemory()) } + +func TestVault_Settings_LastUserAgent(t *testing.T) { + // create a new test vault. + s := newVault(t) + + // Check the default first start value. + require.Equal(t, vault.DefaultUserAgent, s.GetLastUserAgent()) +} diff --git a/internal/vault/types_settings.go b/internal/vault/types_settings.go index 8f83423f..d6961673 100644 --- a/internal/vault/types_settings.go +++ b/internal/vault/types_settings.go @@ -20,8 +20,10 @@ package vault import ( "math/rand" "runtime" + "time" "github.com/ProtonMail/proton-bridge/v3/internal/updater" + "github.com/ProtonMail/proton-bridge/v3/pkg/ports" ) type Settings struct { @@ -35,23 +37,29 @@ type Settings struct { UpdateChannel updater.Channel UpdateRollout float64 - ColorScheme string - ProxyAllowed bool - ShowAllMail bool - Autostart bool - AutoUpdate bool + ColorScheme string + ProxyAllowed bool + ShowAllMail bool + Autostart bool + AutoUpdate bool + TelemetryDisabled bool LastVersion string FirstStart bool MaxSyncMemory uint64 + LastUserAgent string + + LastHeartbeatSent time.Time + // **WARNING**: These entry can't be removed until they vault has proper migration support. SyncWorkers int SyncAttPool int } const DefaultMaxSyncMemory = 2 * 1024 * uint64(1024*1024) +const DefaultUserAgent = "UnknownClient/0.0.1" func GetDefaultSyncWorkerCount() int { const minSyncWorkers = 16 @@ -67,23 +75,26 @@ func GetDefaultSyncWorkerCount() int { func newDefaultSettings(gluonDir string) Settings { syncWorkers := GetDefaultSyncWorkerCount() + imapPort := ports.FindFreePortFrom(1143) + smtpPort := ports.FindFreePortFrom(1025, imapPort) return Settings{ GluonDir: gluonDir, - IMAPPort: 1143, - SMTPPort: 1025, + IMAPPort: imapPort, + SMTPPort: smtpPort, IMAPSSL: false, SMTPSSL: false, UpdateChannel: updater.DefaultUpdateChannel, UpdateRollout: rand.Float64(), //nolint:gosec - ColorScheme: "", - ProxyAllowed: false, - ShowAllMail: true, - Autostart: true, - AutoUpdate: true, + ColorScheme: "", + ProxyAllowed: false, + ShowAllMail: true, + Autostart: true, + AutoUpdate: true, + TelemetryDisabled: false, LastVersion: "0.0.0", FirstStart: true, @@ -91,5 +102,8 @@ func newDefaultSettings(gluonDir string) Settings { MaxSyncMemory: DefaultMaxSyncMemory, SyncWorkers: syncWorkers, SyncAttPool: syncWorkers, + + LastUserAgent: DefaultUserAgent, + LastHeartbeatSent: time.Time{}, } } diff --git a/pkg/keychain/helper_darwin.go b/pkg/keychain/helper_darwin.go index 2e36c9d2..9faae613 100644 --- a/pkg/keychain/helper_darwin.go +++ b/pkg/keychain/helper_darwin.go @@ -38,7 +38,7 @@ func init() { //nolint:gochecknoinits Helpers[MacOSKeychain] = newMacOSHelper // Use MacOSKeychain by default. - defaultHelper = MacOSKeychain + DefaultHelper = MacOSKeychain } func parseError(original error) error { diff --git a/pkg/keychain/helper_linux.go b/pkg/keychain/helper_linux.go index 3c31736d..ea146fc7 100644 --- a/pkg/keychain/helper_linux.go +++ b/pkg/keychain/helper_linux.go @@ -48,14 +48,14 @@ func init() { //nolint:gochecknoinits Helpers[Pass] = newPassHelper } - defaultHelper = SecretServiceDBus + DefaultHelper = SecretServiceDBus // If Pass is available, use it by default. // Otherwise, if SecretService is available, use it by default. if _, ok := Helpers[Pass]; ok { - defaultHelper = Pass + DefaultHelper = Pass } else if _, ok := Helpers[SecretService]; ok { - defaultHelper = SecretService + DefaultHelper = SecretService } } diff --git a/pkg/keychain/helper_windows.go b/pkg/keychain/helper_windows.go index 6eb2dd06..b4b8ccbd 100644 --- a/pkg/keychain/helper_windows.go +++ b/pkg/keychain/helper_windows.go @@ -31,7 +31,7 @@ func init() { //nolint:gochecknoinits Helpers[WindowsCredentials] = newWinCredHelper // Use WindowsCredentials by default. - defaultHelper = WindowsCredentials + DefaultHelper = WindowsCredentials } func newWinCredHelper(string) (credentials.Helper, error) { diff --git a/pkg/keychain/keychain.go b/pkg/keychain/keychain.go index 251477c9..57b895c9 100644 --- a/pkg/keychain/keychain.go +++ b/pkg/keychain/keychain.go @@ -42,8 +42,8 @@ var ( // Helpers holds all discovered keychain helpers. It is populated in init(). Helpers map[string]helperConstructor //nolint:gochecknoglobals - // defaultHelper is the default helper to use if the user hasn't yet set a preference. - defaultHelper string //nolint:gochecknoglobals + // DefaultHelper is the default helper to use if the user hasn't yet set a preference. + DefaultHelper string //nolint:gochecknoglobals ) // NewKeychain creates a new native keychain. @@ -55,7 +55,7 @@ func NewKeychain(preferred, keychainName string) (*Keychain, error) { // If the preferred keychain is unsupported, fallback to the default one. if _, ok := Helpers[preferred]; !ok { - preferred = defaultHelper + preferred = DefaultHelper } // Load the user's preferred keychain helper. diff --git a/pkg/message/build.go b/pkg/message/build.go index b67503e2..5e7e44bb 100644 --- a/pkg/message/build.go +++ b/pkg/message/build.go @@ -441,7 +441,7 @@ func getMessageHeader(msg proton.Message, opts JobOptions) message.Header { hdr.Set("From", msg.Sender.String()) } - if len(msg.ReplyTos) > 0 { + if len(msg.ReplyTos) > 0 && !msg.IsDraft() { if !(len(msg.ReplyTos) == 1 && addressEmpty(msg.ReplyTos[0])) { hdr.Set("Reply-To", toAddressList(msg.ReplyTos)) } diff --git a/pkg/message/build_test.go b/pkg/message/build_test.go index 41d52936..58c2ee9b 100644 --- a/pkg/message/build_test.go +++ b/pkg/message/build_test.go @@ -431,7 +431,7 @@ func TestBuildSignedPlainEncryptedMessageWithPubKey(t *testing.T) { section(t, res). expectDate(is(`Wed, 01 Jan 2020 00:00:00 +0000`)). expectContentType(is(`multipart/signed`)). - expectContentTypeParam(`micalg`, is(`pgp-sha256`)). + expectContentTypeParam(`micalg`, is(`SHA-256`)). expectContentTypeParam(`protocol`, is(`application/pgp-signature`)) section(t, res, 1). @@ -439,7 +439,7 @@ func TestBuildSignedPlainEncryptedMessageWithPubKey(t *testing.T) { expectContentTypeParam(`protected-headers`, is(`v1`)). expectHeader(`Subject`, is(`simple plaintext body`)). expectHeader(`From`, is(`"pm.bridge.qa" `)). - expectHeader(`To`, is(`schizofrenic@pm.me`)). + expectHeader(`To`, is("\"InfernalBridgeTester@proton.me\" ")). expectSection(verifiesAgainst(section(t, res, 1, 1, 2).pubKey(), section(t, res, 2).signature())) section(t, res, 1, 1). @@ -477,7 +477,7 @@ func TestBuildSignedHTMLEncryptedMessageWithPubKey(t *testing.T) { section(t, res). expectDate(is(`Wed, 01 Jan 2020 00:00:00 +0000`)). expectContentType(is(`multipart/signed`)). - expectContentTypeParam(`micalg`, is(`pgp-sha256`)). + expectContentTypeParam(`micalg`, is(`SHA-256`)). expectContentTypeParam(`protocol`, is(`application/pgp-signature`)) section(t, res, 1). @@ -485,7 +485,7 @@ func TestBuildSignedHTMLEncryptedMessageWithPubKey(t *testing.T) { expectContentTypeParam(`protected-headers`, is(`v1`)). expectHeader(`Subject`, is(`simple html body`)). expectHeader(`From`, is(`"pm.bridge.qa" `)). - expectHeader(`To`, is(`schizofrenic@pm.me`)). + expectHeader(`To`, is("\"InfernalBridgeTester@proton.me\" ")). expectSection(verifiesAgainst(section(t, res, 1, 1, 2).pubKey(), section(t, res, 2).signature())) section(t, res, 1, 1). @@ -524,7 +524,7 @@ func TestBuildSignedMultipartAlternativeEncryptedMessageWithPubKey(t *testing.T) section(t, res). expectDate(is(`Wed, 01 Jan 2020 00:00:00 +0000`)). expectContentType(is(`multipart/signed`)). - expectContentTypeParam(`micalg`, is(`pgp-sha256`)). + expectContentTypeParam(`micalg`, is(`SHA-256`)). expectContentTypeParam(`protocol`, is(`application/pgp-signature`)) section(t, res, 1). @@ -532,8 +532,8 @@ func TestBuildSignedMultipartAlternativeEncryptedMessageWithPubKey(t *testing.T) expectContentTypeParam(`protected-headers`, is(`v1`)). expectHeader(`Subject`, is(`Alternative`)). expectHeader(`From`, is(`"pm.bridge.qa" `)). - expectHeader(`To`, is(`schizofrenic@pm.me`)). - expectSection(verifiesAgainst(section(t, res, 1, 1, 3).pubKey(), section(t, res, 2).signature())) + expectHeader(`To`, is("\"InfernalBridgeTester@proton.me\" ")). + expectSection(verifiesAgainst(section(t, res, 1, 1, 2).pubKey(), section(t, res, 2).signature())) section(t, res, 1, 1). expectContentType(is(`multipart/mixed`)) @@ -549,17 +549,11 @@ func TestBuildSignedMultipartAlternativeEncryptedMessageWithPubKey(t *testing.T) section(t, res, 1, 1, 1, 2). expectContentType(is(`text/html`)). - expectBody(contains(`This Rich formated text`)). + expectBody(contains(`This Rich formated text`)). expectBody(contains(`What kind of shoes do ninjas wear`)). expectBody(contains(`How does a penguin build its house`)) section(t, res, 1, 1, 2). - expectContentType(is(`application/pdf`)). - expectTransferEncoding(is(`base64`)). - expectContentTypeParam(`name`, is(`minimal.pdf`)). - expectContentDispositionParam(`filename`, is(`minimal.pdf`)) - - section(t, res, 1, 1, 3). expectContentType(is(`application/pgp-keys`)). expectContentTypeParam(`name`, is(`OpenPGP_0x161C0875822359F7.asc`)). expectContentDisposition(is(`attachment`)). @@ -587,16 +581,16 @@ func TestBuildSignedEmbeddedMessageRFC822EncryptedMessageWithPubKey(t *testing.T section(t, res). expectDate(is(`Wed, 01 Jan 2020 00:00:00 +0000`)). expectContentType(is(`multipart/signed`)). - expectContentTypeParam(`micalg`, is(`pgp-sha256`)). + expectContentTypeParam(`micalg`, is(`SHA-256`)). expectContentTypeParam(`protocol`, is(`application/pgp-signature`)) section(t, res, 1). expectContentType(is(`multipart/mixed`)). expectContentTypeParam(`protected-headers`, is(`v1`)). - expectHeader(`Subject`, is(`Fwd: HTML with attachment external PGP`)). + expectHeader(`Subject`, is(`Fwd: simple html body`)). expectHeader(`From`, is(`"pm.bridge.qa" `)). - expectHeader(`To`, is(`schizofrenic@pm.me`)). - expectSection(verifiesAgainst(section(t, res, 1, 1, 2).pubKey(), section(t, res, 2).signature())) + expectHeader(`To`, is("\"InfernalBridgeTester@proton.me\" ")). + expectSection(verifiesAgainst(section(t, res, 1, 1, 3).pubKey(), section(t, res, 2).signature())) section(t, res, 1, 1). expectContentType(is(`multipart/mixed`)) @@ -605,17 +599,17 @@ func TestBuildSignedEmbeddedMessageRFC822EncryptedMessageWithPubKey(t *testing.T expectContentType(is(`text/plain`)) section(t, res, 1, 1, 2). + expectContentType(is(`message/rfc822`)). + expectContentTypeParam(`name`, is(`simple html body.eml`)). + expectContentDisposition(is(`attachment`)). + expectContentDispositionParam(`filename`, is(`simple html body.eml`)) + + section(t, res, 1, 1, 3). expectContentType(is(`application/pgp-keys`)). expectContentTypeParam(`name`, is(`OpenPGP_0x161C0875822359F7.asc`)). expectContentDisposition(is(`attachment`)). expectContentDispositionParam(`filename`, is(`OpenPGP_0x161C0875822359F7.asc`)) - section(t, res, 1, 1, 3). - expectContentType(is(`message/rfc822`)). - expectContentTypeParam(`name`, is(`HTML with attachment external PGP.eml`)). - expectContentDisposition(is(`attachment`)). - expectContentDispositionParam(`filename`, is(`HTML with attachment external PGP.eml`)) - section(t, res, 2). expectContentType(is(`application/pgp-signature`)). expectContentTypeParam(`name`, is(`OpenPGP_signature.asc`)). diff --git a/pkg/message/parser.go b/pkg/message/parser.go index 91fc105c..ead63a8d 100644 --- a/pkg/message/parser.go +++ b/pkg/message/parser.go @@ -73,6 +73,15 @@ type Attachment struct { // Parse parses an RFC822 message. func Parse(r io.Reader) (m Message, err error) { + return parseIOReaderImpl(r, false) +} + +// ParseAndAllowInvalidAddressLists parses an RFC822 message and allows email address lists to be invalid. +func ParseAndAllowInvalidAddressLists(r io.Reader) (m Message, err error) { + return parseIOReaderImpl(r, true) +} + +func parseIOReaderImpl(r io.Reader, allowInvalidAddressLists bool) (m Message, err error) { defer func() { if r := recover(); r != nil { err = fmt.Errorf("panic while parsing message: %v", r) @@ -84,21 +93,21 @@ func Parse(r io.Reader) (m Message, err error) { return Message{}, errors.Wrap(err, "failed to create new parser") } - return parse(p) + return parse(p, allowInvalidAddressLists) } // ParseWithParser parses an RFC822 message using an existing parser. -func ParseWithParser(p *parser.Parser) (m Message, err error) { +func ParseWithParser(p *parser.Parser, allowInvalidAddressLists bool) (m Message, err error) { defer func() { if r := recover(); r != nil { err = fmt.Errorf("panic while parsing message: %v", r) } }() - return parse(p) + return parse(p, allowInvalidAddressLists) } -func parse(p *parser.Parser) (Message, error) { +func parse(p *parser.Parser, allowInvalidAddressLists bool) (Message, error) { if err := convertEncodedTransferEncoding(p); err != nil { return Message{}, errors.Wrap(err, "failed to convert encoded transfer encoding") } @@ -107,7 +116,7 @@ func parse(p *parser.Parser) (Message, error) { return Message{}, errors.Wrap(err, "failed to convert foreign encodings") } - m, err := parseMessageHeader(p.Root().Header) + m, err := parseMessageHeader(p.Root().Header, allowInvalidAddressLists) if err != nil { return Message{}, errors.Wrap(err, "failed to parse message header") } @@ -433,7 +442,7 @@ func getPlainBody(part *parser.Part) []byte { } } -func parseMessageHeader(h message.Header) (Message, error) { +func parseMessageHeader(h message.Header, allowInvalidAddressLists bool) (Message, error) { var m Message for fields := h.Fields(); fields.Next(); { @@ -451,7 +460,11 @@ func parseMessageHeader(h message.Header) (Message, error) { case "from": sender, err := rfc5322.ParseAddressList(fields.Value()) if err != nil { - return Message{}, errors.Wrap(err, "failed to parse from") + if !allowInvalidAddressLists { + return Message{}, errors.Wrap(err, "failed to parse from") + } + + logrus.WithError(err).Warn("failed to parse from") } if len(sender) > 0 { @@ -461,7 +474,11 @@ func parseMessageHeader(h message.Header) (Message, error) { case "to": toList, err := rfc5322.ParseAddressList(fields.Value()) if err != nil { - return Message{}, errors.Wrap(err, "failed to parse to") + if !allowInvalidAddressLists { + return Message{}, errors.Wrap(err, "failed to parse to") + } + + logrus.WithError(err).Warn("failed to parse to") } m.ToList = toList @@ -469,7 +486,11 @@ func parseMessageHeader(h message.Header) (Message, error) { case "reply-to": replyTos, err := rfc5322.ParseAddressList(fields.Value()) if err != nil { - return Message{}, errors.Wrap(err, "failed to parse reply-to") + if !allowInvalidAddressLists { + return Message{}, errors.Wrap(err, "failed to parse reply-to") + } + + logrus.WithError(err).Warn("failed to parse reply-to") } m.ReplyTos = replyTos @@ -477,7 +498,11 @@ func parseMessageHeader(h message.Header) (Message, error) { case "cc": ccList, err := rfc5322.ParseAddressList(fields.Value()) if err != nil { - return Message{}, errors.Wrap(err, "failed to parse cc") + if !allowInvalidAddressLists { + return Message{}, errors.Wrap(err, "failed to parse cc") + } + + logrus.WithError(err).Warn("failed to parse cc") } m.CCList = ccList @@ -485,7 +510,11 @@ func parseMessageHeader(h message.Header) (Message, error) { case "bcc": bccList, err := rfc5322.ParseAddressList(fields.Value()) if err != nil { - return Message{}, errors.Wrap(err, "failed to parse bcc") + if !allowInvalidAddressLists { + return Message{}, errors.Wrap(err, "failed to parse bcc") + } + + logrus.WithError(err).Warn("failed to parse bcc") } m.BCCList = bccList diff --git a/pkg/message/parser_test.go b/pkg/message/parser_test.go index 6942deee..5bbce163 100644 --- a/pkg/message/parser_test.go +++ b/pkg/message/parser_test.go @@ -23,6 +23,7 @@ import ( "io" "os" "path/filepath" + "strings" "testing" "github.com/ProtonMail/go-proton-api" @@ -444,7 +445,7 @@ func TestParseWithAttachedPublicKey(t *testing.T) { p, err := parser.New(f) require.NoError(t, err) - m, err := ParseWithParser(p) + m, err := ParseWithParser(p, false) require.NoError(t, err) p.AttachPublicKey("publickey", "publickeyname") @@ -636,6 +637,32 @@ func TestParseIcsAttachment(t *testing.T) { assert.Equal(t, string(m.Attachments[0].Data), "This is an ics calendar invite") } +func TestParseAllowInvalidAddress(t *testing.T) { + const literal = `To: foo +From: bar +BCC: fff +CC: FFF +Reply-To: AAA +Subject: Test +` + + // This will fail as the addresses are not valid. + { + _, err := Parse(strings.NewReader(literal)) + require.Error(t, err) + } + + // This will work as invalid addresses will be ignored. + m, err := ParseAndAllowInvalidAddressLists(strings.NewReader(literal)) + require.NoError(t, err) + + assert.Empty(t, m.ToList) + assert.Empty(t, m.Sender) + assert.Empty(t, m.CCList) + assert.Empty(t, m.BCCList) + assert.Empty(t, m.ReplyTos) +} + func TestParsePanic(t *testing.T) { var err error diff --git a/pkg/message/testdata/pgp-mime-body-signed-embedded-message-rfc822-with-pubkey.eml b/pkg/message/testdata/pgp-mime-body-signed-embedded-message-rfc822-with-pubkey.eml index 69a0c258..47219822 100644 --- a/pkg/message/testdata/pgp-mime-body-signed-embedded-message-rfc822-with-pubkey.eml +++ b/pkg/message/testdata/pgp-mime-body-signed-embedded-message-rfc822-with-pubkey.eml @@ -1,212 +1,252 @@ -Content-Type: multipart/signed; micalg=pgp-sha256; - protocol="application/pgp-signature"; - boundary="Rrmlds5vN3IeeCVjbnepHmuVgyROSBjsS" - -This is an OpenPGP/MIME signed message (RFC 4880 and 3156) ---Rrmlds5vN3IeeCVjbnepHmuVgyROSBjsS -Content-Type: multipart/mixed; boundary="avFkF0LAPYPXcFHcnsgGmACbGIPeVDdYc"; - protected-headers="v1" -Subject: Fwd: HTML with attachment external PGP -From: "pm.bridge.qa" -To: schizofrenic@pm.me -Message-ID: <7c04869b-c470-116f-b8e5-8b4fd5e1195d@gmail.com> -References: -In-Reply-To: - ---avFkF0LAPYPXcFHcnsgGmACbGIPeVDdYc -Content-Type: multipart/mixed; - boundary="------------2F19EE9A8A1A6F779F5D14AF" -Content-Language: en-US - -This is a multi-part message in MIME format. ---------------2F19EE9A8A1A6F779F5D14AF -Content-Type: text/plain; charset=utf-8; format=flowed -Content-Transfer-Encoding: quoted-printable - - - ---------------2F19EE9A8A1A6F779F5D14AF -Content-Type: application/pgp-keys; - name="OpenPGP_0x161C0875822359F7.asc" -Content-Transfer-Encoding: quoted-printable -Content-Disposition: attachment; - filename="OpenPGP_0x161C0875822359F7.asc" - ------BEGIN PGP PUBLIC KEY BLOCK----- - -xsBNBFxlUPwBCACx954Ey4SD88f8DSKFw9BaZNXrNwYxNYSgqaqOGHQ0WllF3mstEhTfuxxCZ= -pDh -I5IhWCXUNxanzsFkn88mRDwFRVl2sf2aAG4/P/p1381oh2kd0UElMRQaQGzoCadQMaQOL9WYT= -f4S -PWSCzjrPyKgjq5FbqjbF/ndu376na9L+tnsEXyL6RrI6aZhjWG73xlqxS65dzTIYzsyM/P97x= -Snd -NvlvWtGvLlpFkzxfAEGpVzfOYVYFKoc8rGmUDwrDWYfk5JczRDDogJnY+BNMZf9pjSqk6rTyB= -OfN -H5fpU8r7A5Q7l+HVakvMUQ9DzDWJtg2ru1Y8hexnJOF68avO4+a1ABEBAAHNKEJyaWRnZSBLe= -XUt -RWh5aiA8cG0uYnJpZGdlLnFhQGdtYWlsLmNvbT7CwJQEEwEIAD4CGwMFCwkIBwIGFQoJCAsCB= -BYC -AwECHgECF4AWIQRc5gl5cC8oW/Mo+bEWHAh1giNZ9wUCYC32ygUJB4sMzgAKCRAWHAh1giNZ9= -/K8 -B/4qs84Ii/zKH+q+C8vwO4jUJkOM73qD0pgB7zBs651zWbpgopyol1YUKNpFaHlx/Qch7RDI7= -Vcz -1+60/KZJSJR19/N2EDVbCUdh8ueioUp9X/218YWV2TRJNxTnljd4FAn7smZnXuP1TsLjQ6sKO= -V0U -u6JoiG6LZFXqDgxYpA++58Rkl6xaY6R71VkmVQlbEKtubX9AjHydq97Y+Jvn11XzWZaKhv4L7= -6Pa -4tMKXvvrKh1oywMmh6mZJo+5ZA/ABTkr45cwlTPYqGTS9+uvOHt+PH/oYwwJB4ls2cIAUldSj= -TVQ -IsseYz3LlbcCfKJiiCFxeHOQXA5J6zNLKOT58TsczsBNBFxlUPwBCADh2HsX23yVnJt9fxFz3= -D07 -kCBNvu4HQfps6h1rgNxGhE32VmpESHebvIB5xjL6xKbIqqRa3x/7KDVBNJvca0gUsqEt5kzYF= -88F -yf2NBcejpIbcP7BS/g+C6KOowYj+Et26T6GdwFXExUcl80JvoX8yHQOfvJpdiBRbjyB8UqfCa= -knm -3c7dNuXmhflz/w3aBj32q9ZyGqA1NpHCpLyVAlvSNQ/pat/rGUCPZ9duw4KhUUqEmatQPVFPk= -utT -ouEZQbMK+i+chOH3AsKCuNDfvCDwirnsSqIJmAgl1lC4de+bsWYCMqN9ei99hOCRUyhZ3g3sr= -8RB -owVAdcvjZxeIDKALABEBAAHCwHwEGAEIACYCGwwWIQRc5gl5cC8oW/Mo+bEWHAh1giNZ9wUCY= -C32 -lAUJB4sMmAAKCRAWHAh1giNZ9+Y2B/9rTKZaKviae+ummXNumXcrKvbkAAvfuLpKUn53FlQLm= -L6H -jB++lJnPWvVSzdZxdv8FiPP3d632XHKUrkQRQM/9byRDXDommi7Qttx7YCkhd4JLVYqJqpnAQ= -xI5 -RMkXiZNWyr1lz8JOM1XvDk1M7sJwPMWews8VOIE03E1nt7AsQGnvHtadgEnQaufrYNX3hFA8S= -osO -HSnedcys6yrzCSIGCqCD9VHbnMtS4DOv0XJGh2hwc8omzH0KZA517dyKBorJRwadcVauGXDKx= -Etv -Im4rl94PR/3An1Mj6HeeVVpLqDQ5Jb9J90BahWeQ53FzRa4EQzYCw0nLnxcsT1ZEEP5u -=3Dv/1p ------END PGP PUBLIC KEY BLOCK----- - ---------------2F19EE9A8A1A6F779F5D14AF -Content-Type: message/rfc822; - name="HTML with attachment external PGP.eml" -Content-Transfer-Encoding: 7bit -Content-Disposition: attachment; - filename="HTML with attachment external PGP.eml" - -Delivered-To: pm.bridge.qa@gmail.com -Received: by 2002:a17:906:a051:0:0:0:0 with SMTP id bg17csp66709ejb; - Wed, 24 Mar 2021 22:03:32 -0700 (PDT) -X-Google-Smtp-Source: ABdhPJxllBuHnnJzKWy77R291tZbVFVk0iahkLm1TQsluEYTvyAXdOWB/zp1y10e60UlGGZYH3YF -X-Received: by 2002:a05:6000:118c:: with SMTP id g12mr6758087wrx.353.1616648612550; - Wed, 24 Mar 2021 22:03:32 -0700 (PDT) -ARC-Seal: i=1; a=rsa-sha256; t=1616648612; cv=none; - d=google.com; s=arc-20160816; - b=Jf4vmKEoeJQ3rIDMbI2twiDkfn50ejNnqIbs2nkaFruITcw6XhvhbcfV9HLC80Yt8E - tfN7TV9qoBneSWzfSJ+Sqw31hBKKtKpMhuqZT9GPzBN5gdMJKj5ISAQ8Lgm9zvR3Zbjn - N0nOzCu/oT1amMMm+48hpKj8VL2tydjvNG+g/a5lk1Aw7JdqIKV6t1XhsyyYaa1O+NFC - rQThdalcQj2NjoZWba1mjZSzI7B7hJdZg5d+jado2TPMQXe2kz2wGmr3+/JcKvPJjrSA - S+jzhpjcd7ZnctkzTfpsdlBJAGKoDBnSvQc3eMJ/AgRHFc+5ks5nRDt/1DowSjQ7i7rp - 4a+g== -ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; - h=mime-version:message-id:subject:reply-to:from:to:dkim-signature - :date; - bh=vmJ0JT+IfeO4idMYP7zPvldBkdONjKTXWTp7ly/B9qk=; - b=f8VY+ajsE/XNYrqD666FM0WCtNEQtUyU/Zh3pFCI9sFrMnAui4Qp9Gs1fe/8HLxt2v - /C4l4eHELvPBv4vX0KtUvOlRZYPZbLZCNdtTcFtiuZEKUHWx370p7yyMWcmSMdlUbq4J - NrKMPGfaYiZe5Rt3MyD5RKm4RJpqvep34VCHMYtoFQP/0Po4/1JMDw0Fy6SXUJ54rBRw - bmzqNNBkonda3YghhK3WNrxTxzZ8I7KW9YdpENNS9ewJLeVtFQKdiLZwz5EpMZxOxG0I - LW0jRtDlmZnqRe7bvTAo51IuLf9okHRI8PRiK0UHl+4Vr5Igq4mub7Ee8pC/Nz3Yj29G - KODw== -ARC-Authentication-Results: i=1; mx.google.com; - dkim=pass header.i=@protonmail.com header.s=protonmail header.b=EX07e46H; - spf=pass (google.com: domain of bridge-test-user@protonmail.com designates 185.70.40.22 as permitted sender) smtp.mailfrom=bridge-test-user@protonmail.com; - dmarc=pass (p=QUARANTINE sp=QUARANTINE dis=NONE) header.from=protonmail.com -Return-Path: -Received: from mail2.protonmail.ch (mail2.protonmail.ch. [185.70.40.22]) - by mx.google.com with ESMTPS id g6si2999785wrr.110.2021.03.24.22.03.32 - for - (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); - Wed, 24 Mar 2021 22:03:32 -0700 (PDT) -Received-SPF: pass (google.com: domain of bridge-test-user@protonmail.com designates 185.70.40.22 as permitted sender) client-ip=185.70.40.22; -Authentication-Results: mx.google.com; - dkim=pass header.i=@protonmail.com header.s=protonmail header.b=EX07e46H; - spf=pass (google.com: domain of bridge-test-user@protonmail.com designates 185.70.40.22 as permitted sender) smtp.mailfrom=bridge-test-user@protonmail.com; - dmarc=pass (p=QUARANTINE sp=QUARANTINE dis=NONE) header.from=protonmail.com -Date: Thu, 25 Mar 2021 05:03:27 +0000 -DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=protonmail.com; - s=protonmail; t=1616648611; - bh=vmJ0JT+IfeO4idMYP7zPvldBkdONjKTXWTp7ly/B9qk=; - h=Date:To:From:Reply-To:Subject:From; - b=EX07e46H5/HmotAWZ69I4qa5jCVRao/p3KEM3eQn/AQ8s+cLMaR5b2ozdHrPCsTw5 - i5b1DLUHZHBf+6Ven47WJfKNwLUfkAGD2P0aI/dAk/h/h0Bg4Ni85pv+uPpRHLNQKv - T3VnDP9MSwl6IUJu5zoM2EC70MLoiHS07lxhM2pw= -To: External Bridge -From: Bridge Test -Reply-To: Bridge Test -Subject: HTML with attachment external PGP -Message-ID: -MIME-Version: 1.0 -Content-Type: multipart/mixed; - boundary="b1_LCxIUvb0rqBufdwR4JNxMg4ZDMI8x7pRG0vEHGHYwA" -X-Spam-Status: No, score=-1.2 required=10.0 tests=ALL_TRUSTED,DKIM_SIGNED, - DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,FREEMAIL_FROM,HTML_MESSAGE - shortcircuit=no autolearn=disabled version=3.4.4 -X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on - mailout.protonmail.ch - -This is a multi-part message in MIME format. - ---b1_LCxIUvb0rqBufdwR4JNxMg4ZDMI8x7pRG0vEHGHYwA -Content-Type: multipart/alternative; - boundary="b2_LCxIUvb0rqBufdwR4JNxMg4ZDMI8x7pRG0vEHGHYwA" - ---b2_LCxIUvb0rqBufdwR4JNxMg4ZDMI8x7pRG0vEHGHYwA -Content-Type: text/plain; charset=utf-8 -Content-Transfer-Encoding: base64 - -VGhpcyBpcyBib2R5IG9mIEhUTUwgbWFpbCB3aXRoIGF0dGFjaG1lbnQ= - ---b2_LCxIUvb0rqBufdwR4JNxMg4ZDMI8x7pRG0vEHGHYwA -Content-Type: text/html; charset=utf-8 -Content-Transfer-Encoding: base64 - -PGh0bWw+PGhlYWQ+PC9oZWFkPjxib2R5PlRoaXMgaXMgYm9keSBvZiA8Yj5IVE1MIG1haWw8L2I+ -IHdpdGggYXR0YWNobWVudA0KPC9ib2R5PjwvaHRtbD4= - - ---b2_LCxIUvb0rqBufdwR4JNxMg4ZDMI8x7pRG0vEHGHYwA-- - ---b1_LCxIUvb0rqBufdwR4JNxMg4ZDMI8x7pRG0vEHGHYwA -Content-Type: image/png; name=outline-light-instagram-48.png -Content-Transfer-Encoding: base64 -Content-Disposition: attachment; filename=outline-light-instagram-48.png - -iVBORw0KGgoAAAANSUhEUgAAADAAAAAwBAMAAAClLOS0AAAALVBMVEUAAAD///////////////// -//////////////////////////////////////+hSKubAAAADnRSTlMAgO8QQM+/IJ9gj1AwcIQd -OXUAAAGdSURBVDjLXJC9SgNBFIVPXDURTYhgIQghINgowyLYCAYtRFAIgtYhpAjYhC0srCRW6YIg -WNpoHVSsg/gEii+Qnfxq4DyDc3cyMfrBwl2+O+fOHTi8p7LS5RUf/9gpMKL7iT9sK47Q95ggpkzv -1cvRcsGYNMYsmP+zKN27NR2vcDyTNVdfkOuuniNPMWafvIbljt+YoMEvW8y7lt+ARwhvrgPjhA0I -BTng7S1GLPlypBvtIBPidY4YBDJFdtnkscQ5JGaGqxC9i7jSDwcwnB8qHWBaQjw1ABI8wYgtVoG6 -9pFkH8iZIiJeulFt4JLvJq8I5N2GMWYbHWDWzM3JZTMdeSWla0kW86FcuI0mfStiNKQ/AhEeh8h0 -YUTffFwrMTT5oSwdojIQ0UKcocgAKRH1HiqhFQmmJa5qRaYHNbRiSsOgslY0NdixItUTUWlZkedP -HXVyAgAIA1F0wP5btQZPIyTwvAqa/Fl4oacuP+e4XHAjSYpkQkxSiMX+T7FPoZJToSStzED70HCy -KE3NGCg4jJrC6Ti7AFwZLhnW0gMbzFZc0RmmeAAAAABJRU5ErkJggg== - ---b1_LCxIUvb0rqBufdwR4JNxMg4ZDMI8x7pRG0vEHGHYwA-- - - ---------------2F19EE9A8A1A6F779F5D14AF-- - ---avFkF0LAPYPXcFHcnsgGmACbGIPeVDdYc-- - ---Rrmlds5vN3IeeCVjbnepHmuVgyROSBjsS -Content-Type: application/pgp-signature; name="OpenPGP_signature.asc" -Content-Description: OpenPGP digital signature -Content-Disposition: attachment; filename="OpenPGP_signature" - ------BEGIN PGP SIGNATURE----- - -wsB5BAABCAAjFiEEXOYJeXAvKFvzKPmxFhwIdYIjWfcFAmBciIAFAwAAAAAACgkQFhwIdYIjWfcN -ZQf+NzAoEJRTSW5JFNgSGkwLsH89wAbw3wEt4PYuZaa+35xBuU8Sojm1oLOyuPkIasQf98Iu5P1o -8cokViEa6wm+ZZpcFMi6T2/3+UNlSm81Epm7GrFyjAFTWrdTPLb4k4x47sz77RoTp/UEwm/7fVI5 -gMYhQyIYaocXHmDk61UshWE9q/Po6qjHBnnWS8YBnhUS9lK8uimpfRO9UQ9bIUjIYDGDPAtBoYnb -X9V4SjBvbbdNrgoVaDxPw6HYCb3RhzRXunr5Icdnjfbc2H40/FayVi/p7GzFh+8zv/TzRxMkHo72 -DBsONaC7r8bxQ9BwJvpmWufqL7ZXHfVXQ6z+M43e1Q== -=Stx+ ------END PGP SIGNATURE----- - ---Rrmlds5vN3IeeCVjbnepHmuVgyROSBjsS-- +Content-Type: multipart/signed; + boundary=e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855; + micalg=SHA-256; protocol="application/pgp-signature" + +--e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 +Content-Type: multipart/mixed; boundary="------------6sNRIgaKOJHTghuLxPUzlxn1"; + protected-headers="v1" +From: "pm.bridge.qa" +To: "InfernalBridgeTester@proton.me" +Message-ID: <3f60022f-1ff2-9792-926b-a556cc39195d@gmail.com> +Subject: Fwd: simple html body +References: <1655e652-1abc-575f-6e03-5bbf119afbfa@gmail.com> +In-Reply-To: <1655e652-1abc-575f-6e03-5bbf119afbfa@gmail.com> + +--------------6sNRIgaKOJHTghuLxPUzlxn1 +Content-Type: multipart/mixed; boundary="------------Z0a0IncIqoVlOIpOfcALEK5P" + +--------------Z0a0IncIqoVlOIpOfcALEK5P +Content-Type: text/plain; charset=UTF-8; format=flowed +Content-Transfer-Encoding: base64 + +DQo= +--------------Z0a0IncIqoVlOIpOfcALEK5P +Content-Type: message/rfc822; name="simple html body.eml" +Content-Disposition: attachment; filename="simple html body.eml" +Content-Transfer-Encoding: 7bit + +Message-ID: <1655e652-1abc-575f-6e03-5bbf119afbfa@gmail.com> +Date: Tue, 25 Apr 2023 17:12:15 +0200 +MIME-Version: 1.0 +User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:102.0) Gecko/20100101 + Thunderbird/102.10.0 +Content-Language: en-US +To: "InfernalBridgeTester@proton.me" +From: "pm.bridge.qa" +Subject: simple html body +Autocrypt: addr=pm.bridge.qa@gmail.com; keydata= + xsBNBFxlUPwBCACx954Ey4SD88f8DSKFw9BaZNXrNwYxNYSgqaqOGHQ0WllF3mstEhTfuxxC + ZpDhI5IhWCXUNxanzsFkn88mRDwFRVl2sf2aAG4/P/p1381oh2kd0UElMRQaQGzoCadQMaQO + L9WYTf4SPWSCzjrPyKgjq5FbqjbF/ndu376na9L+tnsEXyL6RrI6aZhjWG73xlqxS65dzTIY + zsyM/P97xSndNvlvWtGvLlpFkzxfAEGpVzfOYVYFKoc8rGmUDwrDWYfk5JczRDDogJnY+BNM + Zf9pjSqk6rTyBOfNH5fpU8r7A5Q7l+HVakvMUQ9DzDWJtg2ru1Y8hexnJOF68avO4+a1ABEB + AAHNKEJyaWRnZSBLeXUtRWh5aiA8cG0uYnJpZGdlLnFhQGdtYWlsLmNvbT7CwI4EEwEIADgC + GwMFCwkIBwIGFQoJCAsCBBYCAwECHgECF4AWIQRc5gl5cC8oW/Mo+bEWHAh1giNZ9wUCZEfU + zQAKCRAWHAh1giNZ9872B/4mM6cXErSSYK6/apGUVebg9QiP1RhFlLE/kg7BW3FaSP/yTUZN + ZdX7WPnEVyaa5Dk4xRZiB47Yc5myspwc+JEJ3YDAHq+4n/D74TF1kUCzP+QVsWcn40UqX9gH + bO01O/DYtoxMOljEgkfQjEZcRoHuUhCUzldFf8aV+uZKiOXhrPYCwsilnh0RAmDV7fLoOfKX + MLiKXE8wM/5Bax+dk2AmEM4bOTIo58GGDDqseIg03ocrW7vPegmxiLUwmsHIIDwTq6qZ0CVx + bt2uv4cCyNz/0pmRzG7p8192Evdu8JOuLSj3pI1X00Ub326yay3BBUnsL4PJIGoly8hnLb5N + 3cyNzsBNBFxlUPwBCADh2HsX23yVnJt9fxFz3D07kCBNvu4HQfps6h1rgNxGhE32VmpESHeb + vIB5xjL6xKbIqqRa3x/7KDVBNJvca0gUsqEt5kzYF88Fyf2NBcejpIbcP7BS/g+C6KOowYj+ + Et26T6GdwFXExUcl80JvoX8yHQOfvJpdiBRbjyB8UqfCaknm3c7dNuXmhflz/w3aBj32q9Zy + GqA1NpHCpLyVAlvSNQ/pat/rGUCPZ9duw4KhUUqEmatQPVFPkutTouEZQbMK+i+chOH3AsKC + uNDfvCDwirnsSqIJmAgl1lC4de+bsWYCMqN9ei99hOCRUyhZ3g3sr8RBowVAdcvjZxeIDKAL + ABEBAAHCwHYEGAEIACACGwwWIQRc5gl5cC8oW/Mo+bEWHAh1giNZ9wUCZEfUugAKCRAWHAh1 + giNZ9ycfB/97iOFFeYSFB5CqOxsyo9TjHve0BOzfGyLh632+sUQEw3qqwVreAqrjVa/wnLFW + 67Pbf4GBn6ZnaIMIq4rv6d4wnDZ4b18yQkITErWvU+3thpeZS/NUeWlLZlXFauDhCdPpAq5T + nw7+5lq0pe2BEcNBF4IRoBRs7UQVhr/QpN+xawbnQUM1oIOMljTWuQZtPo75OsltQn59+OTn + 7ZYQD4Q3Sn0vPAzFbPBa4fostzbx8ktTGWfhBctQrpwS06VqoSowr8RFY9S+ssjCK+Hlq2t8 + ZC0CBL1aU1AAPqcAOfrw9rin0rN1dH07g1uDeZ9SnyLuee5QN7r3VY8b9tiOJV9m +Content-Type: multipart/signed; micalg=pgp-sha256; + protocol="application/pgp-signature"; + boundary="------------Kh8bXWpcGJrKDmQHlv9QWtgJ" + +This is an OpenPGP/MIME signed message (RFC 4880 and 3156) +--------------Kh8bXWpcGJrKDmQHlv9QWtgJ +Content-Type: multipart/mixed; boundary="------------iFRY0nd000IWAcfqrg6ZdUuF"; + protected-headers="v1" +From: "pm.bridge.qa" +To: "InfernalBridgeTester@proton.me" +Message-ID: <1655e652-1abc-575f-6e03-5bbf119afbfa@gmail.com> +Subject: simple html body + +--------------iFRY0nd000IWAcfqrg6ZdUuF +Content-Type: multipart/mixed; boundary="------------0tRoF00iqRv70TBczVNfagKk" + +--------------0tRoF00iqRv70TBczVNfagKk +Content-Type: text/html; charset=UTF-8 +Content-Transfer-Encoding: quoted-printable + + + + + + + +

+

And this is HTML
+

+
    +
  • Do I enjoy making courthouse puns? + Guilty.=3D3DE2=3D3D80=3D3D9=3D + 4 @=3D3D baddadjokes
  • +
  • Can February March? No, but April May. =3D3DE2=3D3D80=3D= +3D94@Bear=3D3D + dedMOGuy
  • +
+


+

+

+ +

+ + +--------------0tRoF00iqRv70TBczVNfagKk +Content-Type: application/pgp-keys; name="OpenPGP_0x161C0875822359F7.asc" +Content-Disposition: attachment; filename="OpenPGP_0x161C0875822359F7.asc" +Content-Description: OpenPGP public key +Content-Transfer-Encoding: quoted-printable + +-----BEGIN PGP PUBLIC KEY BLOCK----- + +xsBNBFxlUPwBCACx954Ey4SD88f8DSKFw9BaZNXrNwYxNYSgqaqOGHQ0WllF3mst +EhTfuxxCZpDhI5IhWCXUNxanzsFkn88mRDwFRVl2sf2aAG4/P/p1381oh2kd0UEl +MRQaQGzoCadQMaQOL9WYTf4SPWSCzjrPyKgjq5FbqjbF/ndu376na9L+tnsEXyL6 +RrI6aZhjWG73xlqxS65dzTIYzsyM/P97xSndNvlvWtGvLlpFkzxfAEGpVzfOYVYF +Koc8rGmUDwrDWYfk5JczRDDogJnY+BNMZf9pjSqk6rTyBOfNH5fpU8r7A5Q7l+HV +akvMUQ9DzDWJtg2ru1Y8hexnJOF68avO4+a1ABEBAAHNKEJyaWRnZSBLeXUtRWh5 +aiA8cG0uYnJpZGdlLnFhQGdtYWlsLmNvbT7CwI4EEwEIADgCGwMFCwkIBwIGFQoJ +CAsCBBYCAwECHgECF4AWIQRc5gl5cC8oW/Mo+bEWHAh1giNZ9wUCZEfUzQAKCRAW +HAh1giNZ9872B/4mM6cXErSSYK6/apGUVebg9QiP1RhFlLE/kg7BW3FaSP/yTUZN +ZdX7WPnEVyaa5Dk4xRZiB47Yc5myspwc+JEJ3YDAHq+4n/D74TF1kUCzP+QVsWcn +40UqX9gHbO01O/DYtoxMOljEgkfQjEZcRoHuUhCUzldFf8aV+uZKiOXhrPYCwsil +nh0RAmDV7fLoOfKXMLiKXE8wM/5Bax+dk2AmEM4bOTIo58GGDDqseIg03ocrW7vP +egmxiLUwmsHIIDwTq6qZ0CVxbt2uv4cCyNz/0pmRzG7p8192Evdu8JOuLSj3pI1X +00Ub326yay3BBUnsL4PJIGoly8hnLb5N3cyNwsCUBBMBCAA+FiEEXOYJeXAvKFvz +KPmxFhwIdYIjWfcFAlxlUPwCGwMFCQPCZwAFCwkIBwIGFQoJCAsCBBYCAwECHgEC +F4AACgkQFhwIdYIjWfeQzgf+NWseR+UvrJ7I1CFd6M2+RmyIC1QTQ+uyJIhIBQfC +vBhueU9GUPWR6a6GWsb2DGCMkBM2aHoTCcf46fq87VspYb3+b0JsKfRFxBa2cuNH +Ey6PK3xHBDnYFtSZaRB7QMQMfYVin5oyHq8mOd4mImOKfpGhuuhq1hrT8sOhVxRY +Nl/2Hanya7tEJlVyAAEwtN4QVCqiRjjD7kBQ+mgxdDFo62X+sl4Zz2BFlZks+c1+ +LRWwaQZvGgf2tm2NqZhC04CKc2Gg5j7wNJBPVh/FVluxY27D2hV6v9/cTvXDGo8J +pnZ28CnQqiiaKEU83BGwcUlcr4G5YApHyIPujaxffE2R887ATQRcZVD8AQgA4dh7 +F9t8lZybfX8Rc9w9O5AgTb7uB0H6bOoda4DcRoRN9lZqREh3m7yAecYy+sSmyKqk +Wt8f+yg1QTSb3GtIFLKhLeZM2BfPBcn9jQXHo6SG3D+wUv4PguijqMGI/hLduk+h +ncBVxMVHJfNCb6F/Mh0Dn7yaXYgUW48gfFKnwmpJ5t3O3Tbl5oX5c/8N2gY99qvW +chqgNTaRwqS8lQJb0jUP6Wrf6xlAj2fXbsOCoVFKhJmrUD1RT5LrU6LhGUGzCvov +nITh9wLCgrjQ37wg8Iq57EqiCZgIJdZQuHXvm7FmAjKjfXovfYTgkVMoWd4N7K/E +QaMFQHXL42cXiAygCwARAQABwsB2BBgBCAAgAhsMFiEEXOYJeXAvKFvzKPmxFhwI +dYIjWfcFAmRH1LoACgkQFhwIdYIjWfcnHwf/e4jhRXmEhQeQqjsbMqPU4x73tATs +3xsi4et9vrFEBMN6qsFa3gKq41Wv8JyxVuuz23+BgZ+mZ2iDCKuK7+neMJw2eG9f +MkJCExK1r1Pt7YaXmUvzVHlpS2ZVxWrg4QnT6QKuU58O/uZatKXtgRHDQReCEaAU +bO1EFYa/0KTfsWsG50FDNaCDjJY01rkGbT6O+TrJbUJ+ffjk5+2WEA+EN0p9LzwM +xWzwWuH6LLc28fJLUxln4QXLUK6cEtOlaqEqMK/ERWPUvrLIwivh5atrfGQtAgS9 +WlNQAD6nADn68Pa4p9KzdXR9O4Nbg3mfUp8i7nnuUDe691WPG/bYjiVfZsLAfAQY +AQgAJhYhBFzmCXlwLyhb8yj5sRYcCHWCI1n3BQJcZVD8AhsMBQkDwmcAAAoJEBYc +CHWCI1n3rhcH/iCB0ZV861H0RKJ2F7bXEyCLR2ncBFUCnFo3muSrN9NXTojz2vwv +zexRBpZzaRJoksBkvH+ofuZ1iK7ycZO23dnukvPwGQsz3QiITjVeB6ZR0250MG1q +A5yZRlZCsCbGJb4/2e8Ey8BbblHn49Zta4l2Ex5NpNNQ8FYoqXhXu5Bd2F/wX/Bp +5gkZegfE3H9Dw4QjP82Mt0RZSBg9RMGCk6nNfEuze1Up+IOdtqzf3/Z8J5XxLzN2 +s8WPmDwJDwvxJRtto8U+ulv4ElcwlA+wYiKAq7cRCKGM/si5ClkUNgb319grUrBU +6h8SuYtgnD84965xRiVAgtH4wCPN544N8CE=3D +=3DNmqc +-----END PGP PUBLIC KEY BLOCK----- + +--------------0tRoF00iqRv70TBczVNfagKk-- + +--------------iFRY0nd000IWAcfqrg6ZdUuF-- + +--------------Kh8bXWpcGJrKDmQHlv9QWtgJ +Content-Type: application/pgp-signature; name="OpenPGP_signature.asc" +Content-Description: OpenPGP digital signature +Content-Disposition: attachment; filename="OpenPGP_signature" + +-----BEGIN PGP SIGNATURE----- + +wsB5BAABCAAjFiEEXOYJeXAvKFvzKPmxFhwIdYIjWfcFAmRH7c8FAwAAAAAACgkQFhwIdYIjWffG +uQgAlK68JzT/9NLOg4SZPUbVaEdlbru6ebX1Lwaj93FZEKfmiEZ4heuYfq4yVw1JI/CGhHa1wxUJ +M6+Tg+0lqIslG1rTposgIziugMBhEWXYWXBwDdvu+9T2eqo0se3h+oXueVlRihowfuPcP9jvt6p3 +DR+pu+hJ/D42DarJrn8v0CMm3PyLNHodyKLmEtZrzP4ok9Wal850xZ3Tmu5dL3v300wPGJaxrn8o +4OeHRUodE43UijUrFKNoEfhqzY8HsMKIdF8Bi6+XiA0sHwcaUqJsaczBqgmbJbPqG8N4CokiUnUu +4QDmClWa0rG4I5rrx4PrTbzAt7cGIb8N3ACNI7vI/Q== +=Llod +-----END PGP SIGNATURE----- + +--------------Kh8bXWpcGJrKDmQHlv9QWtgJ-- +--------------Z0a0IncIqoVlOIpOfcALEK5P +Content-Type: application/pgp-keys; name="OpenPGP_0x161C0875822359F7.asc" +Content-Disposition: attachment; filename="OpenPGP_0x161C0875822359F7.asc" +Content-Description: OpenPGP public key +Content-Transfer-Encoding: quoted-printable + +-----BEGIN PGP PUBLIC KEY BLOCK----- + +xsBNBFxlUPwBCACx954Ey4SD88f8DSKFw9BaZNXrNwYxNYSgqaqOGHQ0WllF3mst +EhTfuxxCZpDhI5IhWCXUNxanzsFkn88mRDwFRVl2sf2aAG4/P/p1381oh2kd0UEl +MRQaQGzoCadQMaQOL9WYTf4SPWSCzjrPyKgjq5FbqjbF/ndu376na9L+tnsEXyL6 +RrI6aZhjWG73xlqxS65dzTIYzsyM/P97xSndNvlvWtGvLlpFkzxfAEGpVzfOYVYF +Koc8rGmUDwrDWYfk5JczRDDogJnY+BNMZf9pjSqk6rTyBOfNH5fpU8r7A5Q7l+HV +akvMUQ9DzDWJtg2ru1Y8hexnJOF68avO4+a1ABEBAAHNKEJyaWRnZSBLeXUtRWh5 +aiA8cG0uYnJpZGdlLnFhQGdtYWlsLmNvbT7CwI4EEwEIADgCGwMFCwkIBwIGFQoJ +CAsCBBYCAwECHgECF4AWIQRc5gl5cC8oW/Mo+bEWHAh1giNZ9wUCZEfUzQAKCRAW +HAh1giNZ9872B/4mM6cXErSSYK6/apGUVebg9QiP1RhFlLE/kg7BW3FaSP/yTUZN +ZdX7WPnEVyaa5Dk4xRZiB47Yc5myspwc+JEJ3YDAHq+4n/D74TF1kUCzP+QVsWcn +40UqX9gHbO01O/DYtoxMOljEgkfQjEZcRoHuUhCUzldFf8aV+uZKiOXhrPYCwsil +nh0RAmDV7fLoOfKXMLiKXE8wM/5Bax+dk2AmEM4bOTIo58GGDDqseIg03ocrW7vP +egmxiLUwmsHIIDwTq6qZ0CVxbt2uv4cCyNz/0pmRzG7p8192Evdu8JOuLSj3pI1X +00Ub326yay3BBUnsL4PJIGoly8hnLb5N3cyNwsCUBBMBCAA+FiEEXOYJeXAvKFvz +KPmxFhwIdYIjWfcFAlxlUPwCGwMFCQPCZwAFCwkIBwIGFQoJCAsCBBYCAwECHgEC +F4AACgkQFhwIdYIjWfeQzgf+NWseR+UvrJ7I1CFd6M2+RmyIC1QTQ+uyJIhIBQfC +vBhueU9GUPWR6a6GWsb2DGCMkBM2aHoTCcf46fq87VspYb3+b0JsKfRFxBa2cuNH +Ey6PK3xHBDnYFtSZaRB7QMQMfYVin5oyHq8mOd4mImOKfpGhuuhq1hrT8sOhVxRY +Nl/2Hanya7tEJlVyAAEwtN4QVCqiRjjD7kBQ+mgxdDFo62X+sl4Zz2BFlZks+c1+ +LRWwaQZvGgf2tm2NqZhC04CKc2Gg5j7wNJBPVh/FVluxY27D2hV6v9/cTvXDGo8J +pnZ28CnQqiiaKEU83BGwcUlcr4G5YApHyIPujaxffE2R887ATQRcZVD8AQgA4dh7 +F9t8lZybfX8Rc9w9O5AgTb7uB0H6bOoda4DcRoRN9lZqREh3m7yAecYy+sSmyKqk +Wt8f+yg1QTSb3GtIFLKhLeZM2BfPBcn9jQXHo6SG3D+wUv4PguijqMGI/hLduk+h +ncBVxMVHJfNCb6F/Mh0Dn7yaXYgUW48gfFKnwmpJ5t3O3Tbl5oX5c/8N2gY99qvW +chqgNTaRwqS8lQJb0jUP6Wrf6xlAj2fXbsOCoVFKhJmrUD1RT5LrU6LhGUGzCvov +nITh9wLCgrjQ37wg8Iq57EqiCZgIJdZQuHXvm7FmAjKjfXovfYTgkVMoWd4N7K/E +QaMFQHXL42cXiAygCwARAQABwsB2BBgBCAAgAhsMFiEEXOYJeXAvKFvzKPmxFhwI +dYIjWfcFAmRH1LoACgkQFhwIdYIjWfcnHwf/e4jhRXmEhQeQqjsbMqPU4x73tATs +3xsi4et9vrFEBMN6qsFa3gKq41Wv8JyxVuuz23+BgZ+mZ2iDCKuK7+neMJw2eG9f +MkJCExK1r1Pt7YaXmUvzVHlpS2ZVxWrg4QnT6QKuU58O/uZatKXtgRHDQReCEaAU +bO1EFYa/0KTfsWsG50FDNaCDjJY01rkGbT6O+TrJbUJ+ffjk5+2WEA+EN0p9LzwM +xWzwWuH6LLc28fJLUxln4QXLUK6cEtOlaqEqMK/ERWPUvrLIwivh5atrfGQtAgS9 +WlNQAD6nADn68Pa4p9KzdXR9O4Nbg3mfUp8i7nnuUDe691WPG/bYjiVfZsLAfAQY +AQgAJhYhBFzmCXlwLyhb8yj5sRYcCHWCI1n3BQJcZVD8AhsMBQkDwmcAAAoJEBYc +CHWCI1n3rhcH/iCB0ZV861H0RKJ2F7bXEyCLR2ncBFUCnFo3muSrN9NXTojz2vwv +zexRBpZzaRJoksBkvH+ofuZ1iK7ycZO23dnukvPwGQsz3QiITjVeB6ZR0250MG1q +A5yZRlZCsCbGJb4/2e8Ey8BbblHn49Zta4l2Ex5NpNNQ8FYoqXhXu5Bd2F/wX/Bp +5gkZegfE3H9Dw4QjP82Mt0RZSBg9RMGCk6nNfEuze1Up+IOdtqzf3/Z8J5XxLzN2 +s8WPmDwJDwvxJRtto8U+ulv4ElcwlA+wYiKAq7cRCKGM/si5ClkUNgb319grUrBU +6h8SuYtgnD84965xRiVAgtH4wCPN544N8CE=3D +=3DNmqc +-----END PGP PUBLIC KEY BLOCK----- + +--------------Z0a0IncIqoVlOIpOfcALEK5P-- + +--------------6sNRIgaKOJHTghuLxPUzlxn1-- + +--e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 +Content-Description: OpenPGP digital signature +Content-Disposition: attachment; filename=OpenPGP_signature +Content-Type: application/pgp-signature; name=OpenPGP_signature.asc + +-----BEGIN PGP SIGNATURE----- +Version: GopenPGP 2.7.1 +Comment: https://gopenpgp.org + +wsB5BAABCAAjFiEEXOYJeXAvKFvzKPmxFhwIdYIjWfcFAmRIzW4FAwAAAAAACgkQ +FhwIdYIjWfe84QgAj1mf/g/jvobkik9RRvyUCN3InyHBqcwMOgyVDmd4U5uh/DVZ +sZ8kFU+/koEfr/8+Y7ataenEG5pY2f4krZNzc85VzjwniK1xcjxDW86UFa/ud/2Q +OD7eqJUQO1UpuQ/xe4gbfy3BKvTp5u09UjcBDnZ/lHASSREpfGBhk37Y2lkb5iIP +4KR7DOi1S1MFrdDPgKp59B9mk2ZMSC1Njzido9Zm/2tdYldAI66uMQiMgB2iv7yn +FMGxKzewt2OxZWKVmNaAzzvrQw7AYfIr70NbwnK75Gmh1CkwLadNpzSRMCqW5BP6 +TsypxeGfXuQi0upWT2E3YpIvtkOrHRGXY9jXNw== +=5Yce +-----END PGP SIGNATURE----- +--e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855-- diff --git a/pkg/message/testdata/pgp-mime-body-signed-html-with-pubkey.eml b/pkg/message/testdata/pgp-mime-body-signed-html-with-pubkey.eml index 9f530e7f..3191731e 100644 --- a/pkg/message/testdata/pgp-mime-body-signed-html-with-pubkey.eml +++ b/pkg/message/testdata/pgp-mime-body-signed-html-with-pubkey.eml @@ -1,116 +1,119 @@ -Content-Type: multipart/signed; micalg=pgp-sha256; - protocol="application/pgp-signature"; - boundary="pavrbLYh8Q4RWBboYnVxY3mNBBzan1Zz4" - -This is an OpenPGP/MIME signed message (RFC 4880 and 3156) ---pavrbLYh8Q4RWBboYnVxY3mNBBzan1Zz4 -Content-Type: multipart/mixed; boundary="avFoFILZo8SdHM1Pc1OUviN4UKQh16HyR"; - protected-headers="v1" -Subject: simple html body -From: "pm.bridge.qa" -To: schizofrenic@pm.me -Message-ID: - ---avFoFILZo8SdHM1Pc1OUviN4UKQh16HyR -Content-Type: multipart/mixed; - boundary="------------9EAE2E1A715ACB9849E5C4E3" -Content-Language: en-US - -This is a multi-part message in MIME format. ---------------9EAE2E1A715ACB9849E5C4E3 -Content-Type: text/html; charset=utf-8 -Content-Transfer-Encoding: quoted-printable - - - - - - - - And this is HTML
-
    -
  • Do I enjoy making courthouse puns? Guilty.=E2=80=94 @= -baddadjokes
  • -
  • Can February March? No, but April May. =E2=80=94@Bear= -dedMOGuy
  • -
- - - ---------------9EAE2E1A715ACB9849E5C4E3 -Content-Type: application/pgp-keys; - name="OpenPGP_0x161C0875822359F7.asc" -Content-Transfer-Encoding: quoted-printable -Content-Disposition: attachment; - filename="OpenPGP_0x161C0875822359F7.asc" - ------BEGIN PGP PUBLIC KEY BLOCK----- - -xsBNBFxlUPwBCACx954Ey4SD88f8DSKFw9BaZNXrNwYxNYSgqaqOGHQ0WllF3mstEhTfuxxCZ= -pDh -I5IhWCXUNxanzsFkn88mRDwFRVl2sf2aAG4/P/p1381oh2kd0UElMRQaQGzoCadQMaQOL9WYT= -f4S -PWSCzjrPyKgjq5FbqjbF/ndu376na9L+tnsEXyL6RrI6aZhjWG73xlqxS65dzTIYzsyM/P97x= -Snd -NvlvWtGvLlpFkzxfAEGpVzfOYVYFKoc8rGmUDwrDWYfk5JczRDDogJnY+BNMZf9pjSqk6rTyB= -OfN -H5fpU8r7A5Q7l+HVakvMUQ9DzDWJtg2ru1Y8hexnJOF68avO4+a1ABEBAAHNKEJyaWRnZSBLe= -XUt -RWh5aiA8cG0uYnJpZGdlLnFhQGdtYWlsLmNvbT7CwJQEEwEIAD4CGwMFCwkIBwIGFQoJCAsCB= -BYC -AwECHgECF4AWIQRc5gl5cC8oW/Mo+bEWHAh1giNZ9wUCYC32ygUJB4sMzgAKCRAWHAh1giNZ9= -/K8 -B/4qs84Ii/zKH+q+C8vwO4jUJkOM73qD0pgB7zBs651zWbpgopyol1YUKNpFaHlx/Qch7RDI7= -Vcz -1+60/KZJSJR19/N2EDVbCUdh8ueioUp9X/218YWV2TRJNxTnljd4FAn7smZnXuP1TsLjQ6sKO= -V0U -u6JoiG6LZFXqDgxYpA++58Rkl6xaY6R71VkmVQlbEKtubX9AjHydq97Y+Jvn11XzWZaKhv4L7= -6Pa -4tMKXvvrKh1oywMmh6mZJo+5ZA/ABTkr45cwlTPYqGTS9+uvOHt+PH/oYwwJB4ls2cIAUldSj= -TVQ -IsseYz3LlbcCfKJiiCFxeHOQXA5J6zNLKOT58TsczsBNBFxlUPwBCADh2HsX23yVnJt9fxFz3= -D07 -kCBNvu4HQfps6h1rgNxGhE32VmpESHebvIB5xjL6xKbIqqRa3x/7KDVBNJvca0gUsqEt5kzYF= -88F -yf2NBcejpIbcP7BS/g+C6KOowYj+Et26T6GdwFXExUcl80JvoX8yHQOfvJpdiBRbjyB8UqfCa= -knm -3c7dNuXmhflz/w3aBj32q9ZyGqA1NpHCpLyVAlvSNQ/pat/rGUCPZ9duw4KhUUqEmatQPVFPk= -utT -ouEZQbMK+i+chOH3AsKCuNDfvCDwirnsSqIJmAgl1lC4de+bsWYCMqN9ei99hOCRUyhZ3g3sr= -8RB -owVAdcvjZxeIDKALABEBAAHCwHwEGAEIACYCGwwWIQRc5gl5cC8oW/Mo+bEWHAh1giNZ9wUCY= -C32 -lAUJB4sMmAAKCRAWHAh1giNZ9+Y2B/9rTKZaKviae+ummXNumXcrKvbkAAvfuLpKUn53FlQLm= -L6H -jB++lJnPWvVSzdZxdv8FiPP3d632XHKUrkQRQM/9byRDXDommi7Qttx7YCkhd4JLVYqJqpnAQ= -xI5 -RMkXiZNWyr1lz8JOM1XvDk1M7sJwPMWews8VOIE03E1nt7AsQGnvHtadgEnQaufrYNX3hFA8S= -osO -HSnedcys6yrzCSIGCqCD9VHbnMtS4DOv0XJGh2hwc8omzH0KZA517dyKBorJRwadcVauGXDKx= -Etv -Im4rl94PR/3An1Mj6HeeVVpLqDQ5Jb9J90BahWeQ53FzRa4EQzYCw0nLnxcsT1ZEEP5u -=3Dv/1p ------END PGP PUBLIC KEY BLOCK----- - ---------------9EAE2E1A715ACB9849E5C4E3-- - ---avFoFILZo8SdHM1Pc1OUviN4UKQh16HyR-- - ---pavrbLYh8Q4RWBboYnVxY3mNBBzan1Zz4 -Content-Type: application/pgp-signature; name="OpenPGP_signature.asc" -Content-Description: OpenPGP digital signature -Content-Disposition: attachment; filename="OpenPGP_signature" - ------BEGIN PGP SIGNATURE----- - -wsB5BAABCAAjFiEEXOYJeXAvKFvzKPmxFhwIdYIjWfcFAmBa9hAFAwAAAAAACgkQFhwIdYIjWffL -1AgApF18AVOPEm9y5R+d0NQmxqhSwAtvaqCwqQpG3mArIYK3Y0zrDkPQZZl/3emW8LWht7ZyYCAb -NZo7HoYxjLy3yxAOPUl/Pc0nJpEqk/wAZT58yOnzv8DU5Q9o+444FfTMJpcrcH/M5cXYyqRtVhas -k5wu5u2DEgSO3Kj/5l7lThb+CUgRC6wSiOuUkqGEWLiAguCdd88XDkLMbwrDnOu3PbhcA8o1msns -PfkBdq3mFjp4M8M4ha+D2MxmV6tBv1E7snWf/spBVb9fHIa7zI4ZS6shpzGHCnJarO0Jco0Qh3IZ -ZVfwhtJeFsmdqSm6DLvCmQWAYk2fDOZDMVKqe9IbUA== -=pkS0 ------END PGP SIGNATURE----- - ---pavrbLYh8Q4RWBboYnVxY3mNBBzan1Zz4-- +Content-Type: multipart/signed; + boundary=e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855; + micalg=SHA-256; protocol="application/pgp-signature" + +--e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 +Content-Type: multipart/mixed; boundary="------------iFRY0nd000IWAcfqrg6ZdUuF"; + protected-headers="v1" +From: "pm.bridge.qa" +To: "InfernalBridgeTester@proton.me" +Message-ID: <1655e652-1abc-575f-6e03-5bbf119afbfa@gmail.com> +Subject: simple html body + +--------------iFRY0nd000IWAcfqrg6ZdUuF +Content-Type: multipart/mixed; boundary="------------0tRoF00iqRv70TBczVNfagKk" + +--------------0tRoF00iqRv70TBczVNfagKk +Content-Type: text/html; charset=UTF-8 +Content-Transfer-Encoding: quoted-printable + + + + + + + +

+

And this is HTML
+

+
    +
  • Do I enjoy making courthouse puns? + Guilty.=3D3DE2=3D3D80=3D3D9=3D + 4 @=3D3D baddadjokes
  • +
  • Can February March? No, but April May. =3D3DE2=3D3D80=3D= +3D94@Bear=3D3D + dedMOGuy
  • +
+


+

+

+ +

+ + +--------------0tRoF00iqRv70TBczVNfagKk +Content-Type: application/pgp-keys; name="OpenPGP_0x161C0875822359F7.asc" +Content-Disposition: attachment; filename="OpenPGP_0x161C0875822359F7.asc" +Content-Description: OpenPGP public key +Content-Transfer-Encoding: quoted-printable + +-----BEGIN PGP PUBLIC KEY BLOCK----- + +xsBNBFxlUPwBCACx954Ey4SD88f8DSKFw9BaZNXrNwYxNYSgqaqOGHQ0WllF3mst +EhTfuxxCZpDhI5IhWCXUNxanzsFkn88mRDwFRVl2sf2aAG4/P/p1381oh2kd0UEl +MRQaQGzoCadQMaQOL9WYTf4SPWSCzjrPyKgjq5FbqjbF/ndu376na9L+tnsEXyL6 +RrI6aZhjWG73xlqxS65dzTIYzsyM/P97xSndNvlvWtGvLlpFkzxfAEGpVzfOYVYF +Koc8rGmUDwrDWYfk5JczRDDogJnY+BNMZf9pjSqk6rTyBOfNH5fpU8r7A5Q7l+HV +akvMUQ9DzDWJtg2ru1Y8hexnJOF68avO4+a1ABEBAAHNKEJyaWRnZSBLeXUtRWh5 +aiA8cG0uYnJpZGdlLnFhQGdtYWlsLmNvbT7CwI4EEwEIADgCGwMFCwkIBwIGFQoJ +CAsCBBYCAwECHgECF4AWIQRc5gl5cC8oW/Mo+bEWHAh1giNZ9wUCZEfUzQAKCRAW +HAh1giNZ9872B/4mM6cXErSSYK6/apGUVebg9QiP1RhFlLE/kg7BW3FaSP/yTUZN +ZdX7WPnEVyaa5Dk4xRZiB47Yc5myspwc+JEJ3YDAHq+4n/D74TF1kUCzP+QVsWcn +40UqX9gHbO01O/DYtoxMOljEgkfQjEZcRoHuUhCUzldFf8aV+uZKiOXhrPYCwsil +nh0RAmDV7fLoOfKXMLiKXE8wM/5Bax+dk2AmEM4bOTIo58GGDDqseIg03ocrW7vP +egmxiLUwmsHIIDwTq6qZ0CVxbt2uv4cCyNz/0pmRzG7p8192Evdu8JOuLSj3pI1X +00Ub326yay3BBUnsL4PJIGoly8hnLb5N3cyNwsCUBBMBCAA+FiEEXOYJeXAvKFvz +KPmxFhwIdYIjWfcFAlxlUPwCGwMFCQPCZwAFCwkIBwIGFQoJCAsCBBYCAwECHgEC +F4AACgkQFhwIdYIjWfeQzgf+NWseR+UvrJ7I1CFd6M2+RmyIC1QTQ+uyJIhIBQfC +vBhueU9GUPWR6a6GWsb2DGCMkBM2aHoTCcf46fq87VspYb3+b0JsKfRFxBa2cuNH +Ey6PK3xHBDnYFtSZaRB7QMQMfYVin5oyHq8mOd4mImOKfpGhuuhq1hrT8sOhVxRY +Nl/2Hanya7tEJlVyAAEwtN4QVCqiRjjD7kBQ+mgxdDFo62X+sl4Zz2BFlZks+c1+ +LRWwaQZvGgf2tm2NqZhC04CKc2Gg5j7wNJBPVh/FVluxY27D2hV6v9/cTvXDGo8J +pnZ28CnQqiiaKEU83BGwcUlcr4G5YApHyIPujaxffE2R887ATQRcZVD8AQgA4dh7 +F9t8lZybfX8Rc9w9O5AgTb7uB0H6bOoda4DcRoRN9lZqREh3m7yAecYy+sSmyKqk +Wt8f+yg1QTSb3GtIFLKhLeZM2BfPBcn9jQXHo6SG3D+wUv4PguijqMGI/hLduk+h +ncBVxMVHJfNCb6F/Mh0Dn7yaXYgUW48gfFKnwmpJ5t3O3Tbl5oX5c/8N2gY99qvW +chqgNTaRwqS8lQJb0jUP6Wrf6xlAj2fXbsOCoVFKhJmrUD1RT5LrU6LhGUGzCvov +nITh9wLCgrjQ37wg8Iq57EqiCZgIJdZQuHXvm7FmAjKjfXovfYTgkVMoWd4N7K/E +QaMFQHXL42cXiAygCwARAQABwsB2BBgBCAAgAhsMFiEEXOYJeXAvKFvzKPmxFhwI +dYIjWfcFAmRH1LoACgkQFhwIdYIjWfcnHwf/e4jhRXmEhQeQqjsbMqPU4x73tATs +3xsi4et9vrFEBMN6qsFa3gKq41Wv8JyxVuuz23+BgZ+mZ2iDCKuK7+neMJw2eG9f +MkJCExK1r1Pt7YaXmUvzVHlpS2ZVxWrg4QnT6QKuU58O/uZatKXtgRHDQReCEaAU +bO1EFYa/0KTfsWsG50FDNaCDjJY01rkGbT6O+TrJbUJ+ffjk5+2WEA+EN0p9LzwM +xWzwWuH6LLc28fJLUxln4QXLUK6cEtOlaqEqMK/ERWPUvrLIwivh5atrfGQtAgS9 +WlNQAD6nADn68Pa4p9KzdXR9O4Nbg3mfUp8i7nnuUDe691WPG/bYjiVfZsLAfAQY +AQgAJhYhBFzmCXlwLyhb8yj5sRYcCHWCI1n3BQJcZVD8AhsMBQkDwmcAAAoJEBYc +CHWCI1n3rhcH/iCB0ZV861H0RKJ2F7bXEyCLR2ncBFUCnFo3muSrN9NXTojz2vwv +zexRBpZzaRJoksBkvH+ofuZ1iK7ycZO23dnukvPwGQsz3QiITjVeB6ZR0250MG1q +A5yZRlZCsCbGJb4/2e8Ey8BbblHn49Zta4l2Ex5NpNNQ8FYoqXhXu5Bd2F/wX/Bp +5gkZegfE3H9Dw4QjP82Mt0RZSBg9RMGCk6nNfEuze1Up+IOdtqzf3/Z8J5XxLzN2 +s8WPmDwJDwvxJRtto8U+ulv4ElcwlA+wYiKAq7cRCKGM/si5ClkUNgb319grUrBU +6h8SuYtgnD84965xRiVAgtH4wCPN544N8CE=3D +=3DNmqc +-----END PGP PUBLIC KEY BLOCK----- + +--------------0tRoF00iqRv70TBczVNfagKk-- + +--------------iFRY0nd000IWAcfqrg6ZdUuF-- + +--e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 +Content-Description: OpenPGP digital signature +Content-Disposition: attachment; filename=OpenPGP_signature +Content-Type: application/pgp-signature; name=OpenPGP_signature.asc + +-----BEGIN PGP SIGNATURE----- +Version: GopenPGP 2.7.1 +Comment: https://gopenpgp.org + +wsB5BAABCAAjFiEEXOYJeXAvKFvzKPmxFhwIdYIjWfcFAmRH7c8FAwAAAAAACgkQ +FhwIdYIjWffGuQgAlK68JzT/9NLOg4SZPUbVaEdlbru6ebX1Lwaj93FZEKfmiEZ4 +heuYfq4yVw1JI/CGhHa1wxUJM6+Tg+0lqIslG1rTposgIziugMBhEWXYWXBwDdvu ++9T2eqo0se3h+oXueVlRihowfuPcP9jvt6p3DR+pu+hJ/D42DarJrn8v0CMm3PyL +NHodyKLmEtZrzP4ok9Wal850xZ3Tmu5dL3v300wPGJaxrn8o4OeHRUodE43UijUr +FKNoEfhqzY8HsMKIdF8Bi6+XiA0sHwcaUqJsaczBqgmbJbPqG8N4CokiUnUu4QDm +ClWa0rG4I5rrx4PrTbzAt7cGIb8N3ACNI7vI/Q== +=Llod +-----END PGP SIGNATURE----- +--e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855-- diff --git a/pkg/message/testdata/pgp-mime-body-signed-multipart-alternative-with-pubkey.eml b/pkg/message/testdata/pgp-mime-body-signed-multipart-alternative-with-pubkey.eml index cfbf3434..3476abf3 100644 --- a/pkg/message/testdata/pgp-mime-body-signed-multipart-alternative-with-pubkey.eml +++ b/pkg/message/testdata/pgp-mime-body-signed-multipart-alternative-with-pubkey.eml @@ -1,161 +1,143 @@ -Content-Type: multipart/signed; micalg=pgp-sha256; - protocol="application/pgp-signature"; - boundary="MHEDFShwcX18dyE3X7RXujo5fjpgdjHNM" - -This is an OpenPGP/MIME signed message (RFC 4880 and 3156) ---MHEDFShwcX18dyE3X7RXujo5fjpgdjHNM -Content-Type: multipart/mixed; boundary="FBBl2LNv76z8UkvHhSkT9vLwVwxqV8378"; - protected-headers="v1" -Subject: Alternative -From: "pm.bridge.qa" -To: schizofrenic@pm.me -Message-ID: <753d0314-0286-2c88-2abb-f8080ac7a4cb@gmail.com> - ---FBBl2LNv76z8UkvHhSkT9vLwVwxqV8378 -Content-Type: multipart/mixed; - boundary="------------F97C8ED4878E94675762AE43" -Content-Language: en-US - -This is a multi-part message in MIME format. ---------------F97C8ED4878E94675762AE43 -Content-Type: multipart/alternative; - boundary="------------041318B15DD3FA540FED32C6" - - ---------------041318B15DD3FA540FED32C6 -Content-Type: text/plain; charset=utf-8; format=flowed -Content-Transfer-Encoding: quoted-printable - -This Rich formated text - - * /What kind of shoes do ninjas wear? /*Sneakers!* - * /How does a penguin build its house?/**_/*Igloos it together.*/_ - - - - ---------------041318B15DD3FA540FED32C6 -Content-Type: text/html; charset=utf-8 -Content-Transfer-Encoding: quoted-printable - - - - - - - -

This Rich formated text

-
    -
  • What kind of shoes do ninjas wear? Sneakers!
  • = - -
  • How does a penguin build its house? Iglo= -os - it together.
  • -
-


-

-


-

- - - ---------------041318B15DD3FA540FED32C6-- - ---------------F97C8ED4878E94675762AE43 -Content-Type: application/pdf; - name="minimal.pdf" -Content-Transfer-Encoding: base64 -Content-Disposition: attachment; - filename="minimal.pdf" - -JVBERi0xLjEKJcKlwrHDqwoKMSAwIG9iagogIDw8IC9UeXBlIC9DYXRhbG9nCiAgICAgL1Bh -Z2VzIDIgMCBSCiAgPj4KZW5kb2JqCgoyIDAgb2JqCiAgPDwgL1R5cGUgL1BhZ2VzCiAgICAg -L0tpZHMgWzMgMCBSXQogICAgIC9Db3VudCAxCiAgICAgL01lZGlhQm94IFswIDAgMzAwIDE0 -NF0KICA+PgplbmRvYmoKCjMgMCBvYmoKICA8PCAgL1R5cGUgL1BhZ2UKICAgICAgL1BhcmVu -dCAyIDAgUgogICAgICAvUmVzb3VyY2VzCiAgICAgICA8PCAvRm9udAogICAgICAgICAgIDw8 -IC9GMQogICAgICAgICAgICAgICA8PCAvVHlwZSAvRm9udAogICAgICAgICAgICAgICAgICAv -U3VidHlwZSAvVHlwZTEKICAgICAgICAgICAgICAgICAgL0Jhc2VGb250IC9UaW1lcy1Sb21h -bgogICAgICAgICAgICAgICA+PgogICAgICAgICAgID4+CiAgICAgICA+PgogICAgICAvQ29u -dGVudHMgNCAwIFIKICA+PgplbmRvYmoKCjQgMCBvYmoKICA8PCAvTGVuZ3RoIDU1ID4+CnN0 -cmVhbQogIEJUCiAgICAvRjEgMTggVGYKICAgIDAgMCBUZAogICAgKEhlbGxvIFdvcmxkKSBU -agogIEVUCmVuZHN0cmVhbQplbmRvYmoKCnhyZWYKMCA1CjAwMDAwMDAwMDAgNjU1MzUgZiAK -MDAwMDAwMDAxOCAwMDAwMCBuIAowMDAwMDAwMDc3IDAwMDAwIG4gCjAwMDAwMDAxNzggMDAw -MDAgbiAKMDAwMDAwMDQ1NyAwMDAwMCBuIAp0cmFpbGVyCiAgPDwgIC9Sb290IDEgMCBSCiAg -ICAgIC9TaXplIDUKICA+PgpzdGFydHhyZWYKNTY1CiUlRU9GCg== ---------------F97C8ED4878E94675762AE43 -Content-Type: application/pgp-keys; - name="OpenPGP_0x161C0875822359F7.asc" -Content-Transfer-Encoding: quoted-printable -Content-Disposition: attachment; - filename="OpenPGP_0x161C0875822359F7.asc" - ------BEGIN PGP PUBLIC KEY BLOCK----- - -xsBNBFxlUPwBCACx954Ey4SD88f8DSKFw9BaZNXrNwYxNYSgqaqOGHQ0WllF3mstEhTfuxxCZ= -pDh -I5IhWCXUNxanzsFkn88mRDwFRVl2sf2aAG4/P/p1381oh2kd0UElMRQaQGzoCadQMaQOL9WYT= -f4S -PWSCzjrPyKgjq5FbqjbF/ndu376na9L+tnsEXyL6RrI6aZhjWG73xlqxS65dzTIYzsyM/P97x= -Snd -NvlvWtGvLlpFkzxfAEGpVzfOYVYFKoc8rGmUDwrDWYfk5JczRDDogJnY+BNMZf9pjSqk6rTyB= -OfN -H5fpU8r7A5Q7l+HVakvMUQ9DzDWJtg2ru1Y8hexnJOF68avO4+a1ABEBAAHNKEJyaWRnZSBLe= -XUt -RWh5aiA8cG0uYnJpZGdlLnFhQGdtYWlsLmNvbT7CwJQEEwEIAD4CGwMFCwkIBwIGFQoJCAsCB= -BYC -AwECHgECF4AWIQRc5gl5cC8oW/Mo+bEWHAh1giNZ9wUCYC32ygUJB4sMzgAKCRAWHAh1giNZ9= -/K8 -B/4qs84Ii/zKH+q+C8vwO4jUJkOM73qD0pgB7zBs651zWbpgopyol1YUKNpFaHlx/Qch7RDI7= -Vcz -1+60/KZJSJR19/N2EDVbCUdh8ueioUp9X/218YWV2TRJNxTnljd4FAn7smZnXuP1TsLjQ6sKO= -V0U -u6JoiG6LZFXqDgxYpA++58Rkl6xaY6R71VkmVQlbEKtubX9AjHydq97Y+Jvn11XzWZaKhv4L7= -6Pa -4tMKXvvrKh1oywMmh6mZJo+5ZA/ABTkr45cwlTPYqGTS9+uvOHt+PH/oYwwJB4ls2cIAUldSj= -TVQ -IsseYz3LlbcCfKJiiCFxeHOQXA5J6zNLKOT58TsczsBNBFxlUPwBCADh2HsX23yVnJt9fxFz3= -D07 -kCBNvu4HQfps6h1rgNxGhE32VmpESHebvIB5xjL6xKbIqqRa3x/7KDVBNJvca0gUsqEt5kzYF= -88F -yf2NBcejpIbcP7BS/g+C6KOowYj+Et26T6GdwFXExUcl80JvoX8yHQOfvJpdiBRbjyB8UqfCa= -knm -3c7dNuXmhflz/w3aBj32q9ZyGqA1NpHCpLyVAlvSNQ/pat/rGUCPZ9duw4KhUUqEmatQPVFPk= -utT -ouEZQbMK+i+chOH3AsKCuNDfvCDwirnsSqIJmAgl1lC4de+bsWYCMqN9ei99hOCRUyhZ3g3sr= -8RB -owVAdcvjZxeIDKALABEBAAHCwHwEGAEIACYCGwwWIQRc5gl5cC8oW/Mo+bEWHAh1giNZ9wUCY= -C32 -lAUJB4sMmAAKCRAWHAh1giNZ9+Y2B/9rTKZaKviae+ummXNumXcrKvbkAAvfuLpKUn53FlQLm= -L6H -jB++lJnPWvVSzdZxdv8FiPP3d632XHKUrkQRQM/9byRDXDommi7Qttx7YCkhd4JLVYqJqpnAQ= -xI5 -RMkXiZNWyr1lz8JOM1XvDk1M7sJwPMWews8VOIE03E1nt7AsQGnvHtadgEnQaufrYNX3hFA8S= -osO -HSnedcys6yrzCSIGCqCD9VHbnMtS4DOv0XJGh2hwc8omzH0KZA517dyKBorJRwadcVauGXDKx= -Etv -Im4rl94PR/3An1Mj6HeeVVpLqDQ5Jb9J90BahWeQ53FzRa4EQzYCw0nLnxcsT1ZEEP5u -=3Dv/1p ------END PGP PUBLIC KEY BLOCK----- - ---------------F97C8ED4878E94675762AE43-- - ---FBBl2LNv76z8UkvHhSkT9vLwVwxqV8378-- - ---MHEDFShwcX18dyE3X7RXujo5fjpgdjHNM -Content-Type: application/pgp-signature; name="OpenPGP_signature.asc" -Content-Description: OpenPGP digital signature -Content-Disposition: attachment; filename="OpenPGP_signature" - ------BEGIN PGP SIGNATURE----- - -wsB5BAABCAAjFiEEXOYJeXAvKFvzKPmxFhwIdYIjWfcFAmBciUoFAwAAAAAACgkQFhwIdYIjWfez -rgf+NZCibnCUTovpWRVRiiPQtBPGeHUPEwz2xq2zz4AaqrHC2v4mYUIPe6am7INk8fkBLsa8Dj/A -UN/28Qh7tNb7JsXtHDT4PIoXszukQ8VIRbe09mSkkP6jR4WzNR166d6n3rSxzHpviOyQldjjpOMr -Zl7LxmgGr4ojsgCf6pvurWwCCOGJqbSusrD6JVv6DsmPmmQeBmnlTK/0oG9pnlNkugpNB1WS2K5d -RY6+kWkSrxbq95HrgILpHip8Y/+ITWvQocm14PBIAAdW8Hr7iFQLETFJ/KDA+VP19Bt8n4Kitdi8 -DPqMsV0oOhATqBjnD63AePJ0VWg8R1z6GEK5A+WOpg== -=Bc6p ------END PGP SIGNATURE----- - ---MHEDFShwcX18dyE3X7RXujo5fjpgdjHNM-- +Content-Type: multipart/signed; + boundary=e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855; + micalg=SHA-256; protocol="application/pgp-signature" + +--e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 +Content-Type: multipart/mixed; boundary="------------8730PPHC3FpcshavBTup7Fxz"; + protected-headers="v1" +From: "pm.bridge.qa" +To: "InfernalBridgeTester@proton.me" +Message-ID: <5dce90f2-f1e5-eecb-672e-f39def728f44@gmail.com> +Subject: Alternative + +--------------8730PPHC3FpcshavBTup7Fxz +Content-Type: multipart/mixed; boundary="------------CCuN7f3eLVIM0a1fSlNjk0pq" + +--------------CCuN7f3eLVIM0a1fSlNjk0pq +Content-Type: multipart/alternative; + boundary="------------5kz0EAFr3j63ikmxfQPRt0bq" + +--------------5kz0EAFr3j63ikmxfQPRt0bq +Content-Type: text/plain; charset=UTF-8; format=flowed +Content-Transfer-Encoding: base64 + +VGhpcyBSaWNoIGZvcm1hdGVkIHRleHQNCg0KICAqIFdoYXQga2luZCBvZiBzaG9lcyBkbyBu +aW5qYXMgd2Vhcj8gKlNuZWFrZXJzISoNCiAgKiBIb3cgZG9lcyBhIHBlbmd1aW4gYnVpbGQg +aXRzIGhvdXNlPyAqSWdsb29zIGl0IHRvZ2V0aGVyKg0KDQpUaGlzIFJpY2ggZm9ybWF0ZWQg +dGV4dA0KDQogICogL1doYXQga2luZCBvZiBzaG9lcyBkbyBuaW5qYXMgd2Vhcj8gLypTbmVh +a2VycyEqDQogICogL0hvdyBkb2VzIGEgcGVuZ3VpbiBidWlsZCBpdHMgaG91c2U/LyoqXy8q +SWdsb29zIGl0IHRvZ2V0aGVyLiovXw0KDQoNCg0K +--------------5kz0EAFr3j63ikmxfQPRt0bq +Content-Type: text/html; charset=UTF-8 +Content-Transfer-Encoding: quoted-printable + + + + + + + +

This Rich formated text
+

+
    +
  • What kind of shoes do ninjas wear? Sneakers!
  • +
  • How does a penguin build its house? Igloos it together +
+

+

This Rich formated + text

+
    +
  • What kind of shoes do ninjas wear? Sneakers!
  • = + +
  • How does a penguin build its house? Iglo= +os + it together.
  • +
+


+

+


+

+

+ +

+ + + +--------------5kz0EAFr3j63ikmxfQPRt0bq-- +--------------CCuN7f3eLVIM0a1fSlNjk0pq +Content-Type: application/pgp-keys; name="OpenPGP_0x161C0875822359F7.asc" +Content-Disposition: attachment; filename="OpenPGP_0x161C0875822359F7.asc" +Content-Description: OpenPGP public key +Content-Transfer-Encoding: quoted-printable + +-----BEGIN PGP PUBLIC KEY BLOCK----- + +xsBNBFxlUPwBCACx954Ey4SD88f8DSKFw9BaZNXrNwYxNYSgqaqOGHQ0WllF3mst +EhTfuxxCZpDhI5IhWCXUNxanzsFkn88mRDwFRVl2sf2aAG4/P/p1381oh2kd0UEl +MRQaQGzoCadQMaQOL9WYTf4SPWSCzjrPyKgjq5FbqjbF/ndu376na9L+tnsEXyL6 +RrI6aZhjWG73xlqxS65dzTIYzsyM/P97xSndNvlvWtGvLlpFkzxfAEGpVzfOYVYF +Koc8rGmUDwrDWYfk5JczRDDogJnY+BNMZf9pjSqk6rTyBOfNH5fpU8r7A5Q7l+HV +akvMUQ9DzDWJtg2ru1Y8hexnJOF68avO4+a1ABEBAAHNKEJyaWRnZSBLeXUtRWh5 +aiA8cG0uYnJpZGdlLnFhQGdtYWlsLmNvbT7CwI4EEwEIADgCGwMFCwkIBwIGFQoJ +CAsCBBYCAwECHgECF4AWIQRc5gl5cC8oW/Mo+bEWHAh1giNZ9wUCZEfUzQAKCRAW +HAh1giNZ9872B/4mM6cXErSSYK6/apGUVebg9QiP1RhFlLE/kg7BW3FaSP/yTUZN +ZdX7WPnEVyaa5Dk4xRZiB47Yc5myspwc+JEJ3YDAHq+4n/D74TF1kUCzP+QVsWcn +40UqX9gHbO01O/DYtoxMOljEgkfQjEZcRoHuUhCUzldFf8aV+uZKiOXhrPYCwsil +nh0RAmDV7fLoOfKXMLiKXE8wM/5Bax+dk2AmEM4bOTIo58GGDDqseIg03ocrW7vP +egmxiLUwmsHIIDwTq6qZ0CVxbt2uv4cCyNz/0pmRzG7p8192Evdu8JOuLSj3pI1X +00Ub326yay3BBUnsL4PJIGoly8hnLb5N3cyNwsCUBBMBCAA+FiEEXOYJeXAvKFvz +KPmxFhwIdYIjWfcFAlxlUPwCGwMFCQPCZwAFCwkIBwIGFQoJCAsCBBYCAwECHgEC +F4AACgkQFhwIdYIjWfeQzgf+NWseR+UvrJ7I1CFd6M2+RmyIC1QTQ+uyJIhIBQfC +vBhueU9GUPWR6a6GWsb2DGCMkBM2aHoTCcf46fq87VspYb3+b0JsKfRFxBa2cuNH +Ey6PK3xHBDnYFtSZaRB7QMQMfYVin5oyHq8mOd4mImOKfpGhuuhq1hrT8sOhVxRY +Nl/2Hanya7tEJlVyAAEwtN4QVCqiRjjD7kBQ+mgxdDFo62X+sl4Zz2BFlZks+c1+ +LRWwaQZvGgf2tm2NqZhC04CKc2Gg5j7wNJBPVh/FVluxY27D2hV6v9/cTvXDGo8J +pnZ28CnQqiiaKEU83BGwcUlcr4G5YApHyIPujaxffE2R887ATQRcZVD8AQgA4dh7 +F9t8lZybfX8Rc9w9O5AgTb7uB0H6bOoda4DcRoRN9lZqREh3m7yAecYy+sSmyKqk +Wt8f+yg1QTSb3GtIFLKhLeZM2BfPBcn9jQXHo6SG3D+wUv4PguijqMGI/hLduk+h +ncBVxMVHJfNCb6F/Mh0Dn7yaXYgUW48gfFKnwmpJ5t3O3Tbl5oX5c/8N2gY99qvW +chqgNTaRwqS8lQJb0jUP6Wrf6xlAj2fXbsOCoVFKhJmrUD1RT5LrU6LhGUGzCvov +nITh9wLCgrjQ37wg8Iq57EqiCZgIJdZQuHXvm7FmAjKjfXovfYTgkVMoWd4N7K/E +QaMFQHXL42cXiAygCwARAQABwsB2BBgBCAAgAhsMFiEEXOYJeXAvKFvzKPmxFhwI +dYIjWfcFAmRH1LoACgkQFhwIdYIjWfcnHwf/e4jhRXmEhQeQqjsbMqPU4x73tATs +3xsi4et9vrFEBMN6qsFa3gKq41Wv8JyxVuuz23+BgZ+mZ2iDCKuK7+neMJw2eG9f +MkJCExK1r1Pt7YaXmUvzVHlpS2ZVxWrg4QnT6QKuU58O/uZatKXtgRHDQReCEaAU +bO1EFYa/0KTfsWsG50FDNaCDjJY01rkGbT6O+TrJbUJ+ffjk5+2WEA+EN0p9LzwM +xWzwWuH6LLc28fJLUxln4QXLUK6cEtOlaqEqMK/ERWPUvrLIwivh5atrfGQtAgS9 +WlNQAD6nADn68Pa4p9KzdXR9O4Nbg3mfUp8i7nnuUDe691WPG/bYjiVfZsLAfAQY +AQgAJhYhBFzmCXlwLyhb8yj5sRYcCHWCI1n3BQJcZVD8AhsMBQkDwmcAAAoJEBYc +CHWCI1n3rhcH/iCB0ZV861H0RKJ2F7bXEyCLR2ncBFUCnFo3muSrN9NXTojz2vwv +zexRBpZzaRJoksBkvH+ofuZ1iK7ycZO23dnukvPwGQsz3QiITjVeB6ZR0250MG1q +A5yZRlZCsCbGJb4/2e8Ey8BbblHn49Zta4l2Ex5NpNNQ8FYoqXhXu5Bd2F/wX/Bp +5gkZegfE3H9Dw4QjP82Mt0RZSBg9RMGCk6nNfEuze1Up+IOdtqzf3/Z8J5XxLzN2 +s8WPmDwJDwvxJRtto8U+ulv4ElcwlA+wYiKAq7cRCKGM/si5ClkUNgb319grUrBU +6h8SuYtgnD84965xRiVAgtH4wCPN544N8CE=3D +=3DNmqc +-----END PGP PUBLIC KEY BLOCK----- + +--------------CCuN7f3eLVIM0a1fSlNjk0pq-- + +--------------8730PPHC3FpcshavBTup7Fxz-- + +--e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 +Content-Description: OpenPGP digital signature +Content-Disposition: attachment; filename=OpenPGP_signature +Content-Type: application/pgp-signature; name=OpenPGP_signature.asc + +-----BEGIN PGP SIGNATURE----- +Version: GopenPGP 2.7.1 +Comment: https://gopenpgp.org + +wsB5BAABCAAjFiEEXOYJeXAvKFvzKPmxFhwIdYIjWfcFAmRH94EFAwAAAAAACgkQ +FhwIdYIjWfcFfgf/XHYGr9+DcntW0TLe6dO82xhLuO6HFmQnnChnfNHKA5U6pOeU +5wJoEFL2O4WEU1hbuf5K0wpgPi8ZF+r966bCUTt+tYT/p7sKV0OXYJjtPYxiL+ju +RaNZgK3rIDyi2DNjbRXSV1Y7H2S3pMLAwPio7ovNpe3OgfkAgFDdiG+NnXl8CzqN +suhMwqJbLJRWlEaX7UdbcLimpNtPIU7wtr4YV0NIsqt3EV7AeHnVI9cHJMLvF5tB +VrnkxXbdO3xEylUB+MNmX5NDIrCg5Iwwq4NMk6qaMK80J9XSxERln56SJVN/+tIu +TZFgwBWM/n48prGXrEo8TPk5UkrVYhLXl/ndTg== +=FIoh +-----END PGP SIGNATURE----- +--e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855-- diff --git a/pkg/message/testdata/pgp-mime-body-signed-plaintext-with-pubkey.eml b/pkg/message/testdata/pgp-mime-body-signed-plaintext-with-pubkey.eml index 99a7d84e..7218ff61 100644 --- a/pkg/message/testdata/pgp-mime-body-signed-plaintext-with-pubkey.eml +++ b/pkg/message/testdata/pgp-mime-body-signed-plaintext-with-pubkey.eml @@ -1,103 +1,95 @@ -Content-Type: multipart/signed; micalg=pgp-sha256; - protocol="application/pgp-signature"; - boundary="x4FrOFG2PnNJvlbzxe80NPwxzh2yUHABp" - -This is an OpenPGP/MIME signed message (RFC 4880 and 3156) ---x4FrOFG2PnNJvlbzxe80NPwxzh2yUHABp -Content-Type: multipart/mixed; boundary="bBln6dwDJTLkin5LPHkHBQudqRLwIzTUH"; - protected-headers="v1" -Subject: simple plaintext body -From: "pm.bridge.qa" -To: schizofrenic@pm.me -Message-ID: - ---bBln6dwDJTLkin5LPHkHBQudqRLwIzTUH -Content-Type: multipart/mixed; - boundary="------------1B34C666A4C2FB03E0324F1A" -Content-Language: en-US - -This is a multi-part message in MIME format. ---------------1B34C666A4C2FB03E0324F1A -Content-Type: text/plain; charset=utf-8; format=flowed -Content-Transfer-Encoding: quoted-printable - -Why don't crabs give to charity? Because they're shellfish. - - - ---------------1B34C666A4C2FB03E0324F1A -Content-Type: application/pgp-keys; - name="OpenPGP_0x161C0875822359F7.asc" -Content-Transfer-Encoding: quoted-printable -Content-Disposition: attachment; - filename="OpenPGP_0x161C0875822359F7.asc" - ------BEGIN PGP PUBLIC KEY BLOCK----- - -xsBNBFxlUPwBCACx954Ey4SD88f8DSKFw9BaZNXrNwYxNYSgqaqOGHQ0WllF3mstEhTfuxxCZ= -pDh -I5IhWCXUNxanzsFkn88mRDwFRVl2sf2aAG4/P/p1381oh2kd0UElMRQaQGzoCadQMaQOL9WYT= -f4S -PWSCzjrPyKgjq5FbqjbF/ndu376na9L+tnsEXyL6RrI6aZhjWG73xlqxS65dzTIYzsyM/P97x= -Snd -NvlvWtGvLlpFkzxfAEGpVzfOYVYFKoc8rGmUDwrDWYfk5JczRDDogJnY+BNMZf9pjSqk6rTyB= -OfN -H5fpU8r7A5Q7l+HVakvMUQ9DzDWJtg2ru1Y8hexnJOF68avO4+a1ABEBAAHNKEJyaWRnZSBLe= -XUt -RWh5aiA8cG0uYnJpZGdlLnFhQGdtYWlsLmNvbT7CwJQEEwEIAD4CGwMFCwkIBwIGFQoJCAsCB= -BYC -AwECHgECF4AWIQRc5gl5cC8oW/Mo+bEWHAh1giNZ9wUCYC32ygUJB4sMzgAKCRAWHAh1giNZ9= -/K8 -B/4qs84Ii/zKH+q+C8vwO4jUJkOM73qD0pgB7zBs651zWbpgopyol1YUKNpFaHlx/Qch7RDI7= -Vcz -1+60/KZJSJR19/N2EDVbCUdh8ueioUp9X/218YWV2TRJNxTnljd4FAn7smZnXuP1TsLjQ6sKO= -V0U -u6JoiG6LZFXqDgxYpA++58Rkl6xaY6R71VkmVQlbEKtubX9AjHydq97Y+Jvn11XzWZaKhv4L7= -6Pa -4tMKXvvrKh1oywMmh6mZJo+5ZA/ABTkr45cwlTPYqGTS9+uvOHt+PH/oYwwJB4ls2cIAUldSj= -TVQ -IsseYz3LlbcCfKJiiCFxeHOQXA5J6zNLKOT58TsczsBNBFxlUPwBCADh2HsX23yVnJt9fxFz3= -D07 -kCBNvu4HQfps6h1rgNxGhE32VmpESHebvIB5xjL6xKbIqqRa3x/7KDVBNJvca0gUsqEt5kzYF= -88F -yf2NBcejpIbcP7BS/g+C6KOowYj+Et26T6GdwFXExUcl80JvoX8yHQOfvJpdiBRbjyB8UqfCa= -knm -3c7dNuXmhflz/w3aBj32q9ZyGqA1NpHCpLyVAlvSNQ/pat/rGUCPZ9duw4KhUUqEmatQPVFPk= -utT -ouEZQbMK+i+chOH3AsKCuNDfvCDwirnsSqIJmAgl1lC4de+bsWYCMqN9ei99hOCRUyhZ3g3sr= -8RB -owVAdcvjZxeIDKALABEBAAHCwHwEGAEIACYCGwwWIQRc5gl5cC8oW/Mo+bEWHAh1giNZ9wUCY= -C32 -lAUJB4sMmAAKCRAWHAh1giNZ9+Y2B/9rTKZaKviae+ummXNumXcrKvbkAAvfuLpKUn53FlQLm= -L6H -jB++lJnPWvVSzdZxdv8FiPP3d632XHKUrkQRQM/9byRDXDommi7Qttx7YCkhd4JLVYqJqpnAQ= -xI5 -RMkXiZNWyr1lz8JOM1XvDk1M7sJwPMWews8VOIE03E1nt7AsQGnvHtadgEnQaufrYNX3hFA8S= -osO -HSnedcys6yrzCSIGCqCD9VHbnMtS4DOv0XJGh2hwc8omzH0KZA517dyKBorJRwadcVauGXDKx= -Etv -Im4rl94PR/3An1Mj6HeeVVpLqDQ5Jb9J90BahWeQ53FzRa4EQzYCw0nLnxcsT1ZEEP5u -=3Dv/1p ------END PGP PUBLIC KEY BLOCK----- - ---------------1B34C666A4C2FB03E0324F1A-- - ---bBln6dwDJTLkin5LPHkHBQudqRLwIzTUH-- - ---x4FrOFG2PnNJvlbzxe80NPwxzh2yUHABp -Content-Type: application/pgp-signature; name="OpenPGP_signature.asc" -Content-Description: OpenPGP digital signature -Content-Disposition: attachment; filename="OpenPGP_signature" - ------BEGIN PGP SIGNATURE----- - -wsB5BAABCAAjFiEEXOYJeXAvKFvzKPmxFhwIdYIjWfcFAmBa9YIFAwAAAAAACgkQFhwIdYIjWfem -vQgAjUMAaxL7D6fRtFBqLjdQGr7PkDBigeQD9ax17CJFld7Zfo2dAYUzYJRi0HP0Kn1YCSBppF0w -5/P8458H2sqfPC32ptbDCZ/seL0Rpt/gRx6yufbz7wQC0iUZxqxBq2Ox9PGZYSCrTO837lAVYxUo -aMnDL/K9ohAGIyTZVv31z+r3LLWQsFpfpB5hJFqsjQXA9IGKSQIkWbaeE+0wveJSwqxdTwYvsHs2 -xjBw+s8tRHO/whP4pvzL185fGsHAb8x9a9oyoDVcszhw5xBpiWW37mI58qkQ6g+4wTarreuXGTp3 -RKgPupoYOMJja90yh3TWovcmuZz6QOgne5Rbn3s+Vg== -=hUb8 ------END PGP SIGNATURE----- - ---x4FrOFG2PnNJvlbzxe80NPwxzh2yUHABp-- +Content-Type: multipart/signed; + boundary=e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855; + micalg=SHA-256; protocol="application/pgp-signature" + +--e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 +Content-Type: multipart/mixed; boundary="------------bhHlRtbq4tEzp2NgVmAJ4AbV"; + protected-headers="v1" +From: "pm.bridge.qa" +To: "InfernalBridgeTester@proton.me" +Message-ID: <9bb09a2a-1442-9439-f53f-490df7e46331@gmail.com> +Subject: simple plaintext body + +--------------bhHlRtbq4tEzp2NgVmAJ4AbV +Content-Type: multipart/mixed; boundary="------------FHzf8jBNv06d9SowGc7KOjXr" + +--------------FHzf8jBNv06d9SowGc7KOjXr +Content-Type: text/plain; charset=UTF-8; format=flowed +Content-Transfer-Encoding: base64 + +V2h5IGRvbid0IGNyYWJzIGdpdmUgdG8gY2hhcml0eT8gQmVjYXVzZSB0aGV5J3JlIHNoZWxs +ZmlzaC4NCg0K +--------------FHzf8jBNv06d9SowGc7KOjXr +Content-Type: application/pgp-keys; name="OpenPGP_0x161C0875822359F7.asc" +Content-Disposition: attachment; filename="OpenPGP_0x161C0875822359F7.asc" +Content-Description: OpenPGP public key +Content-Transfer-Encoding: quoted-printable + +-----BEGIN PGP PUBLIC KEY BLOCK----- + +xsBNBFxlUPwBCACx954Ey4SD88f8DSKFw9BaZNXrNwYxNYSgqaqOGHQ0WllF3mst +EhTfuxxCZpDhI5IhWCXUNxanzsFkn88mRDwFRVl2sf2aAG4/P/p1381oh2kd0UEl +MRQaQGzoCadQMaQOL9WYTf4SPWSCzjrPyKgjq5FbqjbF/ndu376na9L+tnsEXyL6 +RrI6aZhjWG73xlqxS65dzTIYzsyM/P97xSndNvlvWtGvLlpFkzxfAEGpVzfOYVYF +Koc8rGmUDwrDWYfk5JczRDDogJnY+BNMZf9pjSqk6rTyBOfNH5fpU8r7A5Q7l+HV +akvMUQ9DzDWJtg2ru1Y8hexnJOF68avO4+a1ABEBAAHNKEJyaWRnZSBLeXUtRWh5 +aiA8cG0uYnJpZGdlLnFhQGdtYWlsLmNvbT7CwI4EEwEIADgCGwMFCwkIBwIGFQoJ +CAsCBBYCAwECHgECF4AWIQRc5gl5cC8oW/Mo+bEWHAh1giNZ9wUCZEfUzQAKCRAW +HAh1giNZ9872B/4mM6cXErSSYK6/apGUVebg9QiP1RhFlLE/kg7BW3FaSP/yTUZN +ZdX7WPnEVyaa5Dk4xRZiB47Yc5myspwc+JEJ3YDAHq+4n/D74TF1kUCzP+QVsWcn +40UqX9gHbO01O/DYtoxMOljEgkfQjEZcRoHuUhCUzldFf8aV+uZKiOXhrPYCwsil +nh0RAmDV7fLoOfKXMLiKXE8wM/5Bax+dk2AmEM4bOTIo58GGDDqseIg03ocrW7vP +egmxiLUwmsHIIDwTq6qZ0CVxbt2uv4cCyNz/0pmRzG7p8192Evdu8JOuLSj3pI1X +00Ub326yay3BBUnsL4PJIGoly8hnLb5N3cyNwsCUBBMBCAA+FiEEXOYJeXAvKFvz +KPmxFhwIdYIjWfcFAlxlUPwCGwMFCQPCZwAFCwkIBwIGFQoJCAsCBBYCAwECHgEC +F4AACgkQFhwIdYIjWfeQzgf+NWseR+UvrJ7I1CFd6M2+RmyIC1QTQ+uyJIhIBQfC +vBhueU9GUPWR6a6GWsb2DGCMkBM2aHoTCcf46fq87VspYb3+b0JsKfRFxBa2cuNH +Ey6PK3xHBDnYFtSZaRB7QMQMfYVin5oyHq8mOd4mImOKfpGhuuhq1hrT8sOhVxRY +Nl/2Hanya7tEJlVyAAEwtN4QVCqiRjjD7kBQ+mgxdDFo62X+sl4Zz2BFlZks+c1+ +LRWwaQZvGgf2tm2NqZhC04CKc2Gg5j7wNJBPVh/FVluxY27D2hV6v9/cTvXDGo8J +pnZ28CnQqiiaKEU83BGwcUlcr4G5YApHyIPujaxffE2R887ATQRcZVD8AQgA4dh7 +F9t8lZybfX8Rc9w9O5AgTb7uB0H6bOoda4DcRoRN9lZqREh3m7yAecYy+sSmyKqk +Wt8f+yg1QTSb3GtIFLKhLeZM2BfPBcn9jQXHo6SG3D+wUv4PguijqMGI/hLduk+h +ncBVxMVHJfNCb6F/Mh0Dn7yaXYgUW48gfFKnwmpJ5t3O3Tbl5oX5c/8N2gY99qvW +chqgNTaRwqS8lQJb0jUP6Wrf6xlAj2fXbsOCoVFKhJmrUD1RT5LrU6LhGUGzCvov +nITh9wLCgrjQ37wg8Iq57EqiCZgIJdZQuHXvm7FmAjKjfXovfYTgkVMoWd4N7K/E +QaMFQHXL42cXiAygCwARAQABwsB2BBgBCAAgAhsMFiEEXOYJeXAvKFvzKPmxFhwI +dYIjWfcFAmRH1LoACgkQFhwIdYIjWfcnHwf/e4jhRXmEhQeQqjsbMqPU4x73tATs +3xsi4et9vrFEBMN6qsFa3gKq41Wv8JyxVuuz23+BgZ+mZ2iDCKuK7+neMJw2eG9f +MkJCExK1r1Pt7YaXmUvzVHlpS2ZVxWrg4QnT6QKuU58O/uZatKXtgRHDQReCEaAU +bO1EFYa/0KTfsWsG50FDNaCDjJY01rkGbT6O+TrJbUJ+ffjk5+2WEA+EN0p9LzwM +xWzwWuH6LLc28fJLUxln4QXLUK6cEtOlaqEqMK/ERWPUvrLIwivh5atrfGQtAgS9 +WlNQAD6nADn68Pa4p9KzdXR9O4Nbg3mfUp8i7nnuUDe691WPG/bYjiVfZsLAfAQY +AQgAJhYhBFzmCXlwLyhb8yj5sRYcCHWCI1n3BQJcZVD8AhsMBQkDwmcAAAoJEBYc +CHWCI1n3rhcH/iCB0ZV861H0RKJ2F7bXEyCLR2ncBFUCnFo3muSrN9NXTojz2vwv +zexRBpZzaRJoksBkvH+ofuZ1iK7ycZO23dnukvPwGQsz3QiITjVeB6ZR0250MG1q +A5yZRlZCsCbGJb4/2e8Ey8BbblHn49Zta4l2Ex5NpNNQ8FYoqXhXu5Bd2F/wX/Bp +5gkZegfE3H9Dw4QjP82Mt0RZSBg9RMGCk6nNfEuze1Up+IOdtqzf3/Z8J5XxLzN2 +s8WPmDwJDwvxJRtto8U+ulv4ElcwlA+wYiKAq7cRCKGM/si5ClkUNgb319grUrBU +6h8SuYtgnD84965xRiVAgtH4wCPN544N8CE=3D +=3DNmqc +-----END PGP PUBLIC KEY BLOCK----- + +--------------FHzf8jBNv06d9SowGc7KOjXr-- + +--------------bhHlRtbq4tEzp2NgVmAJ4AbV-- + +--e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 +Content-Description: OpenPGP digital signature +Content-Disposition: attachment; filename=OpenPGP_signature +Content-Type: application/pgp-signature; name=OpenPGP_signature.asc + +-----BEGIN PGP SIGNATURE----- +Comment: https://gopenpgp.org +Version: GopenPGP 2.7.1 + +wsB5BAABCAAjFiEEXOYJeXAvKFvzKPmxFhwIdYIjWfcFAmRH6MwFAwAAAAAACgkQ +FhwIdYIjWfdX5Qf/W2hFY5PiCrRTvcXGASc2RBLXmCh/mn0tTNUsGtyq/MhcNKfR +9bSFCb3xz9q26MAJDHtO/Vm0lUjre42rLMkEIDIdJT960HIClELzmgglwFbVgdqy +T0Psma8ySQpZ2LxZ1oleCXeXaxm4DOwQP+COfb5+FmLTA2z1djLA3HjFPNKglcUr +atzCTvlt2yqwrx6aeqTxcFezPkl1o+kdqjMCMP0LFFuImuor0vaCFUz76hgNC3kk +CflcYGPJIVH7D06UXkLKC5vnJZ+Pidn4K5sMkF3nXBlourmSU2cZFTNUUdHNAxi8 +s9XTavfQxm4fyLPyGcgNpdM6PhZW9r+lZkr66w== +=se49 +-----END PGP SIGNATURE----- +--e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855-- diff --git a/pkg/ports/ports.go b/pkg/ports/ports.go index d5cfbaff..212a3d42 100644 --- a/pkg/ports/ports.go +++ b/pkg/ports/ports.go @@ -22,6 +22,7 @@ import ( "net" "github.com/ProtonMail/proton-bridge/v3/internal/constants" + "golang.org/x/exp/slices" ) const ( @@ -43,19 +44,19 @@ func IsPortFree(port int) bool { func isOccupied(port string) bool { // Try to create server at port. - dummyserver, err := net.Listen("tcp", port) + dummyServer, err := net.Listen("tcp", port) if err != nil { return true } - _ = dummyserver.Close() + _ = dummyServer.Close() return false } -// FindFreePortFrom finds first empty port, starting with `startPort`. -func FindFreePortFrom(startPort int) int { +// FindFreePortFrom finds first empty port, starting with `startPort`, and excluding ports listed in exclude. +func FindFreePortFrom(startPort int, exclude ...int) int { loopedOnce := false freePort := startPort - for !IsPortFree(freePort) { + for slices.Contains(exclude, freePort) || !IsPortFree(freePort) { freePort++ if freePort >= maxPortNumber { freePort = 1 diff --git a/pkg/ports/ports_test.go b/pkg/ports/ports_test.go index a88bbce2..53276be7 100644 --- a/pkg/ports/ports_test.go +++ b/pkg/ports/ports_test.go @@ -32,12 +32,12 @@ func TestFreePort(t *testing.T) { } func TestOccupiedPort(t *testing.T) { - dummyserver, err := net.Listen("tcp", ":"+strconv.Itoa(testPort)) + dummyServer, err := net.Listen("tcp", ":"+strconv.Itoa(testPort)) require.NoError(t, err) require.True(t, !IsPortFree(testPort), "port should be occupied") - _ = dummyserver.Close() + _ = dummyServer.Close() } func TestFindFreePortFromDirectly(t *testing.T) { @@ -46,11 +46,21 @@ func TestFindFreePortFromDirectly(t *testing.T) { } func TestFindFreePortFromNextOne(t *testing.T) { - dummyserver, err := net.Listen("tcp", ":"+strconv.Itoa(testPort)) + dummyServer, err := net.Listen("tcp", ":"+strconv.Itoa(testPort)) require.NoError(t, err) foundPort := FindFreePortFrom(testPort) require.Equal(t, testPort+1, foundPort) - _ = dummyserver.Close() + _ = dummyServer.Close() +} + +func TestFindFreePortExcluding(t *testing.T) { + dummyServer, err := net.Listen("tcp", ":"+strconv.Itoa(testPort)) + require.NoError(t, err) + + foundPort := FindFreePortFrom(testPort, testPort+1, testPort+2) + require.Equal(t, testPort+3, foundPort) + + _ = dummyServer.Close() } diff --git a/tests/bdd_test.go b/tests/bdd_test.go index f67caa70..92a73bed 100644 --- a/tests/bdd_test.go +++ b/tests/bdd_test.go @@ -107,7 +107,10 @@ func TestFeatures(testingT *testing.T) { ctx.Step(`^the header in the "([^"]*)" request to "([^"]*)" has "([^"]*)" set to "([^"]*)"$`, s.theHeaderInTheRequestToHasSetTo) ctx.Step(`^the body in the "([^"]*)" request to "([^"]*)" is:$`, s.theBodyInTheRequestToIs) ctx.Step(`^the API requires bridge version at least "([^"]*)"$`, s.theAPIRequiresBridgeVersion) - + ctx.Step(`^the network port (\d+) is busy$`, s.networkPortIsBusy) + ctx.Step(`^the network port range (\d+)-(\d+) is busy$`, s.networkPortRangeIsBusy) + ctx.Step(`^bridge IMAP port is (\d+)`, s.bridgeIMAPPortIs) + ctx.Step(`^bridge SMTP port is (\d+)`, s.bridgeSMTPPortIs) // ==== SETUP ==== ctx.Step(`^there exists an account with username "([^"]*)" and password "([^"]*)"$`, s.thereExistsAnAccountWithUsernameAndPassword) ctx.Step(`^there exists a disabled account with username "([^"]*)" and password "([^"]*)"$`, s.thereExistsAnAccountWithUsernameAndPasswordWithDisablePrimary) @@ -121,7 +124,7 @@ func TestFeatures(testingT *testing.T) { ctx.Step(`^the address "([^"]*)" of account "([^"]*)" has the following messages in "([^"]*)":$`, s.theAddressOfAccountHasTheFollowingMessagesInMailbox) ctx.Step(`^the address "([^"]*)" of account "([^"]*)" has (\d+) messages in "([^"]*)"$`, s.theAddressOfAccountHasMessagesInMailbox) ctx.Step(`^the following fields were changed in draft (\d+) for address "([^"]*)" of account "([^"]*)":$`, s.theFollowingFieldsWereChangedInDraftForAddressOfAccount) - ctx.Step(`^draft (\d+) for address "([^"]*)" of account "([^"]*) was moved to trash$`, s.drafAtIndexWasMovedToTrashForAddressOfAccount) + ctx.Step(`^draft (\d+) for address "([^"]*)" of account "([^"]*)" was moved to trash$`, s.drafAtIndexWasMovedToTrashForAddressOfAccount) // === REPORTER === ctx.Step(`^test skips reporter checks$`, s.skipReporterChecks) @@ -132,15 +135,22 @@ func TestFeatures(testingT *testing.T) { ctx.Step(`^bridge stops$`, s.bridgeStops) ctx.Step(`^bridge is version "([^"]*)" and the latest available version is "([^"]*)" reachable from "([^"]*)"$`, s.bridgeVersionIsAndTheLatestAvailableVersionIsReachableFrom) ctx.Step(`^the user has disabled automatic updates$`, s.theUserHasDisabledAutomaticUpdates) + ctx.Step(`^the user has disabled automatic start`, s.theUserHasDisabledAutomaticStart) + ctx.Step(`^the user has enabled alternative routing`, s.theUserHasEnabledAlternativeRouting) + ctx.Step(`^the user set IMAP mode to SSL`, s.theUserSetIMAPModeToSSL) + ctx.Step(`^the user set SMTP mode to SSL`, s.theUserSetSMTPModeToSSL) ctx.Step(`^the user changes the IMAP port to (\d+)$`, s.theUserChangesTheIMAPPortTo) ctx.Step(`^the user changes the SMTP port to (\d+)$`, s.theUserChangesTheSMTPPortTo) ctx.Step(`^the user sets the address mode of user "([^"]*)" to "([^"]*)"$`, s.theUserSetsTheAddressModeOfUserTo) + ctx.Step(`^the user changes the default keychain application`, s.theUserChangesTheDefaultKeychainApplication) ctx.Step(`^the user changes the gluon path$`, s.theUserChangesTheGluonPath) ctx.Step(`^the user deletes the gluon files$`, s.theUserDeletesTheGluonFiles) ctx.Step(`^the user deletes the gluon cache$`, s.theUserDeletesTheGluonCache) ctx.Step(`^the user reports a bug$`, s.theUserReportsABug) ctx.Step(`^the user hides All Mail$`, s.theUserHidesAllMail) ctx.Step(`^the user shows All Mail$`, s.theUserShowsAllMail) + ctx.Step(`^the user disables telemetry in bridge settings$`, s.theUserDisablesTelemetryInBridgeSettings) + ctx.Step(`^the user enables telemetry in bridge settings$`, s.theUserEnablesTelemetryInBridgeSettings) ctx.Step(`^bridge sends a connection up event$`, s.bridgeSendsAConnectionUpEvent) ctx.Step(`^bridge sends a connection down event$`, s.bridgeSendsAConnectionDownEvent) ctx.Step(`^bridge sends a deauth event for user "([^"]*)"$`, s.bridgeSendsADeauthEventForUser) @@ -153,6 +163,8 @@ func TestFeatures(testingT *testing.T) { ctx.Step(`^bridge sends an update not available event$`, s.bridgeSendsAnUpdateNotAvailableEvent) ctx.Step(`^bridge sends a forced update event$`, s.bridgeSendsAForcedUpdateEvent) ctx.Step(`^bridge reports a message with "([^"]*)"$`, s.bridgeReportsMessage) + ctx.Step(`^bridge telemetry feature is enabled$`, s.bridgeTelemetryFeatureEnabled) + ctx.Step(`^bridge telemetry feature is disabled$`, s.bridgeTelemetryFeatureDisabled) // ==== FRONTEND ==== ctx.Step(`^frontend sees that bridge is version "([^"]*)"$`, s.frontendSeesThatBridgeIsVersion) @@ -166,6 +178,7 @@ func TestFeatures(testingT *testing.T) { ctx.Step(`^user "([^"]*)" is listed but not connected$`, s.userIsListedButNotConnected) ctx.Step(`^user "([^"]*)" is not listed$`, s.userIsNotListed) ctx.Step(`^user "([^"]*)" finishes syncing$`, s.userFinishesSyncing) + ctx.Step(`^user "([^"]*)" has telemetry set to (\d+)$`, s.userHasTelemetrySetTo) // ==== IMAP ==== ctx.Step(`^user "([^"]*)" connects IMAP client "([^"]*)"$`, s.userConnectsIMAPClient) @@ -206,6 +219,7 @@ func TestFeatures(testingT *testing.T) { ctx.Step(`^IMAP client "([^"]*)" appends "([^"]*)" to "([^"]*)"$`, s.imapClientAppendsToMailbox) ctx.Step(`^IMAP clients "([^"]*)" and "([^"]*)" move message with subject "([^"]*)" of "([^"]*)" to "([^"]*)" by ([^"]*) ([^"]*) ([^"]*)`, s.imapClientsMoveMessageWithSubjectUserFromToByOrderedOperations) ctx.Step(`^IMAP client "([^"]*)" sees header "([^"]*)" in message with subject "([^"]*)" in "([^"]*)"$`, s.imapClientSeesHeaderInMessageWithSubject) + ctx.Step(`^IMAP client "([^"]*)" does not see header "([^"]*)" in message with subject "([^"]*)" in "([^"]*)"$`, s.imapClientDoesNotSeeHeaderInMessageWithSubject) // ==== SMTP ==== ctx.Step(`^user "([^"]*)" connects SMTP client "([^"]*)"$`, s.userConnectsSMTPClient) @@ -222,6 +236,12 @@ func TestFeatures(testingT *testing.T) { ctx.Step(`^SMTP client "([^"]*)" sends RSET$`, s.smtpClientSendsReset) ctx.Step(`^SMTP client "([^"]*)" sends the following message from "([^"]*)" to "([^"]*)":$`, s.smtpClientSendsTheFollowingMessageFromTo) ctx.Step(`^SMTP client "([^"]*)" logs out$`, s.smtpClientLogsOut) + + // ==== TELEMETRY ==== + ctx.Step(`^bridge eventually sends the following heartbeat:$`, s.bridgeEventuallySendsTheFollowingHeartbeat) + ctx.Step(`^bridge needs to send heartbeat`, s.bridgeNeedsToSendHeartbeat) + ctx.Step(`^bridge do not need to send heartbeat`, s.bridgeDoNotNeedToSendHeartbeat) + ctx.Step(`^heartbeat is not whitelisted`, s.heartbeatIsNotwhitelisted) }, Options: &godog.Options{ Format: "pretty", diff --git a/tests/bridge_test.go b/tests/bridge_test.go index 45f6e67a..7d3edd14 100644 --- a/tests/bridge_test.go +++ b/tests/bridge_test.go @@ -21,7 +21,9 @@ import ( "context" "errors" "fmt" + "net" "os" + "strconv" "time" "github.com/Masterminds/semver/v3" @@ -78,6 +80,10 @@ func (s *scenario) theUserSetsTheAddressModeOfUserTo(user, mode string) error { } } +func (s *scenario) theUserChangesTheDefaultKeychainApplication() error { + return s.t.bridge.SetKeychainApp("CustomKeychainApp") +} + func (s *scenario) theUserChangesTheGluonPath() error { gluonDir, err := os.MkdirTemp(s.t.dir, "gluon") if err != nil { @@ -116,7 +122,6 @@ func (s *scenario) theUserHasDisabledAutomaticUpdates() error { started = true } - if err := s.t.bridge.SetAutoUpdate(false); err != nil { return err } @@ -126,10 +131,26 @@ func (s *scenario) theUserHasDisabledAutomaticUpdates() error { return err } } - return nil } +func (s *scenario) theUserHasDisabledAutomaticStart() error { + return s.t.bridge.SetAutostart(false) +} + +func (s *scenario) theUserHasEnabledAlternativeRouting() error { + s.t.expectProxyCtlAllowProxy() + return s.t.bridge.SetProxyAllowed(true) +} + +func (s *scenario) theUserSetIMAPModeToSSL() error { + return s.t.bridge.SetIMAPSSL(true) +} + +func (s *scenario) theUserSetSMTPModeToSSL() error { + return s.t.bridge.SetSMTPSSL(true) +} + func (s *scenario) theUserReportsABug() error { return s.t.bridge.ReportBug(context.Background(), "osType", "osVersion", "description", "username", "email", "client", false) } @@ -284,6 +305,22 @@ func (s *scenario) bridgeReportsMessage(message string) error { return nil } +func (s *scenario) bridgeTelemetryFeatureEnabled() error { + return s.checkTelemetry(true) +} + +func (s *scenario) bridgeTelemetryFeatureDisabled() error { + return s.checkTelemetry(false) +} + +func (s *scenario) checkTelemetry(expect bool) error { + res := s.t.bridge.IsTelemetryAvailable() + if res != expect { + return fmt.Errorf("expected telemetry feature %v but got %v ", expect, res) + } + return nil +} + func (s *scenario) theUserHidesAllMail() error { return s.t.bridge.SetShowAllMail(false) } @@ -291,3 +328,45 @@ func (s *scenario) theUserHidesAllMail() error { func (s *scenario) theUserShowsAllMail() error { return s.t.bridge.SetShowAllMail(true) } + +func (s *scenario) theUserDisablesTelemetryInBridgeSettings() error { + return s.t.bridge.SetTelemetryDisabled(true) +} + +func (s *scenario) theUserEnablesTelemetryInBridgeSettings() error { + return s.t.bridge.SetTelemetryDisabled(false) +} + +func (s *scenario) networkPortIsBusy(port int) { + if listener, err := net.Listen("tcp", "127.0.0.1:"+strconv.Itoa(port)); err == nil { // we ignore errors. Most likely port is already busy. + s.t.dummyListeners = append(s.t.dummyListeners, listener) + } +} + +func (s *scenario) networkPortRangeIsBusy(startPort, endPort int) { + if startPort > endPort { + startPort, endPort = endPort, startPort + } + + for port := startPort; port <= endPort; port++ { + s.networkPortIsBusy(port) + } +} + +func (s *scenario) bridgeIMAPPortIs(expectedPort int) error { + actualPort := s.t.bridge.GetIMAPPort() + if actualPort != expectedPort { + return fmt.Errorf("expected IMAP port to be %v but got %v", expectedPort, actualPort) + } + + return nil +} + +func (s *scenario) bridgeSMTPPortIs(expectedPort int) error { + actualPort := s.t.bridge.GetSMTPPort() + if actualPort != expectedPort { + return fmt.Errorf("expected SMTP port to be %v but got %v", expectedPort, actualPort) + } + + return nil +} diff --git a/tests/ctx_bridge_test.go b/tests/ctx_bridge_test.go index 92cdf0e1..0afe93d7 100644 --- a/tests/ctx_bridge_test.go +++ b/tests/ctx_bridge_test.go @@ -174,6 +174,9 @@ func (t *testCtx) initBridge() (<-chan events.Event, error) { } t.bridge = bridge + t.heartbeat.setBridge(bridge) + + bridge.StartHeartbeat(t.heartbeat) return t.events.collectFrom(eventCh), nil } @@ -342,6 +345,9 @@ func (t *testCtx) closeFrontendClient() error { return nil } +func (t *testCtx) expectProxyCtlAllowProxy() { + t.mocks.ProxyCtl.EXPECT().AllowProxy() +} type mockRestarter struct{} diff --git a/tests/ctx_heartbeat_test.go b/tests/ctx_heartbeat_test.go new file mode 100644 index 00000000..babf4f9e --- /dev/null +++ b/tests/ctx_heartbeat_test.go @@ -0,0 +1,89 @@ +// Copyright (c) 2023 Proton AG +// +// This file is part of Proton Mail Bridge. +// +// Proton Mail Bridge is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Proton Mail Bridge is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Proton Mail Bridge. If not, see . + +package tests + +import ( + "errors" + "testing" + "time" + + "github.com/ProtonMail/proton-bridge/v3/internal/bridge" + "github.com/ProtonMail/proton-bridge/v3/internal/telemetry" + "github.com/stretchr/testify/assert" +) + +type heartbeatRecorder struct { + heartbeat telemetry.HeartbeatData + bridge *bridge.Bridge + reject bool + assert *assert.Assertions +} + +func newHeartbeatRecorder(tb testing.TB) *heartbeatRecorder { + return &heartbeatRecorder{ + heartbeat: telemetry.HeartbeatData{}, + bridge: nil, + reject: false, + assert: assert.New(tb), + } +} + +func (hb *heartbeatRecorder) setBridge(bridge *bridge.Bridge) { + hb.bridge = bridge +} + +func (hb *heartbeatRecorder) GetLastHeartbeatSent() time.Time { + if hb.bridge == nil { + return time.Now() + } + return hb.bridge.GetLastHeartbeatSent() +} + +func (hb *heartbeatRecorder) IsTelemetryAvailable() bool { + if hb.bridge == nil { + return false + } + return hb.bridge.IsTelemetryAvailable() +} + +func (hb *heartbeatRecorder) SendHeartbeat(metrics *telemetry.HeartbeatData) bool { + if hb.bridge == nil { + return false + } + + if len(hb.bridge.GetUserIDs()) == 0 { + return false + } + + if hb.reject { + return false + } + hb.heartbeat = *metrics + return true +} + +func (hb *heartbeatRecorder) SetLastHeartbeatSent(timestamp time.Time) error { + if hb.bridge == nil { + return errors.New("no bridge initialized") + } + return hb.bridge.SetLastHeartbeatSent(timestamp) +} + +func (hb *heartbeatRecorder) rejectSend() { + hb.reject = true +} diff --git a/tests/ctx_test.go b/tests/ctx_test.go index 13bff820..369e865f 100644 --- a/tests/ctx_test.go +++ b/tests/ctx_test.go @@ -20,6 +20,7 @@ package tests import ( "context" "fmt" + "net" "net/smtp" "net/url" "regexp" @@ -121,15 +122,16 @@ func newTestAddr(addrID, email string) *testAddr { type testCtx struct { // These are the objects supporting the test. - dir string - api API - netCtl *proton.NetCtl - locator *locations.Locations - storeKey []byte - version *semver.Version - mocks *bridge.Mocks - events *eventCollector - reporter *reportRecorder + dir string + api API + netCtl *proton.NetCtl + locator *locations.Locations + storeKey []byte + version *semver.Version + mocks *bridge.Mocks + events *eventCollector + reporter *reportRecorder + heartbeat *heartbeatRecorder // bridge holds the bridge app under test. bridge *bridge.Bridge @@ -160,6 +162,9 @@ type testCtx struct { // errors holds test-related errors encountered while running test steps. errors [][]error errorsLock sync.RWMutex + + // This slice contains the dummy listeners that are intended to block network ports. + dummyListeners []net.Listener } type imapClient struct { @@ -176,15 +181,16 @@ func newTestCtx(tb testing.TB) *testCtx { dir := tb.TempDir() t := &testCtx{ - dir: dir, - api: newTestAPI(), - netCtl: proton.NewNetCtl(), - locator: locations.New(bridge.NewTestLocationsProvider(dir), "config-name"), - storeKey: []byte("super-secret-store-key"), - version: defaultVersion, - mocks: bridge.NewMocks(tb, defaultVersion, defaultVersion), - events: newEventCollector(), - reporter: newReportRecorder(tb), + dir: dir, + api: newTestAPI(), + netCtl: proton.NewNetCtl(), + locator: locations.New(bridge.NewTestLocationsProvider(dir), "config-name"), + storeKey: []byte("super-secret-store-key"), + version: defaultVersion, + mocks: bridge.NewMocks(tb, defaultVersion, defaultVersion), + events: newEventCollector(), + reporter: newReportRecorder(tb), + heartbeat: newHeartbeatRecorder(tb), userByID: make(map[string]*testUser), userUUIDByName: make(map[string]string), @@ -437,6 +443,12 @@ func (t *testCtx) close(ctx context.Context) { } } + for _, listener := range t.dummyListeners { + if err := listener.Close(); err != nil { + logrus.WithError(err).Errorf("Failed to close dummy listener %v", listener.Addr()) + } + } + t.api.Close() t.events.close() t.reporter.close() diff --git a/tests/features/bridge/default_ports.feature b/tests/features/bridge/default_ports.feature new file mode 100644 index 00000000..4c7f3703 --- /dev/null +++ b/tests/features/bridge/default_ports.feature @@ -0,0 +1,24 @@ +Feature: Bridge picks default ports wisely + + Scenario: bridge picks ports for IMAP and SMTP using default values. + When bridge starts + Then bridge IMAP port is 1143 + Then bridge SMTP port is 1025 + + Scenario: bridge picks ports for IMAP wisely when default port is busy. + When the network port 1143 is busy + And bridge starts + Then bridge IMAP port is 1144 + Then bridge SMTP port is 1025 + + Scenario: bridge picks ports for SMTP wisely when default port is busy. + When the network port range 1025-1030 is busy + And bridge starts + Then bridge IMAP port is 1143 + Then bridge SMTP port is 1031 + + Scenario: bridge picks ports for IMAP SMTP wisely when default ports are busy. + When the network port range 1025-1200 is busy + And bridge starts + Then bridge IMAP port is 1201 + Then bridge SMTP port is 1202 diff --git a/tests/features/bridge/heartbeat.feature b/tests/features/bridge/heartbeat.feature new file mode 100644 index 00000000..9584f800 --- /dev/null +++ b/tests/features/bridge/heartbeat.feature @@ -0,0 +1,129 @@ +Feature: Send Telemetry Heartbeat + Background: + Given there exists an account with username "[user:user1]" and password "password" + And bridge starts + + + Scenario: Send at first start - one user default settings + Then bridge telemetry feature is enabled + And bridge needs to send heartbeat + When the user logs in with username "[user:user1]" and password "password" + And user "[user:user1]" finishes syncing + Then bridge eventually sends the following heartbeat: + """ + { + "MeasurementGroup": "bridge.any.usage", + "Event": "bridge_heartbeat", + "Values": { + "nb_account": 1 + }, + "Dimensions": { + "auto_update": "on", + "auto_start": "on", + "beta": "off", + "doh": "off", + "split_mode": "off", + "show_all_mail": "on", + "imap_connection_mode": "starttls", + "smtp_connection_mode": "starttls", + "imap_port": "default", + "smtp_port": "default", + "cache_location": "default", + "keychain_pref": "default", + "prev_version": "0.0.0", + "rollout": "42" + } + } + """ + And bridge do not need to send heartbeat + + + Scenario: Send at first start - one user modified settings + Then bridge telemetry feature is enabled + And bridge needs to send heartbeat + When the user has disabled automatic updates + And the user has disabled automatic start + And the user has enabled alternative routing + And the user hides All Mail + And the user set IMAP mode to SSL + And the user set SMTP mode to SSL + And the user changes the IMAP port to 42695 + And the user changes the SMTP port to 56942 + And the user changes the gluon path + And the user changes the default keychain application + When the user logs in with username "[user:user1]" and password "password" + And user "[user:user1]" finishes syncing + Then bridge eventually sends the following heartbeat: + """ + { + "MeasurementGroup": "bridge.any.usage", + "Event": "bridge_heartbeat", + "Values": { + "nb_account": 1 + }, + "Dimensions": { + "auto_update": "off", + "auto_start": "off", + "beta": "off", + "doh": "on", + "split_mode": "off", + "show_all_mail": "off", + "imap_connection_mode": "ssl", + "smtp_connection_mode": "ssl", + "imap_port": "custom", + "smtp_port": "custom", + "cache_location": "custom", + "keychain_pref": "custom", + "prev_version": "0.0.0", + "rollout": "42" + } + } + """ + And bridge do not need to send heartbeat + + + Scenario: Send at first start - one user telemetry disabled + Then bridge telemetry feature is enabled + And bridge needs to send heartbeat + When the user disables telemetry in bridge settings + And the user logs in with username "[user:user1]" and password "password" + And user "[user:user1]" finishes syncing + And bridge needs to send heartbeat + Then the user sets the address mode of user "[user:user1]" to "split" + And the user enables telemetry in bridge settings + Then bridge eventually sends the following heartbeat: + """ + { + "MeasurementGroup": "bridge.any.usage", + "Event": "bridge_heartbeat", + "Values": { + "nb_account": 1 + }, + "Dimensions": { + "auto_update": "on", + "auto_start": "on", + "beta": "off", + "doh": "off", + "split_mode": "on", + "show_all_mail": "on", + "imap_connection_mode": "starttls", + "smtp_connection_mode": "starttls", + "imap_port": "default", + "smtp_port": "default", + "cache_location": "default", + "keychain_pref": "default", + "prev_version": "0.0.0", + "rollout": "42" + } + } + """ + And bridge do not need to send heartbeat + + + Scenario: GroupMeasurement rejected by API + Given heartbeat is not whitelisted + Then bridge telemetry feature is enabled + And bridge needs to send heartbeat + When the user logs in with username "[user:user1]" and password "password" + And user "[user:user1]" finishes syncing + Then bridge needs to send heartbeat diff --git a/tests/features/updates.feature b/tests/features/bridge/updates.feature similarity index 100% rename from tests/features/updates.feature rename to tests/features/bridge/updates.feature diff --git a/tests/features/imap/message/delete_from_trash.feature b/tests/features/imap/message/delete_from_trash.feature index fdc5105e..7d80ece4 100644 --- a/tests/features/imap/message/delete_from_trash.feature +++ b/tests/features/imap/message/delete_from_trash.feature @@ -6,7 +6,7 @@ Feature: IMAP remove messages from Trash | mbox | folder | | label | label | - Scenario Outline: Message in Trash and some other label is not permanently deleted + Scenario Outline: Message in Trash and some other label is permanently deleted Given the address "[user:user]@[domain]" of account "[user:user]" has the following messages in "Trash": | from | to | subject | body | | john.doe@mail.com | [user:user]@[domain] | foo | hello | @@ -26,8 +26,8 @@ Feature: IMAP remove messages from Trash When IMAP client "1" expunges Then it succeeds And IMAP client "1" eventually sees 1 messages in "Trash" - And IMAP client "1" eventually sees 2 messages in "All Mail" - And IMAP client "1" eventually sees 1 messages in "Labels/label" + And IMAP client "1" eventually sees 1 messages in "All Mail" + And IMAP client "1" eventually sees 0 messages in "Labels/label" Scenario Outline: Message in Trash only is permanently deleted Given the address "[user:user]@[domain]" of account "[user:user]" has the following messages in "Trash": diff --git a/tests/features/imap/message/drafts.feature b/tests/features/imap/message/drafts.feature index 6f185418..2c8e6ae7 100644 --- a/tests/features/imap/message/drafts.feature +++ b/tests/features/imap/message/drafts.feature @@ -34,6 +34,7 @@ Feature: IMAP Draft messages | to | subject | body | | someone@example.com | Basic Draft | This is a draft, but longer | And IMAP client "1" eventually sees 1 messages in "Drafts" + And IMAP client "1" does not see header "Reply-To" in message with subject "Basic Draft" in "Drafts" Scenario: Draft edited remotely When the following fields were changed in draft 1 for address "[user:user]@[domain]" of account "[user:user]": @@ -43,9 +44,10 @@ Feature: IMAP Draft messages | to | subject | body | | someone@example.com | Basic Draft | This is a draft body, but longer | And IMAP client "1" eventually sees 1 messages in "Drafts" + And IMAP client "1" does not see header "Reply-To" in message with subject "Basic Draft" in "Drafts" Scenario: Draft moved to trash remotely - When draft 1 for address "[user:user]@[domain]" of account "[user:user] was moved to trash + When draft 1 for address "[user:user]@[domain]" of account "[user:user]" was moved to trash Then IMAP client "1" eventually sees the following messages in "Trash": | body | | This is a dra | diff --git a/tests/features/smtp/send/send_reply.feature b/tests/features/smtp/send/send_reply.feature index 47f9acf4..a3c17143 100644 --- a/tests/features/smtp/send/send_reply.feature +++ b/tests/features/smtp/send/send_reply.feature @@ -5,9 +5,9 @@ Feature: SMTP send reply And there exists an account with username "[user:user2]" and password "password" And bridge starts And the user logs in with username "[user:user1]" and password "password" + And user "[user:user1]" finishes syncing And user "[user:user1]" connects and authenticates SMTP client "1" And user "[user:user1]" connects and authenticates IMAP client "1" - And user "[user:user1]" finishes syncing @long-black Scenario: Reply with In-Reply-To but no References @@ -33,8 +33,8 @@ Feature: SMTP send reply And user "[user:user2]" finishes syncing # User2 receive the message. Then IMAP client "2" eventually sees the following messages in "INBOX": - | from | subject | message-id | - | [user:user1]@[domain] | Please Reply | | + | from | subject | message-id | reply-to | + | [user:user1]@[domain] | Please Reply | | [user:user1]@[domain] | # User2 reply to it. When SMTP client "2" sends the following message from "[user:user2]@[domain]" to "[user:user1]@[domain]": """ @@ -53,8 +53,8 @@ Feature: SMTP send reply | [user:user2]@[domain] | [user:user1]@[domain] | FW - Please Reply | | | # User1 receive the reply.| And IMAP client "1" eventually sees the following messages in "INBOX": - | from | subject | body | in-reply-to | references | - | [user:user2]@[domain] | FW - Please Reply | Heya | | | + | from | subject | body | in-reply-to | references | reply-to | + | [user:user2]@[domain] | FW - Please Reply | Heya | | | [user:user2]@[domain] | @long-black Scenario: Reply with References but no In-Reply-To @@ -80,8 +80,8 @@ Feature: SMTP send reply And user "[user:user2]" finishes syncing # User2 receive the message. Then IMAP client "2" eventually sees the following messages in "INBOX": - | from | subject | message-id | - | [user:user1]@[domain] | Please Reply | | + | from | subject | message-id | reply-to | + | [user:user1]@[domain] | Please Reply | | [user:user1]@[domain] | # User2 reply to it. When SMTP client "2" sends the following message from "[user:user2]@[domain]" to "[user:user1]@[domain]": """ @@ -100,8 +100,8 @@ Feature: SMTP send reply | [user:user2]@[domain] | [user:user1]@[domain] | FW - Please Reply | | | # User1 receive the reply.| And IMAP client "1" eventually sees the following messages in "INBOX": - | from | subject | body | in-reply-to | references | - | [user:user2]@[domain] | FW - Please Reply | Heya | | | + | from | subject | body | in-reply-to | references | reply-to | + | [user:user2]@[domain] | FW - Please Reply | Heya | | | [user:user2]@[domain] | @long-black @@ -128,8 +128,8 @@ Feature: SMTP send reply And user "[user:user2]" finishes syncing # User2 receive the message. Then IMAP client "2" eventually sees the following messages in "INBOX": - | from | subject | message-id | - | [user:user1]@[domain] | Please Reply | | + | from | subject | message-id | reply-to | + | [user:user1]@[domain] | Please Reply | | [user:user1]@[domain] | # User2 reply to it. When SMTP client "2" sends the following message from "[user:user2]@[domain]" to "[user:user1]@[domain]": """ @@ -149,5 +149,5 @@ Feature: SMTP send reply | [user:user2]@[domain] | [user:user1]@[domain] | FW - Please Reply | | | # User1 receive the reply.| And IMAP client "1" eventually sees the following messages in "INBOX": - | from | subject | body | in-reply-to | references | - | [user:user2]@[domain] | FW - Please Reply | Heya | | | \ No newline at end of file + | from | subject | body | in-reply-to | references | reply-to | + | [user:user2]@[domain] | FW - Please Reply | Heya | | | [user:user2]@[domain] | \ No newline at end of file diff --git a/tests/features/user/telemetry.feature b/tests/features/user/telemetry.feature new file mode 100644 index 00000000..ff98029b --- /dev/null +++ b/tests/features/user/telemetry.feature @@ -0,0 +1,29 @@ +Feature: Bridge send usage metrics + Background: + Given there exists an account with username "[user:user1]" and password "password" + And there exists an account with username "[user:user2]" and password "password" + And bridge starts + + + Scenario: Telemetry availability - No user + Then bridge telemetry feature is enabled + When the user disables telemetry in bridge settings + Then bridge telemetry feature is disabled + When the user enables telemetry in bridge settings + Then bridge telemetry feature is enabled + + + Scenario: Telemetry availability - Multi user + When the user logs in with username "[user:user1]" and password "password" + And user "[user:user1]" finishes syncing + Then bridge telemetry feature is enabled + When the user logs in with username "[user:user2]" and password "password" + And user "[user:user2]" finishes syncing + When user "[user:user2]" has telemetry set to 0 + Then bridge telemetry feature is disabled + When user "[user:user2]" has telemetry set to 1 + Then bridge telemetry feature is enabled + When the user disables telemetry in bridge settings + Then bridge telemetry feature is disabled + When the user enables telemetry in bridge settings + Then bridge telemetry feature is enabled \ No newline at end of file diff --git a/tests/heartbeat_test.go b/tests/heartbeat_test.go new file mode 100644 index 00000000..65faa254 --- /dev/null +++ b/tests/heartbeat_test.go @@ -0,0 +1,87 @@ +// Copyright (c) 2023 Proton AG +// +// This file is part of Proton Mail Bridge. +// +// Proton Mail Bridge is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Proton Mail Bridge is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Proton Mail Bridge. If not, see . + +package tests + +import ( + "encoding/json" + "errors" + "fmt" + "time" + + "github.com/ProtonMail/proton-bridge/v3/internal/telemetry" + "github.com/cucumber/godog" + "github.com/sirupsen/logrus" +) + +func (s *scenario) bridgeEventuallySendsTheFollowingHeartbeat(text *godog.DocString) error { + return eventually(func() error { + err := s.bridgeSendsTheFollowingHeartbeat(text) + logrus.WithError(err).Trace("Matching eventually") + return err + }) +} + +func (s *scenario) bridgeSendsTheFollowingHeartbeat(text *godog.DocString) error { + var wantHeartbeat telemetry.HeartbeatData + err := json.Unmarshal([]byte(text.Content), &wantHeartbeat) + if err != nil { + return err + } + + return matchHeartbeat(s.t.heartbeat.heartbeat, wantHeartbeat) +} + +func (s *scenario) bridgeNeedsToSendHeartbeat() error { + last := s.t.heartbeat.GetLastHeartbeatSent() + if !isAnotherDay(last, time.Now()) { + return fmt.Errorf("heartbeat already sent at %s", last) + } + return nil +} + +func (s *scenario) bridgeDoNotNeedToSendHeartbeat() error { + last := s.t.heartbeat.GetLastHeartbeatSent() + if isAnotherDay(last, time.Now()) { + return fmt.Errorf("heartbeat needs to be sent - last %s", last) + } + return nil +} + +func (s *scenario) heartbeatIsNotwhitelisted() error { + s.t.heartbeat.rejectSend() + return nil +} + +func matchHeartbeat(have, want telemetry.HeartbeatData) error { + if have == (telemetry.HeartbeatData{}) { + return errors.New("no heartbeat send (yet)") + } + + // Ignore rollout number + want.Dimensions.Rollout = have.Dimensions.Rollout + + if have != want { + return fmt.Errorf("missing heartbeat: have %#v, want %#v", have, want) + } + + return nil +} + +func isAnotherDay(last, now time.Time) bool { + return now.Year() > last.Year() || (now.Year() == last.Year() && now.YearDay() > last.YearDay()) +} diff --git a/tests/imap_test.go b/tests/imap_test.go index 8cae5707..155b6e37 100644 --- a/tests/imap_test.go +++ b/tests/imap_test.go @@ -297,7 +297,6 @@ func (s *scenario) imapClientSeesTheFollowingMessagesInMailbox(clientID, mailbox if err != nil { return err } - return matchMessages(haveMessages, wantMessages) } @@ -575,6 +574,14 @@ func (s *scenario) imapClientSeesHeaderInMessageWithSubject(clientID, headerStri return fmt.Errorf("could not find message with given subject '%v'", subject) } +func (s *scenario) imapClientDoesNotSeeHeaderInMessageWithSubject(clientID, headerString, subject, mailbox string) error { + err := s.imapClientSeesHeaderInMessageWithSubject(clientID, headerString, subject, mailbox) + if err == nil { + return fmt.Errorf("message header contains '%v'", headerString) + } + return nil +} + func clientList(client *client.Client) []*imap.MailboxInfo { resCh := make(chan *imap.MailboxInfo) diff --git a/tests/types_test.go b/tests/types_test.go index c59b13dc..183637d6 100644 --- a/tests/types_test.go +++ b/tests/types_test.go @@ -43,10 +43,11 @@ type Message struct { MessageID string `bdd:"message-id"` Date string `bdd:"date"` - From string `bdd:"from"` - To string `bdd:"to"` - CC string `bdd:"cc"` - BCC string `bdd:"bcc"` + From string `bdd:"from"` + To string `bdd:"to"` + CC string `bdd:"cc"` + BCC string `bdd:"bcc"` + ReplyTo string `bdd:"reply-to"` Unread bool `bdd:"unread"` Deleted bool `bdd:"deleted"` @@ -158,6 +159,10 @@ func newMessageFromIMAP(msg *imap.Message) Message { message.BCC = msg.Envelope.Bcc[0].Address() } + if len(msg.Envelope.ReplyTo) > 0 { + message.ReplyTo = msg.Envelope.ReplyTo[0].Address() + } + return message } diff --git a/tests/user_test.go b/tests/user_test.go index 3be34f5f..17542987 100644 --- a/tests/user_test.go +++ b/tests/user_test.go @@ -414,6 +414,18 @@ func (s *scenario) userFinishesSyncing(username string) error { return s.bridgeSendsSyncStartedAndFinishedEventsForUser(username) } +func (s *scenario) userHasTelemetrySetTo(username string, telemetry int) error { + return s.t.withClientPass(context.Background(), username, s.t.getUserByName(username).userPass, func(ctx context.Context, c *proton.Client) error { + var req proton.SetTelemetryReq + req.Telemetry = proton.SettingsBool(telemetry) + _, err := c.SetUserSettingsTelemetry(ctx, req) + if err != nil { + return err + } + return nil + }) +} + func (s *scenario) addAdditionalAddressToAccount(username, address string, disabled bool) error { userID := s.t.getUserByName(username).getUserID() diff --git a/utils/port-blocker/port-blocker.go b/utils/port-blocker/port-blocker.go new file mode 100644 index 00000000..9a358f44 --- /dev/null +++ b/utils/port-blocker/port-blocker.go @@ -0,0 +1,83 @@ +// Copyright (c) 2023 Proton AG +// +// This file is part of Proton Mail Bridge. +// +// Proton Mail Bridge is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Proton Mail Bridge is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Proton Mail Bridge. If not, see . + +// port-blocker is a command-line that ensure a port or range of ports is occupied by creating listeners. +package main + +import ( + "fmt" + "net" + "os" + "strconv" +) + +func main() { + argCount := len(os.Args) + if (len(os.Args) < 2) || (argCount > 3) { + exitWithUsage("Invalid number of arguments.") + } + + startPort := parsePort(os.Args[1]) + endPort := startPort + if argCount == 3 { + endPort = parsePort(os.Args[2]) + } + + runBlocker(startPort, endPort) +} + +func parsePort(portString string) int { + result, err := strconv.Atoi(portString) + if err != nil { + exitWithUsage(fmt.Sprintf("Invalid port '%v'.", portString)) + } + + if (result < 1024) || (result > 65535) { // ports below 1024 are reserved. + exitWithUsage("Ports must be in the range [1024-65535].") + } + + return result +} + +func exitWithUsage(message string) { + fmt.Printf("Usage: port-blocker []\n") + if len(message) > 0 { + fmt.Println(message) + } + os.Exit(1) +} + +func runBlocker(startPort, endPort int) { + if endPort < startPort { + exitWithUsage("startPort must be less than or equal to endPort.") + } + + for port := startPort; port <= endPort; port++ { + listener, err := net.Listen("tcp", "127.0.0.1:"+strconv.Itoa(port)) + if err != nil { + fmt.Printf("Port %v is already blocked. Skipping.\n", port) + } else { + //goland:noinspection GoDeferInLoop + defer func() { + _ = listener.Close() + }() + } + } + + fmt.Println("Blocking requested ports. Press enter to exit.") + _, _ = fmt.Scanln() +}