libsignal authenticated websocket
This commit is contained in:
parent
31bcb1e4cc
commit
de33410be1
10 changed files with 470 additions and 286 deletions
|
@ -4733,7 +4733,7 @@ For more information on this, and how to apply and follow the GNU AGPL, see
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## attest 0.1.0, libsignal-ffi 0.52.3, libsignal-jni 0.52.3, libsignal-jni-testing 0.52.3, libsignal-node 0.52.3, signal-neon-futures 0.1.0, signal-neon-futures-tests 0.1.0, libsignal-bridge 0.1.0, libsignal-bridge-macros 0.1.0, libsignal-bridge-testing 0.1.0, libsignal-bridge-types 0.1.0, libsignal-core 0.1.0, signal-crypto 0.1.0, device-transfer 0.1.0, signal-media 0.1.0, libsignal-message-backup 0.1.0, libsignal-message-backup-macros 0.1.0, libsignal-net 0.1.0, signal-pin 0.1.0, poksho 0.7.0, libsignal-protocol 0.1.0, libsignal-svr3 0.1.0, usernames 0.1.0, zkcredential 0.1.0, zkgroup 0.9.0
|
## attest 0.1.0, libsignal-ffi 0.54.0, libsignal-jni 0.54.0, libsignal-jni-testing 0.54.0, libsignal-node 0.54.0, signal-neon-futures 0.1.0, signal-neon-futures-tests 0.1.0, libsignal-bridge 0.1.0, libsignal-bridge-macros 0.1.0, libsignal-bridge-testing 0.1.0, libsignal-bridge-types 0.1.0, libsignal-core 0.1.0, signal-crypto 0.1.0, device-transfer 0.1.0, signal-media 0.1.0, libsignal-message-backup 0.1.0, libsignal-message-backup-macros 0.1.0, libsignal-net 0.1.0, signal-pin 0.1.0, poksho 0.7.0, libsignal-protocol 0.1.0, libsignal-svr3 0.1.0, usernames 0.1.0, zkcredential 0.1.0, zkgroup 0.9.0
|
||||||
|
|
||||||
```
|
```
|
||||||
GNU AFFERO GENERAL PUBLIC LICENSE
|
GNU AFFERO GENERAL PUBLIC LICENSE
|
||||||
|
@ -5182,7 +5182,7 @@ You should also get your employer (if you work as a programmer) or school, if an
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## clang-sys 1.7.0
|
## clang-sys 1.8.1
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -5779,7 +5779,7 @@ END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## debugid 0.8.0, prost-build 0.12.6, prost-derive 0.12.6, prost-types 0.12.6, prost 0.12.6
|
## debugid 0.8.0, prost-build 0.13.1, prost-derive 0.13.1, prost-types 0.13.1, prost 0.13.1
|
||||||
|
|
||||||
```
|
```
|
||||||
Apache License
|
Apache License
|
||||||
|
@ -6008,7 +6008,7 @@ limitations under the License.
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## arrayref 0.3.7
|
## arrayref 0.3.8
|
||||||
|
|
||||||
```
|
```
|
||||||
Copyright (c) 2015 David Roundy <roundyd@physics.oregonstate.edu>
|
Copyright (c) 2015 David Roundy <roundyd@physics.oregonstate.edu>
|
||||||
|
@ -6107,10 +6107,11 @@ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
```
|
```
|
||||||
|
|
||||||
## subtle 2.5.0
|
## subtle 2.6.1
|
||||||
|
|
||||||
```
|
```
|
||||||
Copyright (c) 2016-2017 Isis Agora Lovecruft, Henry de Valence. All rights reserved.
|
Copyright (c) 2016-2017 Isis Agora Lovecruft, Henry de Valence. All rights reserved.
|
||||||
|
Copyright (c) 2016-2024 Isis Agora Lovecruft. All rights reserved.
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
Redistribution and use in source and binary forms, with or without
|
||||||
modification, are permitted provided that the following conditions are
|
modification, are permitted provided that the following conditions are
|
||||||
|
@ -6210,7 +6211,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## asn1 0.16.1, asn1_derive 0.16.1
|
## asn1 0.16.2, asn1_derive 0.16.2
|
||||||
|
|
||||||
```
|
```
|
||||||
Copyright (c) Alex Gaynor and individual contributors.
|
Copyright (c) Alex Gaynor and individual contributors.
|
||||||
|
@ -6476,7 +6477,7 @@ express Statement of Purpose.
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## libloading 0.8.3
|
## libloading 0.8.5
|
||||||
|
|
||||||
```
|
```
|
||||||
Copyright © 2015, Simonas Kazlauskas
|
Copyright © 2015, Simonas Kazlauskas
|
||||||
|
@ -6494,7 +6495,7 @@ THIS SOFTWARE.
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## rustls-webpki 0.102.4
|
## rustls-webpki 0.102.6
|
||||||
|
|
||||||
```
|
```
|
||||||
Except as otherwise noted, this project is licensed under the following
|
Except as otherwise noted, this project is licensed under the following
|
||||||
|
@ -6519,7 +6520,7 @@ third-party/chromium/LICENSE.
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## windows-core 0.52.0, windows-sys 0.45.0, windows-sys 0.48.0, windows-sys 0.52.0, windows-targets 0.42.2, windows-targets 0.48.5, windows-targets 0.52.5, windows_aarch64_msvc 0.42.2, windows_aarch64_msvc 0.48.5, windows_aarch64_msvc 0.52.5, windows_x86_64_gnu 0.48.5, windows_x86_64_gnu 0.52.5, windows_x86_64_msvc 0.42.2, windows_x86_64_msvc 0.48.5, windows_x86_64_msvc 0.52.5
|
## windows-core 0.52.0, windows-sys 0.45.0, windows-sys 0.52.0, windows-targets 0.42.2, windows-targets 0.52.6, windows_aarch64_msvc 0.42.2, windows_aarch64_msvc 0.52.6, windows_x86_64_gnu 0.52.6, windows_x86_64_msvc 0.42.2, windows_x86_64_msvc 0.52.6
|
||||||
|
|
||||||
```
|
```
|
||||||
MIT License
|
MIT License
|
||||||
|
@ -6610,7 +6611,7 @@ DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## lazy_static 1.4.0, rayon-core 1.12.1, rayon 1.10.0
|
## lazy_static 1.5.0, rayon-core 1.12.1, rayon 1.10.0
|
||||||
|
|
||||||
```
|
```
|
||||||
Copyright (c) 2010 The Rust Project Developers
|
Copyright (c) 2010 The Rust Project Developers
|
||||||
|
@ -6729,7 +6730,7 @@ DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## idna 0.5.0, percent-encoding 2.3.1, url 2.5.0
|
## idna 0.5.0, percent-encoding 2.3.1, url 2.5.2
|
||||||
|
|
||||||
```
|
```
|
||||||
Copyright (c) 2013-2022 The rust-url developers
|
Copyright (c) 2013-2022 The rust-url developers
|
||||||
|
@ -6760,7 +6761,7 @@ DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## backtrace 0.3.71, cc 1.0.98, cfg-if 1.0.0, cmake 0.1.48, flate2 1.0.30, openssl-probe 0.1.5, rustc-demangle 0.1.24, socket2 0.5.7
|
## backtrace 0.3.73, cc 1.1.6, cfg-if 1.0.0, cmake 0.1.48, flate2 1.0.30, jobserver 0.1.32, openssl-probe 0.1.5, rustc-demangle 0.1.24, socket2 0.5.7
|
||||||
|
|
||||||
```
|
```
|
||||||
Copyright (c) 2014 Alex Crichton
|
Copyright (c) 2014 Alex Crichton
|
||||||
|
@ -6823,38 +6824,7 @@ DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## jobserver 0.1.31
|
## mio 1.0.1
|
||||||
|
|
||||||
```
|
|
||||||
Copyright (c) 2014 Alex Crichton
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any
|
|
||||||
person obtaining a copy of this software and associated
|
|
||||||
documentation files (the "Software"), to deal in the
|
|
||||||
Software without restriction, including without
|
|
||||||
limitation the rights to use, copy, modify, merge,
|
|
||||||
publish, distribute, sublicense, and/or sell copies of
|
|
||||||
the Software, and to permit persons to whom the Software
|
|
||||||
is furnished to do so, subject to the following
|
|
||||||
conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice
|
|
||||||
shall be included in all copies or substantial portions
|
|
||||||
of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
|
|
||||||
ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
|
|
||||||
TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
|
|
||||||
PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
|
|
||||||
SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
|
||||||
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
||||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
|
|
||||||
IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
||||||
DEALINGS IN THE SOFTWARE.
|
|
||||||
|
|
||||||
```
|
|
||||||
|
|
||||||
## mio 0.8.11
|
|
||||||
|
|
||||||
```
|
```
|
||||||
Copyright (c) 2014 Carl Lerche and other MIO contributors
|
Copyright (c) 2014 Carl Lerche and other MIO contributors
|
||||||
|
@ -6942,7 +6912,7 @@ DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## bitflags 2.5.0, glob 0.3.1, log 0.4.21, num-bigint 0.4.5, num-derive 0.4.2, num-integer 0.1.46, num-traits 0.2.19, range-map 0.2.0, regex-automata 0.4.6, regex-syntax 0.8.3, regex 1.10.4
|
## bitflags 2.6.0, glob 0.3.1, log 0.4.22, num-bigint 0.4.6, num-derive 0.4.2, num-integer 0.1.46, num-traits 0.2.19, range-map 0.2.0, regex-automata 0.4.7, regex-syntax 0.8.4, regex 1.10.5
|
||||||
|
|
||||||
```
|
```
|
||||||
Copyright (c) 2014 The Rust Project Developers
|
Copyright (c) 2014 The Rust Project Developers
|
||||||
|
@ -6973,7 +6943,7 @@ DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## uuid 1.8.0
|
## uuid 1.10.0
|
||||||
|
|
||||||
```
|
```
|
||||||
Copyright (c) 2014 The Rust Project Developers
|
Copyright (c) 2014 The Rust Project Developers
|
||||||
|
@ -7062,7 +7032,7 @@ DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## hyper 1.3.1
|
## hyper 1.4.1
|
||||||
|
|
||||||
```
|
```
|
||||||
Copyright (c) 2014-2021 Sean McArthur
|
Copyright (c) 2014-2021 Sean McArthur
|
||||||
|
@ -7087,7 +7057,7 @@ THE SOFTWARE.
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## either 1.12.0, itertools 0.12.1, petgraph 0.6.5
|
## either 1.13.0, itertools 0.13.0, petgraph 0.6.5
|
||||||
|
|
||||||
```
|
```
|
||||||
Copyright (c) 2015
|
Copyright (c) 2015
|
||||||
|
@ -7116,32 +7086,6 @@ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
|
||||||
IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
DEALINGS IN THE SOFTWARE.
|
DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
```
|
|
||||||
|
|
||||||
## num_cpus 1.16.0
|
|
||||||
|
|
||||||
```
|
|
||||||
Copyright (c) 2015
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
|
||||||
in the Software without restriction, including without limitation the rights
|
|
||||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
copies of the Software, and to permit persons to whom the Software is
|
|
||||||
furnished to do so, subject to the following conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in
|
|
||||||
all copies or substantial portions of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
||||||
THE SOFTWARE.
|
|
||||||
|
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## neon-macros 1.0.0, neon 1.0.0
|
## neon-macros 1.0.0, neon 1.0.0
|
||||||
|
@ -7169,7 +7113,7 @@ THE SOFTWARE.
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## anstyle-wincon 3.0.3
|
## anstyle-wincon 3.0.4
|
||||||
|
|
||||||
```
|
```
|
||||||
Copyright (c) 2015 Josh Triplett, 2022 The rust-cli Developers
|
Copyright (c) 2015 Josh Triplett, 2022 The rust-cli Developers
|
||||||
|
@ -7225,7 +7169,7 @@ DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## object 0.32.2
|
## object 0.36.2
|
||||||
|
|
||||||
```
|
```
|
||||||
Copyright (c) 2015 The Gimli Developers
|
Copyright (c) 2015 The Gimli Developers
|
||||||
|
@ -7256,7 +7200,7 @@ DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## gimli 0.28.1, heck 0.3.3, heck 0.4.1, heck 0.5.0, peeking_take_while 0.1.2, unicode-bidi 0.3.15, unicode-normalization 0.1.23, unicode-segmentation 1.11.0
|
## gimli 0.29.0, heck 0.5.0, peeking_take_while 0.1.2, unicode-bidi 0.3.15, unicode-normalization 0.1.23
|
||||||
|
|
||||||
```
|
```
|
||||||
Copyright (c) 2015 The Rust Project Developers
|
Copyright (c) 2015 The Rust Project Developers
|
||||||
|
@ -7577,10 +7521,10 @@ DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## httparse 1.8.0
|
## httparse 1.9.4
|
||||||
|
|
||||||
```
|
```
|
||||||
Copyright (c) 2015-2021 Sean McArthur
|
Copyright (c) 2015-2024 Sean McArthur
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
@ -7635,7 +7579,7 @@ DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## hashbrown 0.12.3, hashbrown 0.14.5
|
## hashbrown 0.14.5
|
||||||
|
|
||||||
```
|
```
|
||||||
Copyright (c) 2016 Amanieu d'Antras
|
Copyright (c) 2016 Amanieu d'Antras
|
||||||
|
@ -7666,7 +7610,7 @@ DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## utf8parse 0.2.1
|
## utf8parse 0.2.2
|
||||||
|
|
||||||
```
|
```
|
||||||
Copyright (c) 2016 Joe Wilm
|
Copyright (c) 2016 Joe Wilm
|
||||||
|
@ -7697,7 +7641,7 @@ DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## anstyle-parse 0.2.4
|
## anstyle-parse 0.2.5
|
||||||
|
|
||||||
```
|
```
|
||||||
Copyright (c) 2016 Joe Wilm and individual contributors
|
Copyright (c) 2016 Joe Wilm and individual contributors
|
||||||
|
@ -7728,7 +7672,7 @@ DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## rustls-native-certs 0.7.0, rustls-pemfile 2.1.2, rustls 0.23.8
|
## rustls-native-certs 0.7.1, rustls-pemfile 2.1.2, rustls 0.23.12
|
||||||
|
|
||||||
```
|
```
|
||||||
Copyright (c) 2016 Joseph Birr-Pixton <jpixton@gmail.com>
|
Copyright (c) 2016 Joseph Birr-Pixton <jpixton@gmail.com>
|
||||||
|
@ -7941,7 +7885,7 @@ DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## indexmap 1.9.3, indexmap 2.2.6
|
## indexmap 2.2.6
|
||||||
|
|
||||||
```
|
```
|
||||||
Copyright (c) 2016--2017
|
Copyright (c) 2016--2017
|
||||||
|
@ -8003,7 +7947,7 @@ DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## addr2line 0.21.0
|
## addr2line 0.22.0
|
||||||
|
|
||||||
```
|
```
|
||||||
Copyright (c) 2016-2018 The gimli Developers
|
Copyright (c) 2016-2018 The gimli Developers
|
||||||
|
@ -8096,7 +8040,7 @@ DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## tungstenite 0.21.0
|
## tungstenite 0.23.0
|
||||||
|
|
||||||
```
|
```
|
||||||
Copyright (c) 2017 Alexey Galakhov
|
Copyright (c) 2017 Alexey Galakhov
|
||||||
|
@ -8215,7 +8159,7 @@ DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## tokio-tungstenite 0.21.0
|
## tokio-tungstenite 0.23.1
|
||||||
|
|
||||||
```
|
```
|
||||||
Copyright (c) 2017 Daniel Abramov
|
Copyright (c) 2017 Daniel Abramov
|
||||||
|
@ -8417,7 +8361,7 @@ DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## bytes 1.6.0
|
## bytes 1.6.1
|
||||||
|
|
||||||
```
|
```
|
||||||
Copyright (c) 2018 Carl Lerche
|
Copyright (c) 2018 Carl Lerche
|
||||||
|
@ -8751,7 +8695,7 @@ DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## http-body-util 0.1.1, http-body 1.0.0
|
## http-body-util 0.1.2
|
||||||
|
|
||||||
```
|
```
|
||||||
Copyright (c) 2019 Hyper Contributors
|
Copyright (c) 2019 Hyper Contributors
|
||||||
|
@ -8813,7 +8757,7 @@ DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## protobuf-codegen 3.4.0, protobuf-json-mapping 3.4.0, protobuf-parse 3.4.0, protobuf-support 3.4.0, protobuf 3.4.0
|
## protobuf-codegen 3.5.0, protobuf-json-mapping 3.5.0, protobuf-support 3.5.0, protobuf 3.5.0
|
||||||
|
|
||||||
```
|
```
|
||||||
Copyright (c) 2019 Stepan Koltsov
|
Copyright (c) 2019 Stepan Koltsov
|
||||||
|
@ -8835,6 +8779,7 @@ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
|
||||||
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
|
||||||
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
|
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
|
||||||
OR OTHER DEALINGS IN THE SOFTWARE.
|
OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## ppv-lite86 0.2.17
|
## ppv-lite86 0.2.17
|
||||||
|
@ -9055,6 +9000,37 @@ DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## http-body 1.0.1
|
||||||
|
|
||||||
|
```
|
||||||
|
Copyright (c) 2019-2024 Sean McArthur & Hyper Contributors
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any
|
||||||
|
person obtaining a copy of this software and associated
|
||||||
|
documentation files (the "Software"), to deal in the
|
||||||
|
Software without restriction, including without
|
||||||
|
limitation the rights to use, copy, modify, merge,
|
||||||
|
publish, distribute, sublicense, and/or sell copies of
|
||||||
|
the Software, and to permit persons to whom the Software
|
||||||
|
is furnished to do so, subject to the following
|
||||||
|
conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice
|
||||||
|
shall be included in all copies or substantial portions
|
||||||
|
of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
|
||||||
|
ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
|
||||||
|
TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
|
||||||
|
PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
|
||||||
|
SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||||
|
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||||
|
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
|
||||||
|
IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
## iana-time-zone 0.1.60
|
## iana-time-zone 0.1.60
|
||||||
|
|
||||||
```
|
```
|
||||||
|
@ -9330,7 +9306,7 @@ DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## anstyle 1.0.7
|
## anstyle 1.0.8
|
||||||
|
|
||||||
```
|
```
|
||||||
Copyright (c) 2022 The rust-cli Developers
|
Copyright (c) 2022 The rust-cli Developers
|
||||||
|
@ -9461,7 +9437,7 @@ SOFTWARE.
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## hyper-util 0.1.4
|
## hyper-util 0.1.6
|
||||||
|
|
||||||
```
|
```
|
||||||
Copyright (c) 2023 Sean McArthur
|
Copyright (c) 2023 Sean McArthur
|
||||||
|
@ -9486,7 +9462,7 @@ THE SOFTWARE.
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## tokio-macros 2.2.0, tokio-stream 0.1.15, tokio-util 0.7.11, tokio 1.37.0
|
## tokio-stream 0.1.15, tokio-util 0.7.11
|
||||||
|
|
||||||
```
|
```
|
||||||
Copyright (c) 2023 Tokio Contributors
|
Copyright (c) 2023 Tokio Contributors
|
||||||
|
@ -9542,7 +9518,7 @@ SOFTWARE.
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## anstream 0.6.14, anstyle-query 1.0.3, clap 4.4.18, colorchoice 1.0.1, env_logger 0.10.2, is_terminal_polyfill 1.70.0, toml_datetime 0.6.6, toml_edit 0.19.15
|
## anstream 0.6.15, anstyle-query 1.1.1, clap 4.5.11, colorchoice 1.0.2, env_filter 0.1.2, env_logger 0.11.5, is_terminal_polyfill 1.70.1, toml_datetime 0.6.7, toml_edit 0.21.1
|
||||||
|
|
||||||
```
|
```
|
||||||
Copyright (c) Individual contributors
|
Copyright (c) Individual contributors
|
||||||
|
@ -9642,7 +9618,7 @@ DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## zerocopy-derive 0.7.34, zerocopy 0.7.34
|
## zerocopy-derive 0.7.35, zerocopy 0.7.35
|
||||||
|
|
||||||
```
|
```
|
||||||
Copyright 2023 The Fuchsia Authors
|
Copyright 2023 The Fuchsia Authors
|
||||||
|
@ -9786,7 +9762,7 @@ SOFTWARE.
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## miniz_oxide 0.7.3
|
## miniz_oxide 0.7.4
|
||||||
|
|
||||||
```
|
```
|
||||||
MIT License
|
MIT License
|
||||||
|
@ -9921,7 +9897,7 @@ SOFTWARE.
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## zeroize 1.7.0
|
## zeroize 1.8.1
|
||||||
|
|
||||||
```
|
```
|
||||||
MIT License
|
MIT License
|
||||||
|
@ -9975,7 +9951,7 @@ SOFTWARE.
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## strum 0.26.2, strum_macros 0.26.4
|
## strum 0.26.3, strum_macros 0.26.4
|
||||||
|
|
||||||
```
|
```
|
||||||
MIT License
|
MIT License
|
||||||
|
@ -10002,6 +9978,34 @@ SOFTWARE.
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## tokio-macros 2.4.0
|
||||||
|
|
||||||
|
```
|
||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2019 Yoshua Wuyts
|
||||||
|
Copyright (c) Tokio Contributors
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
## fslock 0.2.1
|
## fslock 0.2.1
|
||||||
|
|
||||||
```
|
```
|
||||||
|
@ -10217,7 +10221,34 @@ SOFTWARE.
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## cesu8 1.1.0, half 2.4.1, pqcrypto-internals 0.2.5, pqcrypto-kyber 0.7.9, pqcrypto-kyber 0.8.1, pqcrypto-traits 0.3.5, rustls-platform-verifier-android 0.1.0, rustls-platform-verifier 0.3.1
|
## rustls-platform-verifier-android 0.1.0, rustls-platform-verifier 0.3.2
|
||||||
|
|
||||||
|
```
|
||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2022 1Password
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
## cesu8 1.1.0, half 2.4.1, pqcrypto-internals 0.2.5, pqcrypto-kyber 0.7.9, pqcrypto-kyber 0.8.1, pqcrypto-traits 0.3.5, protobuf-parse 3.5.0
|
||||||
|
|
||||||
```
|
```
|
||||||
MIT License
|
MIT License
|
||||||
|
@ -10232,6 +10263,33 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## tokio 1.39.1
|
||||||
|
|
||||||
|
```
|
||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) Tokio Contributors
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
## android-tzdata 0.1.1
|
## android-tzdata 0.1.1
|
||||||
|
|
||||||
```
|
```
|
||||||
|
@ -10316,7 +10374,7 @@ DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## curve25519-dalek-derive 0.1.1, adler 1.0.2, anyhow 1.0.86, async-trait 0.1.80, atomic-waker 1.1.2, displaydoc 0.2.5, dyn-clone 1.0.17, fastrand 2.1.0, home 0.5.9, is-terminal 0.4.12, itoa 1.0.11, linkme-impl 0.3.26, linkme 0.3.26, linux-raw-sys 0.4.14, minimal-lexical 0.2.1, num_enum 0.6.1, num_enum_derive 0.6.1, once_cell 1.19.0, paste 1.0.15, pin-project-lite 0.2.14, prettyplease 0.2.20, proc-macro-crate 1.3.1, proc-macro2 1.0.83, quote 1.0.36, rustc-hash 1.1.0, rustix 0.38.34, rustversion 1.0.17, semver 1.0.23, send_wrapper 0.6.0, serde 1.0.202, serde_derive 1.0.202, serde_json 1.0.117, syn-mid 0.6.0, syn 1.0.109, syn 2.0.66, thiserror-impl 1.0.61, thiserror 1.0.61, unicode-ident 1.0.12, utf-8 0.7.6
|
## curve25519-dalek-derive 0.1.1, adler 1.0.2, anyhow 1.0.86, async-trait 0.1.81, atomic-waker 1.1.2, displaydoc 0.2.5, dyn-clone 1.0.17, fastrand 2.1.0, home 0.5.9, itoa 1.0.11, linkme-impl 0.3.27, linkme 0.3.27, linux-raw-sys 0.4.14, minimal-lexical 0.2.1, num_enum 0.7.2, num_enum_derive 0.7.2, once_cell 1.19.0, paste 1.0.15, pin-project-lite 0.2.14, prettyplease 0.2.20, proc-macro-crate 3.1.0, proc-macro2 1.0.86, quote 1.0.36, rustc-hash 1.1.0, rustix 0.38.34, rustversion 1.0.17, semver 1.0.23, send_wrapper 0.6.0, serde 1.0.204, serde_derive 1.0.204, serde_json 1.0.120, syn-mid 0.6.0, syn 1.0.109, syn 2.0.72, thiserror-impl 1.0.63, thiserror 1.0.63, unicode-ident 1.0.12, utf-8 0.7.6
|
||||||
|
|
||||||
```
|
```
|
||||||
Permission is hereby granted, free of charge, to any
|
Permission is hereby granted, free of charge, to any
|
||||||
|
@ -10369,7 +10427,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## tinyvec 1.6.0
|
## tinyvec 1.8.0
|
||||||
|
|
||||||
```
|
```
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||||
|
@ -10512,7 +10570,7 @@ THE SOFTWARE.
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## aho-corasick 1.1.3, byteorder 1.5.0, memchr 2.7.2, termcolor 1.4.1, walkdir 2.5.0
|
## aho-corasick 1.1.3, byteorder 1.5.0, memchr 2.7.4, walkdir 2.5.0
|
||||||
|
|
||||||
```
|
```
|
||||||
The MIT License (MIT)
|
The MIT License (MIT)
|
||||||
|
@ -10539,7 +10597,7 @@ THE SOFTWARE.
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## strsim 0.10.0
|
## strsim 0.10.0, strsim 0.11.1
|
||||||
|
|
||||||
```
|
```
|
||||||
The MIT License (MIT)
|
The MIT License (MIT)
|
||||||
|
@ -10623,7 +10681,7 @@ THE SOFTWARE.
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## security-framework-sys 2.11.0, security-framework 2.11.0
|
## security-framework-sys 2.11.1, security-framework 2.11.1
|
||||||
|
|
||||||
```
|
```
|
||||||
The MIT License (MIT)
|
The MIT License (MIT)
|
||||||
|
@ -10677,7 +10735,7 @@ SOFTWARE.
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## clap_builder 4.4.18, clap_derive 4.4.7, clap_lex 0.6.0
|
## clap_builder 4.5.11, clap_derive 4.5.11, clap_lex 0.7.2
|
||||||
|
|
||||||
```
|
```
|
||||||
The MIT License (MIT)
|
The MIT License (MIT)
|
||||||
|
@ -10704,7 +10762,7 @@ SOFTWARE.
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## derive_more 0.99.17
|
## derive_more 0.99.18
|
||||||
|
|
||||||
```
|
```
|
||||||
The MIT License (MIT)
|
The MIT License (MIT)
|
||||||
|
@ -10812,7 +10870,7 @@ THE SOFTWARE.
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## async-compression 0.4.10
|
## async-compression 0.4.12
|
||||||
|
|
||||||
```
|
```
|
||||||
The MIT License (MIT)
|
The MIT License (MIT)
|
||||||
|
@ -10960,7 +11018,7 @@ SOFTWARE.
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## version_check 0.9.4
|
## version_check 0.9.5
|
||||||
|
|
||||||
```
|
```
|
||||||
The MIT License (MIT)
|
The MIT License (MIT)
|
||||||
|
|
8
package-lock.json
generated
8
package-lock.json
generated
|
@ -22,7 +22,7 @@
|
||||||
"@react-aria/utils": "3.16.0",
|
"@react-aria/utils": "3.16.0",
|
||||||
"@react-spring/web": "9.5.5",
|
"@react-spring/web": "9.5.5",
|
||||||
"@signalapp/better-sqlite3": "8.7.1",
|
"@signalapp/better-sqlite3": "8.7.1",
|
||||||
"@signalapp/libsignal-client": "0.52.3",
|
"@signalapp/libsignal-client": "0.54.0",
|
||||||
"@signalapp/ringrtc": "2.46.0",
|
"@signalapp/ringrtc": "2.46.0",
|
||||||
"@signalapp/windows-dummy-keystroke": "1.0.0",
|
"@signalapp/windows-dummy-keystroke": "1.0.0",
|
||||||
"@types/fabric": "4.5.3",
|
"@types/fabric": "4.5.3",
|
||||||
|
@ -7224,9 +7224,9 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@signalapp/libsignal-client": {
|
"node_modules/@signalapp/libsignal-client": {
|
||||||
"version": "0.52.3",
|
"version": "0.54.0",
|
||||||
"resolved": "https://registry.npmjs.org/@signalapp/libsignal-client/-/libsignal-client-0.52.3.tgz",
|
"resolved": "https://registry.npmjs.org/@signalapp/libsignal-client/-/libsignal-client-0.54.0.tgz",
|
||||||
"integrity": "sha512-mGO6DUfaWq4tX6NdX3jCXe+1TB/PhX0Lw5HBsJVxJpIUITRF0+OQqDHddj31+DL7F6tbTBX3pyp/L+BKLpg4Gw==",
|
"integrity": "sha512-bkdw3r39UU0W0UaFAJJVhLC5AEiMkgCgtdtabI64c1KuT7oeIx4XvegfqtBwF7vKj29ZHz4lODCh3tFyqbrNLw==",
|
||||||
"hasInstallScript": true,
|
"hasInstallScript": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"node-gyp-build": "^4.2.3",
|
"node-gyp-build": "^4.2.3",
|
||||||
|
|
|
@ -104,7 +104,7 @@
|
||||||
"@react-aria/utils": "3.16.0",
|
"@react-aria/utils": "3.16.0",
|
||||||
"@react-spring/web": "9.5.5",
|
"@react-spring/web": "9.5.5",
|
||||||
"@signalapp/better-sqlite3": "8.7.1",
|
"@signalapp/better-sqlite3": "8.7.1",
|
||||||
"@signalapp/libsignal-client": "0.52.3",
|
"@signalapp/libsignal-client": "0.54.0",
|
||||||
"@signalapp/ringrtc": "2.46.0",
|
"@signalapp/ringrtc": "2.46.0",
|
||||||
"@signalapp/windows-dummy-keystroke": "1.0.0",
|
"@signalapp/windows-dummy-keystroke": "1.0.0",
|
||||||
"@types/fabric": "4.5.3",
|
"@types/fabric": "4.5.3",
|
||||||
|
|
|
@ -26,6 +26,7 @@ export type ConfigKeyType =
|
||||||
| 'desktop.retryRespondMaxAge'
|
| 'desktop.retryRespondMaxAge'
|
||||||
| 'desktop.senderKey.retry'
|
| 'desktop.senderKey.retry'
|
||||||
| 'desktop.senderKeyMaxAge'
|
| 'desktop.senderKeyMaxAge'
|
||||||
|
| 'desktop.experimentalTransport.enableAuth'
|
||||||
| 'desktop.experimentalTransportEnabled.alpha'
|
| 'desktop.experimentalTransportEnabled.alpha'
|
||||||
| 'desktop.experimentalTransportEnabled.beta'
|
| 'desktop.experimentalTransportEnabled.beta'
|
||||||
| 'desktop.experimentalTransportEnabled.prod'
|
| 'desktop.experimentalTransportEnabled.prod'
|
||||||
|
|
|
@ -7,7 +7,7 @@ import { assert } from 'chai';
|
||||||
import Long from 'long';
|
import Long from 'long';
|
||||||
|
|
||||||
import MessageReceiver from '../textsecure/MessageReceiver';
|
import MessageReceiver from '../textsecure/MessageReceiver';
|
||||||
import { IncomingWebSocketRequest } from '../textsecure/WebsocketResources';
|
import { IncomingWebSocketRequestLegacy } from '../textsecure/WebsocketResources';
|
||||||
import type { WebAPIType } from '../textsecure/WebAPI';
|
import type { WebAPIType } from '../textsecure/WebAPI';
|
||||||
import type { DecryptionErrorEvent } from '../textsecure/messageReceiverEvents';
|
import type { DecryptionErrorEvent } from '../textsecure/messageReceiverEvents';
|
||||||
import { generateAci } from '../types/ServiceId';
|
import { generateAci } from '../types/ServiceId';
|
||||||
|
@ -53,7 +53,7 @@ describe('MessageReceiver', () => {
|
||||||
}).finish();
|
}).finish();
|
||||||
|
|
||||||
messageReceiver.handleRequest(
|
messageReceiver.handleRequest(
|
||||||
new IncomingWebSocketRequest(
|
new IncomingWebSocketRequestLegacy(
|
||||||
{
|
{
|
||||||
id: Long.fromNumber(1),
|
id: Long.fromNumber(1),
|
||||||
verb: 'PUT',
|
verb: 'PUT',
|
||||||
|
|
|
@ -16,7 +16,9 @@ import Long from 'long';
|
||||||
import { dropNull } from '../util/dropNull';
|
import { dropNull } from '../util/dropNull';
|
||||||
import { SignalService as Proto } from '../protobuf';
|
import { SignalService as Proto } from '../protobuf';
|
||||||
|
|
||||||
import WebSocketResource from '../textsecure/WebsocketResources';
|
import WebSocketResource, {
|
||||||
|
ServerRequestType,
|
||||||
|
} from '../textsecure/WebsocketResources';
|
||||||
|
|
||||||
describe('WebSocket-Resource', () => {
|
describe('WebSocket-Resource', () => {
|
||||||
class FakeSocket extends EventEmitter {
|
class FakeSocket extends EventEmitter {
|
||||||
|
@ -72,8 +74,7 @@ describe('WebSocket-Resource', () => {
|
||||||
new WebSocketResource(socket as WebSocket, {
|
new WebSocketResource(socket as WebSocket, {
|
||||||
name: 'test',
|
name: 'test',
|
||||||
handleRequest(request: any) {
|
handleRequest(request: any) {
|
||||||
assert.strictEqual(request.verb, 'PUT');
|
assert.strictEqual(request.requestType, ServerRequestType.ApiMessage);
|
||||||
assert.strictEqual(request.path, '/some/path');
|
|
||||||
assert.deepEqual(request.body, new Uint8Array([1, 2, 3]));
|
assert.deepEqual(request.body, new Uint8Array([1, 2, 3]));
|
||||||
request.respond(200, 'OK');
|
request.respond(200, 'OK');
|
||||||
},
|
},
|
||||||
|
@ -87,7 +88,7 @@ describe('WebSocket-Resource', () => {
|
||||||
request: {
|
request: {
|
||||||
id: requestId,
|
id: requestId,
|
||||||
verb: 'PUT',
|
verb: 'PUT',
|
||||||
path: '/some/path',
|
path: ServerRequestType.ApiMessage.toString(),
|
||||||
body: new Uint8Array([1, 2, 3]),
|
body: new Uint8Array([1, 2, 3]),
|
||||||
},
|
},
|
||||||
}).finish(),
|
}).finish(),
|
||||||
|
|
|
@ -15,39 +15,40 @@ import type {
|
||||||
WebAPIType,
|
WebAPIType,
|
||||||
} from './WebAPI';
|
} from './WebAPI';
|
||||||
import type {
|
import type {
|
||||||
CompatSignedPreKeyType,
|
|
||||||
CompatPreKeyType,
|
CompatPreKeyType,
|
||||||
|
CompatSignedPreKeyType,
|
||||||
KeyPairType,
|
KeyPairType,
|
||||||
KyberPreKeyType,
|
KyberPreKeyType,
|
||||||
PniKeyMaterialType,
|
PniKeyMaterialType,
|
||||||
} from './Types.d';
|
} from './Types.d';
|
||||||
import ProvisioningCipher from './ProvisioningCipher';
|
import ProvisioningCipher from './ProvisioningCipher';
|
||||||
import type { IncomingWebSocketRequest } from './WebsocketResources';
|
import type { IncomingWebSocketRequest } from './WebsocketResources';
|
||||||
|
import { ServerRequestType } from './WebsocketResources';
|
||||||
import createTaskWithTimeout from './TaskWithTimeout';
|
import createTaskWithTimeout from './TaskWithTimeout';
|
||||||
import * as Bytes from '../Bytes';
|
import * as Bytes from '../Bytes';
|
||||||
import * as Errors from '../types/errors';
|
import * as Errors from '../types/errors';
|
||||||
import { senderCertificateService } from '../services/senderCertificate';
|
import { senderCertificateService } from '../services/senderCertificate';
|
||||||
import { backupsService } from '../services/backups';
|
import { backupsService } from '../services/backups';
|
||||||
import {
|
import {
|
||||||
|
decryptDeviceName,
|
||||||
deriveAccessKey,
|
deriveAccessKey,
|
||||||
|
deriveStorageServiceKey,
|
||||||
|
encryptDeviceName,
|
||||||
generateRegistrationId,
|
generateRegistrationId,
|
||||||
getRandomBytes,
|
getRandomBytes,
|
||||||
decryptDeviceName,
|
|
||||||
encryptDeviceName,
|
|
||||||
deriveStorageServiceKey,
|
|
||||||
} from '../Crypto';
|
} from '../Crypto';
|
||||||
import {
|
import {
|
||||||
generateKeyPair,
|
generateKeyPair,
|
||||||
generateSignedPreKey,
|
|
||||||
generatePreKey,
|
|
||||||
generateKyberPreKey,
|
generateKyberPreKey,
|
||||||
|
generatePreKey,
|
||||||
|
generateSignedPreKey,
|
||||||
} from '../Curve';
|
} from '../Curve';
|
||||||
import type { ServiceIdString, AciString, PniString } from '../types/ServiceId';
|
import type { AciString, PniString, ServiceIdString } from '../types/ServiceId';
|
||||||
import {
|
import {
|
||||||
ServiceIdKind,
|
|
||||||
normalizePni,
|
|
||||||
toTaggedPni,
|
|
||||||
isUntaggedPniString,
|
isUntaggedPniString,
|
||||||
|
normalizePni,
|
||||||
|
ServiceIdKind,
|
||||||
|
toTaggedPni,
|
||||||
} from '../types/ServiceId';
|
} from '../types/ServiceId';
|
||||||
import { normalizeAci } from '../util/normalizeAci';
|
import { normalizeAci } from '../util/normalizeAci';
|
||||||
import { drop } from '../util/drop';
|
import { drop } from '../util/drop';
|
||||||
|
@ -367,8 +368,7 @@ export default class AccountManager extends EventTarget {
|
||||||
const wsr = await this.server.getProvisioningResource({
|
const wsr = await this.server.getProvisioningResource({
|
||||||
handleRequest(request: IncomingWebSocketRequest) {
|
handleRequest(request: IncomingWebSocketRequest) {
|
||||||
if (
|
if (
|
||||||
request.path === '/v1/address' &&
|
request.requestType === ServerRequestType.ProvisioningAddress &&
|
||||||
request.verb === 'PUT' &&
|
|
||||||
request.body
|
request.body
|
||||||
) {
|
) {
|
||||||
const proto = Proto.ProvisioningUuid.decode(request.body);
|
const proto = Proto.ProvisioningUuid.decode(request.body);
|
||||||
|
@ -388,8 +388,7 @@ export default class AccountManager extends EventTarget {
|
||||||
setProvisioningUrl(url);
|
setProvisioningUrl(url);
|
||||||
request.respond(200, 'OK');
|
request.respond(200, 'OK');
|
||||||
} else if (
|
} else if (
|
||||||
request.path === '/v1/message' &&
|
request.requestType === ServerRequestType.ProvisioningMessage &&
|
||||||
request.verb === 'PUT' &&
|
|
||||||
request.body
|
request.body
|
||||||
) {
|
) {
|
||||||
const envelope = Proto.ProvisionEnvelope.decode(request.body);
|
const envelope = Proto.ProvisionEnvelope.decode(request.body);
|
||||||
|
@ -397,7 +396,7 @@ export default class AccountManager extends EventTarget {
|
||||||
wsr.close();
|
wsr.close();
|
||||||
envelopeCallbacks?.resolve(envelope);
|
envelopeCallbacks?.resolve(envelope);
|
||||||
} else {
|
} else {
|
||||||
log.error('Unknown websocket message', request.path);
|
log.error('Unknown websocket message', request.requestType);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
|
@ -13,13 +13,13 @@ import type {
|
||||||
UnidentifiedSenderMessageContent,
|
UnidentifiedSenderMessageContent,
|
||||||
} from '@signalapp/libsignal-client';
|
} from '@signalapp/libsignal-client';
|
||||||
import {
|
import {
|
||||||
ContentHint,
|
|
||||||
CiphertextMessageType,
|
CiphertextMessageType,
|
||||||
|
ContentHint,
|
||||||
DecryptionErrorMessage,
|
DecryptionErrorMessage,
|
||||||
groupDecrypt,
|
groupDecrypt,
|
||||||
PlaintextContent,
|
PlaintextContent,
|
||||||
PreKeySignalMessage,
|
|
||||||
Pni,
|
Pni,
|
||||||
|
PreKeySignalMessage,
|
||||||
processSenderKeyDistributionMessage,
|
processSenderKeyDistributionMessage,
|
||||||
ProtocolAddress,
|
ProtocolAddress,
|
||||||
PublicKey,
|
PublicKey,
|
||||||
|
@ -40,7 +40,7 @@ import {
|
||||||
SignedPreKeys,
|
SignedPreKeys,
|
||||||
} from '../LibSignalStores';
|
} from '../LibSignalStores';
|
||||||
import { verifySignature } from '../Curve';
|
import { verifySignature } from '../Curve';
|
||||||
import { strictAssert, assertDev } from '../util/assert';
|
import { assertDev, strictAssert } from '../util/assert';
|
||||||
import type { BatcherType } from '../util/batcher';
|
import type { BatcherType } from '../util/batcher';
|
||||||
import { createBatcher } from '../util/batcher';
|
import { createBatcher } from '../util/batcher';
|
||||||
import { drop } from '../util/drop';
|
import { drop } from '../util/drop';
|
||||||
|
@ -48,6 +48,7 @@ import { dropNull } from '../util/dropNull';
|
||||||
import { parseIntOrThrow } from '../util/parseIntOrThrow';
|
import { parseIntOrThrow } from '../util/parseIntOrThrow';
|
||||||
import { clearTimeoutIfNecessary } from '../util/clearTimeoutIfNecessary';
|
import { clearTimeoutIfNecessary } from '../util/clearTimeoutIfNecessary';
|
||||||
import { Zone } from '../util/Zone';
|
import { Zone } from '../util/Zone';
|
||||||
|
import * as durations from '../util/durations';
|
||||||
import { DurationInSeconds, SECOND } from '../util/durations';
|
import { DurationInSeconds, SECOND } from '../util/durations';
|
||||||
import type { AttachmentType } from '../types/Attachment';
|
import type { AttachmentType } from '../types/Attachment';
|
||||||
import { Address } from '../types/Address';
|
import { Address } from '../types/Address';
|
||||||
|
@ -55,13 +56,13 @@ import { QualifiedAddress } from '../types/QualifiedAddress';
|
||||||
import { normalizeStoryDistributionId } from '../types/StoryDistributionId';
|
import { normalizeStoryDistributionId } from '../types/StoryDistributionId';
|
||||||
import type { ServiceIdString } from '../types/ServiceId';
|
import type { ServiceIdString } from '../types/ServiceId';
|
||||||
import {
|
import {
|
||||||
ServiceIdKind,
|
|
||||||
normalizeServiceId,
|
|
||||||
normalizePni,
|
|
||||||
isPniString,
|
|
||||||
isUntaggedPniString,
|
|
||||||
isServiceIdString,
|
|
||||||
fromPniObject,
|
fromPniObject,
|
||||||
|
isPniString,
|
||||||
|
isServiceIdString,
|
||||||
|
isUntaggedPniString,
|
||||||
|
normalizePni,
|
||||||
|
normalizeServiceId,
|
||||||
|
ServiceIdKind,
|
||||||
toTaggedPni,
|
toTaggedPni,
|
||||||
} from '../types/ServiceId';
|
} from '../types/ServiceId';
|
||||||
import { normalizeAci } from '../util/normalizeAci';
|
import { normalizeAci } from '../util/normalizeAci';
|
||||||
|
@ -75,70 +76,70 @@ import createTaskWithTimeout from './TaskWithTimeout';
|
||||||
import {
|
import {
|
||||||
processAttachment,
|
processAttachment,
|
||||||
processDataMessage,
|
processDataMessage,
|
||||||
processPreview,
|
|
||||||
processGroupV2Context,
|
processGroupV2Context,
|
||||||
|
processPreview,
|
||||||
} from './processDataMessage';
|
} from './processDataMessage';
|
||||||
import { processSyncMessage } from './processSyncMessage';
|
import { processSyncMessage } from './processSyncMessage';
|
||||||
import type { EventHandler } from './EventTarget';
|
import type { EventHandler } from './EventTarget';
|
||||||
import EventTarget from './EventTarget';
|
import EventTarget from './EventTarget';
|
||||||
import { downloadAttachment } from './downloadAttachment';
|
import { downloadAttachment } from './downloadAttachment';
|
||||||
import type { IncomingWebSocketRequest } from './WebsocketResources';
|
import type { IncomingWebSocketRequest } from './WebsocketResources';
|
||||||
|
import { ServerRequestType } from './WebsocketResources';
|
||||||
import { parseContactsV2 } from './ContactsParser';
|
import { parseContactsV2 } from './ContactsParser';
|
||||||
import type { WebAPIType } from './WebAPI';
|
import type { WebAPIType } from './WebAPI';
|
||||||
import type { Storage } from './Storage';
|
import type { Storage } from './Storage';
|
||||||
import { WarnOnlyError } from './Errors';
|
import { WarnOnlyError } from './Errors';
|
||||||
import * as Bytes from '../Bytes';
|
import * as Bytes from '../Bytes';
|
||||||
import type {
|
import type {
|
||||||
|
IRequestHandler,
|
||||||
ProcessedAttachment,
|
ProcessedAttachment,
|
||||||
ProcessedDataMessage,
|
ProcessedDataMessage,
|
||||||
ProcessedPreview,
|
|
||||||
ProcessedSyncMessage,
|
|
||||||
ProcessedSent,
|
|
||||||
ProcessedEnvelope,
|
ProcessedEnvelope,
|
||||||
IRequestHandler,
|
ProcessedPreview,
|
||||||
|
ProcessedSent,
|
||||||
|
ProcessedSyncMessage,
|
||||||
UnprocessedType,
|
UnprocessedType,
|
||||||
} from './Types.d';
|
} from './Types.d';
|
||||||
|
import type {
|
||||||
|
ConversationToDelete,
|
||||||
|
DeleteForMeSyncEventData,
|
||||||
|
DeleteForMeSyncTarget,
|
||||||
|
MessageToDelete,
|
||||||
|
ReadSyncEventData,
|
||||||
|
ViewSyncEventData,
|
||||||
|
} from './messageReceiverEvents';
|
||||||
import {
|
import {
|
||||||
CallEventSyncEvent,
|
CallEventSyncEvent,
|
||||||
|
CallLinkUpdateSyncEvent,
|
||||||
|
CallLogEventSyncEvent,
|
||||||
|
ConfigurationEvent,
|
||||||
|
ContactSyncEvent,
|
||||||
|
DecryptionErrorEvent,
|
||||||
|
DeleteForMeSyncEvent,
|
||||||
|
DeliveryEvent,
|
||||||
EmptyEvent,
|
EmptyEvent,
|
||||||
EnvelopeQueuedEvent,
|
EnvelopeQueuedEvent,
|
||||||
EnvelopeUnsealedEvent,
|
EnvelopeUnsealedEvent,
|
||||||
ProgressEvent,
|
|
||||||
TypingEvent,
|
|
||||||
ErrorEvent,
|
ErrorEvent,
|
||||||
DeliveryEvent,
|
|
||||||
DecryptionErrorEvent,
|
|
||||||
SentEvent,
|
|
||||||
ProfileKeyUpdateEvent,
|
|
||||||
InvalidPlaintextEvent,
|
|
||||||
MessageEvent,
|
|
||||||
RetryRequestEvent,
|
|
||||||
ReadEvent,
|
|
||||||
ViewEvent,
|
|
||||||
ConfigurationEvent,
|
|
||||||
ViewOnceOpenSyncEvent,
|
|
||||||
MessageRequestResponseEvent,
|
|
||||||
FetchLatestEvent,
|
FetchLatestEvent,
|
||||||
|
InvalidPlaintextEvent,
|
||||||
KeysEvent,
|
KeysEvent,
|
||||||
StickerPackEvent,
|
MessageEvent,
|
||||||
|
MessageRequestResponseEvent,
|
||||||
|
ProfileKeyUpdateEvent,
|
||||||
|
ProgressEvent,
|
||||||
|
ReadEvent,
|
||||||
ReadSyncEvent,
|
ReadSyncEvent,
|
||||||
ViewSyncEvent,
|
RetryRequestEvent,
|
||||||
ContactSyncEvent,
|
SentEvent,
|
||||||
|
StickerPackEvent,
|
||||||
StoryRecipientUpdateEvent,
|
StoryRecipientUpdateEvent,
|
||||||
CallLogEventSyncEvent,
|
TypingEvent,
|
||||||
CallLinkUpdateSyncEvent,
|
ViewEvent,
|
||||||
DeleteForMeSyncEvent,
|
ViewOnceOpenSyncEvent,
|
||||||
} from './messageReceiverEvents';
|
ViewSyncEvent,
|
||||||
import type {
|
|
||||||
MessageToDelete,
|
|
||||||
DeleteForMeSyncEventData,
|
|
||||||
DeleteForMeSyncTarget,
|
|
||||||
ConversationToDelete,
|
|
||||||
ViewSyncEventData,
|
|
||||||
ReadSyncEventData,
|
|
||||||
} from './messageReceiverEvents';
|
} from './messageReceiverEvents';
|
||||||
import * as log from '../logging/log';
|
import * as log from '../logging/log';
|
||||||
import * as durations from '../util/durations';
|
|
||||||
import { areArraysMatchingSets } from '../util/areArraysMatchingSets';
|
import { areArraysMatchingSets } from '../util/areArraysMatchingSets';
|
||||||
import { generateBlurHash } from '../util/generateBlurHash';
|
import { generateBlurHash } from '../util/generateBlurHash';
|
||||||
import { TEXT_ATTACHMENT } from '../types/MIME';
|
import { TEXT_ATTACHMENT } from '../types/MIME';
|
||||||
|
@ -385,11 +386,11 @@ export default class MessageReceiver
|
||||||
public handleRequest(request: IncomingWebSocketRequest): void {
|
public handleRequest(request: IncomingWebSocketRequest): void {
|
||||||
// We do the message decryption here, instead of in the ordered pending queue,
|
// We do the message decryption here, instead of in the ordered pending queue,
|
||||||
// to avoid exposing the time it took us to process messages through the time-to-ack.
|
// to avoid exposing the time it took us to process messages through the time-to-ack.
|
||||||
log.info('MessageReceiver: got request', request.verb, request.path);
|
log.info('MessageReceiver: got request', request.requestType);
|
||||||
if (request.path !== '/api/v1/message') {
|
if (request.requestType !== ServerRequestType.ApiMessage) {
|
||||||
request.respond(200, 'OK');
|
request.respond(200, 'OK');
|
||||||
|
|
||||||
if (request.verb === 'PUT' && request.path === '/api/v1/queue/empty') {
|
if (request.requestType === ServerRequestType.ApiEmptyQueue) {
|
||||||
drop(
|
drop(
|
||||||
this.incomingQueue.add(
|
this.incomingQueue.add(
|
||||||
createTaskWithTimeout(
|
createTaskWithTimeout(
|
||||||
|
@ -406,8 +407,6 @@ export default class MessageReceiver
|
||||||
}
|
}
|
||||||
|
|
||||||
const job = async () => {
|
const job = async () => {
|
||||||
const headers = request.headers || [];
|
|
||||||
|
|
||||||
if (!request.body) {
|
if (!request.body) {
|
||||||
throw new Error(
|
throw new Error(
|
||||||
'MessageReceiver.handleRequest: request.body was falsey!'
|
'MessageReceiver.handleRequest: request.body was falsey!'
|
||||||
|
@ -429,7 +428,10 @@ export default class MessageReceiver
|
||||||
receivedAtCounter: incrementMessageCounter(),
|
receivedAtCounter: incrementMessageCounter(),
|
||||||
receivedAtDate: Date.now(),
|
receivedAtDate: Date.now(),
|
||||||
// Calculate the message age (time on server).
|
// Calculate the message age (time on server).
|
||||||
messageAgeSec: this.calculateMessageAge(headers, serverTimestamp),
|
messageAgeSec: this.calculateMessageAge(
|
||||||
|
request.timestamp,
|
||||||
|
serverTimestamp
|
||||||
|
),
|
||||||
|
|
||||||
// Proto.Envelope fields
|
// Proto.Envelope fields
|
||||||
type: decoded.type ?? Proto.Envelope.Type.UNKNOWN,
|
type: decoded.type ?? Proto.Envelope.Type.UNKNOWN,
|
||||||
|
@ -728,32 +730,15 @@ export default class MessageReceiver
|
||||||
}
|
}
|
||||||
|
|
||||||
private calculateMessageAge(
|
private calculateMessageAge(
|
||||||
headers: ReadonlyArray<string>,
|
timestamp: number | undefined,
|
||||||
serverTimestamp?: number
|
serverTimestamp: number | undefined
|
||||||
): number {
|
): number {
|
||||||
let messageAgeSec = 0; // Default to 0 in case of unreliable parameters.
|
// Default to 0 in case of unreliable parameters.
|
||||||
|
// One final sanity check, the timestamp when a message is pulled from
|
||||||
if (serverTimestamp) {
|
// the server should be later than when it was pushed.
|
||||||
// The 'X-Signal-Timestamp' is usually the last item, so start there.
|
return serverTimestamp && timestamp && timestamp > serverTimestamp
|
||||||
let it = headers.length;
|
? Math.floor((timestamp - serverTimestamp) / 1000)
|
||||||
// eslint-disable-next-line no-plusplus
|
: 0;
|
||||||
while (--it >= 0) {
|
|
||||||
const match = headers[it].match(/^X-Signal-Timestamp:\s*(\d+)\s*$/i);
|
|
||||||
if (match && match.length === 2) {
|
|
||||||
const timestamp = Number(match[1]);
|
|
||||||
|
|
||||||
// One final sanity check, the timestamp when a message is pulled from
|
|
||||||
// the server should be later than when it was pushed.
|
|
||||||
if (timestamp > serverTimestamp) {
|
|
||||||
messageAgeSec = Math.floor((timestamp - serverTimestamp) / 1000);
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return messageAgeSec;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private async addToQueue<T>(
|
private async addToQueue<T>(
|
||||||
|
|
|
@ -13,14 +13,14 @@ import { AbortableProcess } from '../util/AbortableProcess';
|
||||||
import { strictAssert } from '../util/assert';
|
import { strictAssert } from '../util/assert';
|
||||||
import {
|
import {
|
||||||
BackOff,
|
BackOff,
|
||||||
FIBONACCI_TIMEOUTS,
|
|
||||||
EXTENDED_FIBONACCI_TIMEOUTS,
|
EXTENDED_FIBONACCI_TIMEOUTS,
|
||||||
|
FIBONACCI_TIMEOUTS,
|
||||||
} from '../util/BackOff';
|
} from '../util/BackOff';
|
||||||
import * as durations from '../util/durations';
|
import * as durations from '../util/durations';
|
||||||
import { sleep } from '../util/sleep';
|
import { sleep } from '../util/sleep';
|
||||||
import { drop } from '../util/drop';
|
import { drop } from '../util/drop';
|
||||||
import { createProxyAgent } from '../util/createProxyAgent';
|
|
||||||
import type { ProxyAgent } from '../util/createProxyAgent';
|
import type { ProxyAgent } from '../util/createProxyAgent';
|
||||||
|
import { createProxyAgent } from '../util/createProxyAgent';
|
||||||
import { SocketStatus } from '../types/SocketStatus';
|
import { SocketStatus } from '../types/SocketStatus';
|
||||||
import * as Errors from '../types/errors';
|
import * as Errors from '../types/errors';
|
||||||
import * as Bytes from '../Bytes';
|
import * as Bytes from '../Bytes';
|
||||||
|
@ -32,7 +32,8 @@ import type {
|
||||||
WebSocketResourceOptions,
|
WebSocketResourceOptions,
|
||||||
} from './WebsocketResources';
|
} from './WebsocketResources';
|
||||||
import WebSocketResource, {
|
import WebSocketResource, {
|
||||||
LibsignalWebSocketResource,
|
connectAuthenticatedLibsignal,
|
||||||
|
connectUnauthenticatedLibsignal,
|
||||||
TransportOption,
|
TransportOption,
|
||||||
WebSocketResourceWithShadowing,
|
WebSocketResourceWithShadowing,
|
||||||
} from './WebsocketResources';
|
} from './WebsocketResources';
|
||||||
|
@ -166,22 +167,38 @@ export class SocketManager extends EventListener {
|
||||||
|
|
||||||
this.setStatus(SocketStatus.CONNECTING);
|
this.setStatus(SocketStatus.CONNECTING);
|
||||||
|
|
||||||
const process = this.connectResource({
|
const proxyAgent = await this.getProxyAgent();
|
||||||
name: AUTHENTICATED_CHANNEL_NAME,
|
const useLibsignalTransport =
|
||||||
path: '/v1/websocket/',
|
window.Signal.RemoteConfig.isEnabled(
|
||||||
query: { login: username, password },
|
'desktop.experimentalTransport.enableAuth'
|
||||||
proxyAgent: await this.getProxyAgent(),
|
) && this.transportOption(proxyAgent) === TransportOption.Libsignal;
|
||||||
resourceOptions: {
|
|
||||||
name: AUTHENTICATED_CHANNEL_NAME,
|
const process = useLibsignalTransport
|
||||||
keepalive: { path: '/v1/keepalive' },
|
? connectAuthenticatedLibsignal({
|
||||||
handleRequest: (req: IncomingWebSocketRequest): void => {
|
libsignalNet: this.libsignalNet,
|
||||||
this.queueOrHandleRequest(req);
|
name: AUTHENTICATED_CHANNEL_NAME,
|
||||||
},
|
credentials: this.credentials,
|
||||||
},
|
handler: (req: IncomingWebSocketRequest): void => {
|
||||||
extraHeaders: {
|
this.queueOrHandleRequest(req);
|
||||||
'X-Signal-Receive-Stories': String(!this.hasStoriesDisabled),
|
},
|
||||||
},
|
receiveStories: !this.hasStoriesDisabled,
|
||||||
});
|
})
|
||||||
|
: this.connectResource({
|
||||||
|
name: AUTHENTICATED_CHANNEL_NAME,
|
||||||
|
path: '/v1/websocket/',
|
||||||
|
query: { login: username, password },
|
||||||
|
resourceOptions: {
|
||||||
|
name: AUTHENTICATED_CHANNEL_NAME,
|
||||||
|
keepalive: { path: '/v1/keepalive' },
|
||||||
|
handleRequest: (req: IncomingWebSocketRequest): void => {
|
||||||
|
this.queueOrHandleRequest(req);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
extraHeaders: {
|
||||||
|
'X-Signal-Receive-Stories': String(!this.hasStoriesDisabled),
|
||||||
|
},
|
||||||
|
proxyAgent,
|
||||||
|
});
|
||||||
|
|
||||||
// Cancel previous connect attempt or close socket
|
// Cancel previous connect attempt or close socket
|
||||||
this.authenticated?.abort();
|
this.authenticated?.abort();
|
||||||
|
@ -575,10 +592,10 @@ export class SocketManager extends EventListener {
|
||||||
}
|
}
|
||||||
|
|
||||||
private connectLibsignalUnauthenticated(): AbortableProcess<IWebSocketResource> {
|
private connectLibsignalUnauthenticated(): AbortableProcess<IWebSocketResource> {
|
||||||
return LibsignalWebSocketResource.connect(
|
return connectUnauthenticatedLibsignal({
|
||||||
this.libsignalNet,
|
libsignalNet: this.libsignalNet,
|
||||||
UNAUTHENTICATED_CHANNEL_NAME
|
name: UNAUTHENTICATED_CHANNEL_NAME,
|
||||||
);
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private async getUnauthenticatedResource(): Promise<IWebSocketResource> {
|
private async getUnauthenticatedResource(): Promise<IWebSocketResource> {
|
||||||
|
@ -724,10 +741,10 @@ export class SocketManager extends EventListener {
|
||||||
options: WebSocketResourceOptions
|
options: WebSocketResourceOptions
|
||||||
): AbortableProcess<IWebSocketResource> {
|
): AbortableProcess<IWebSocketResource> {
|
||||||
// creating an `AbortableProcess` of libsignal websocket connection
|
// creating an `AbortableProcess` of libsignal websocket connection
|
||||||
const shadowingConnection = LibsignalWebSocketResource.connect(
|
const shadowingConnection = connectUnauthenticatedLibsignal({
|
||||||
this.libsignalNet,
|
libsignalNet: this.libsignalNet,
|
||||||
options.name
|
name: options.name,
|
||||||
);
|
});
|
||||||
const shadowWrapper = async () => {
|
const shadowWrapper = async () => {
|
||||||
// if main connection results in an error,
|
// if main connection results in an error,
|
||||||
// it's propagated as the error of the resulting process
|
// it's propagated as the error of the resulting process
|
||||||
|
|
|
@ -37,6 +37,8 @@ import { random } from 'lodash';
|
||||||
import type { ChatServiceDebugInfo } from '@signalapp/libsignal-client/Native';
|
import type { ChatServiceDebugInfo } from '@signalapp/libsignal-client/Native';
|
||||||
|
|
||||||
import type { Net } from '@signalapp/libsignal-client';
|
import type { Net } from '@signalapp/libsignal-client';
|
||||||
|
import { Buffer } from 'node:buffer';
|
||||||
|
import type { ChatServerMessageAck } from '@signalapp/libsignal-client/dist/net';
|
||||||
import type { EventHandler } from './EventTarget';
|
import type { EventHandler } from './EventTarget';
|
||||||
import EventTarget from './EventTarget';
|
import EventTarget from './EventTarget';
|
||||||
|
|
||||||
|
@ -54,6 +56,7 @@ import { isProduction } from '../util/version';
|
||||||
|
|
||||||
import { ToastType } from '../types/Toast';
|
import { ToastType } from '../types/Toast';
|
||||||
import { AbortableProcess } from '../util/AbortableProcess';
|
import { AbortableProcess } from '../util/AbortableProcess';
|
||||||
|
import type { WebAPICredentials } from './Types';
|
||||||
|
|
||||||
const THIRTY_SECONDS = 30 * durations.SECOND;
|
const THIRTY_SECONDS = 30 * durations.SECOND;
|
||||||
|
|
||||||
|
@ -166,16 +169,49 @@ export namespace AggregatedStats {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export class IncomingWebSocketRequest {
|
export enum ServerRequestType {
|
||||||
|
ApiMessage = '/api/v1/message',
|
||||||
|
ApiEmptyQueue = '/api/v1/queue/empty',
|
||||||
|
ProvisioningMessage = '/v1/message',
|
||||||
|
ProvisioningAddress = '/v1/address',
|
||||||
|
Unknown = 'unknown',
|
||||||
|
}
|
||||||
|
|
||||||
|
export type IncomingWebSocketRequest = {
|
||||||
|
readonly requestType: ServerRequestType;
|
||||||
|
readonly body: Uint8Array | undefined;
|
||||||
|
readonly timestamp: number | undefined;
|
||||||
|
|
||||||
|
respond(status: number, message: string): void;
|
||||||
|
};
|
||||||
|
|
||||||
|
export class IncomingWebSocketRequestLibsignal
|
||||||
|
implements IncomingWebSocketRequest
|
||||||
|
{
|
||||||
|
constructor(
|
||||||
|
readonly requestType: ServerRequestType,
|
||||||
|
readonly body: Uint8Array | undefined,
|
||||||
|
readonly timestamp: number | undefined,
|
||||||
|
private readonly ack: ChatServerMessageAck | undefined
|
||||||
|
) {}
|
||||||
|
|
||||||
|
respond(status: number, _message: string): void {
|
||||||
|
if (this.ack) {
|
||||||
|
drop(this.ack.send(status));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class IncomingWebSocketRequestLegacy
|
||||||
|
implements IncomingWebSocketRequest
|
||||||
|
{
|
||||||
private readonly id: Long;
|
private readonly id: Long;
|
||||||
|
|
||||||
public readonly verb: string;
|
public readonly requestType: ServerRequestType;
|
||||||
|
|
||||||
public readonly path: string;
|
|
||||||
|
|
||||||
public readonly body: Uint8Array | undefined;
|
public readonly body: Uint8Array | undefined;
|
||||||
|
|
||||||
public readonly headers: ReadonlyArray<string>;
|
public readonly timestamp: number | undefined;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
request: Proto.IWebSocketRequestMessage,
|
request: Proto.IWebSocketRequestMessage,
|
||||||
|
@ -186,10 +222,9 @@ export class IncomingWebSocketRequest {
|
||||||
strictAssert(request.path, 'request without path');
|
strictAssert(request.path, 'request without path');
|
||||||
|
|
||||||
this.id = request.id;
|
this.id = request.id;
|
||||||
this.verb = request.verb;
|
this.requestType = resolveType(request.path, request.verb);
|
||||||
this.path = request.path;
|
|
||||||
this.body = dropNull(request.body);
|
this.body = dropNull(request.body);
|
||||||
this.headers = request.headers || [];
|
this.timestamp = resolveTimestamp(request.headers || []);
|
||||||
}
|
}
|
||||||
|
|
||||||
public respond(status: number, message: string): void {
|
public respond(status: number, message: string): void {
|
||||||
|
@ -202,6 +237,35 @@ export class IncomingWebSocketRequest {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function resolveType(path: string, verb: string): ServerRequestType {
|
||||||
|
if (path === ServerRequestType.ApiMessage) {
|
||||||
|
return ServerRequestType.ApiMessage;
|
||||||
|
}
|
||||||
|
if (path === ServerRequestType.ApiEmptyQueue && verb === 'PUT') {
|
||||||
|
return ServerRequestType.ApiEmptyQueue;
|
||||||
|
}
|
||||||
|
if (path === ServerRequestType.ProvisioningAddress && verb === 'PUT') {
|
||||||
|
return ServerRequestType.ProvisioningAddress;
|
||||||
|
}
|
||||||
|
if (path === ServerRequestType.ProvisioningMessage && verb === 'PUT') {
|
||||||
|
return ServerRequestType.ProvisioningMessage;
|
||||||
|
}
|
||||||
|
return ServerRequestType.Unknown;
|
||||||
|
}
|
||||||
|
|
||||||
|
function resolveTimestamp(headers: ReadonlyArray<string>): number | undefined {
|
||||||
|
// The 'X-Signal-Timestamp' is usually the last item, so start there.
|
||||||
|
let it = headers.length;
|
||||||
|
// eslint-disable-next-line no-plusplus
|
||||||
|
while (--it >= 0) {
|
||||||
|
const match = headers[it].match(/^X-Signal-Timestamp:\s*(\d+)\s*$/i);
|
||||||
|
if (match && match.length === 2) {
|
||||||
|
return Number(match[1]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
export type SendRequestOptions = Readonly<{
|
export type SendRequestOptions = Readonly<{
|
||||||
verb: string;
|
verb: string;
|
||||||
path: string;
|
path: string;
|
||||||
|
@ -266,6 +330,100 @@ export interface IWebSocketResource extends IResource {
|
||||||
localPort(): number | undefined;
|
localPort(): number | undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function connectUnauthenticatedLibsignal({
|
||||||
|
libsignalNet,
|
||||||
|
name,
|
||||||
|
}: {
|
||||||
|
libsignalNet: Net.Net;
|
||||||
|
name: string;
|
||||||
|
}): AbortableProcess<LibsignalWebSocketResource> {
|
||||||
|
return connectLibsignal(libsignalNet.newUnauthenticatedChatService(), name);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function connectAuthenticatedLibsignal({
|
||||||
|
libsignalNet,
|
||||||
|
name,
|
||||||
|
credentials,
|
||||||
|
handler,
|
||||||
|
receiveStories,
|
||||||
|
}: {
|
||||||
|
libsignalNet: Net.Net;
|
||||||
|
name: string;
|
||||||
|
credentials: WebAPICredentials;
|
||||||
|
handler: (request: IncomingWebSocketRequest) => void;
|
||||||
|
receiveStories: boolean;
|
||||||
|
}): AbortableProcess<LibsignalWebSocketResource> {
|
||||||
|
const listener = {
|
||||||
|
onIncomingMessage(
|
||||||
|
envelope: Buffer,
|
||||||
|
timestamp: number,
|
||||||
|
ack: ChatServerMessageAck
|
||||||
|
): void {
|
||||||
|
const request = new IncomingWebSocketRequestLibsignal(
|
||||||
|
ServerRequestType.ApiMessage,
|
||||||
|
envelope,
|
||||||
|
timestamp,
|
||||||
|
ack
|
||||||
|
);
|
||||||
|
handler(request);
|
||||||
|
},
|
||||||
|
onQueueEmpty(): void {
|
||||||
|
const request = new IncomingWebSocketRequestLibsignal(
|
||||||
|
ServerRequestType.ApiEmptyQueue,
|
||||||
|
undefined,
|
||||||
|
undefined,
|
||||||
|
undefined
|
||||||
|
);
|
||||||
|
handler(request);
|
||||||
|
},
|
||||||
|
onConnectionInterrupted(): void {
|
||||||
|
log.warn(`LibsignalWebSocketResource(${name}): connection interrupted`);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
return connectLibsignal(
|
||||||
|
libsignalNet.newAuthenticatedChatService(
|
||||||
|
credentials.username,
|
||||||
|
credentials.password,
|
||||||
|
receiveStories,
|
||||||
|
listener
|
||||||
|
),
|
||||||
|
name
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function connectLibsignal(
|
||||||
|
chatService: Net.ChatService,
|
||||||
|
name: string
|
||||||
|
): AbortableProcess<LibsignalWebSocketResource> {
|
||||||
|
const connectAsync = async () => {
|
||||||
|
try {
|
||||||
|
const debugInfo = await chatService.connect();
|
||||||
|
log.info(`LibsignalWebSocketResource(${name}) connected`, debugInfo);
|
||||||
|
return new LibsignalWebSocketResource(
|
||||||
|
chatService,
|
||||||
|
IpVersion.fromDebugInfoCode(debugInfo.ipType)
|
||||||
|
);
|
||||||
|
} catch (error) {
|
||||||
|
// Handle any errors that occur during connection
|
||||||
|
log.error(
|
||||||
|
`LibsignalWebSocketResource(${name}) connection failed`,
|
||||||
|
Errors.toLogFormat(error)
|
||||||
|
);
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
return new AbortableProcess<LibsignalWebSocketResource>(
|
||||||
|
`LibsignalWebSocketResource.connect(${name})`,
|
||||||
|
{
|
||||||
|
abort() {
|
||||||
|
// if interrupted, trying to disconnect
|
||||||
|
drop(chatService.disconnect());
|
||||||
|
},
|
||||||
|
},
|
||||||
|
connectAsync()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
export class LibsignalWebSocketResource
|
export class LibsignalWebSocketResource
|
||||||
extends EventTarget
|
extends EventTarget
|
||||||
implements IWebSocketResource
|
implements IWebSocketResource
|
||||||
|
@ -277,40 +435,6 @@ export class LibsignalWebSocketResource
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static connect(
|
|
||||||
libsignalNet: Net.Net,
|
|
||||||
name: string
|
|
||||||
): AbortableProcess<LibsignalWebSocketResource> {
|
|
||||||
const chatService = libsignalNet.newChatService();
|
|
||||||
const connectAsync = async () => {
|
|
||||||
try {
|
|
||||||
const debugInfo = await chatService.connectUnauthenticated();
|
|
||||||
log.info(`LibsignalWebSocketResource(${name}) connected`, debugInfo);
|
|
||||||
return new LibsignalWebSocketResource(
|
|
||||||
chatService,
|
|
||||||
IpVersion.fromDebugInfoCode(debugInfo.ipType)
|
|
||||||
);
|
|
||||||
} catch (error) {
|
|
||||||
// Handle any errors that occur during connection
|
|
||||||
log.error(
|
|
||||||
`LibsignalWebSocketResource(${name}) connection failed`,
|
|
||||||
Errors.toLogFormat(error)
|
|
||||||
);
|
|
||||||
throw error;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
return new AbortableProcess<LibsignalWebSocketResource>(
|
|
||||||
`LibsignalWebSocketResource.connect(${name})`,
|
|
||||||
{
|
|
||||||
abort() {
|
|
||||||
// if interrupted, trying to disconnect
|
|
||||||
drop(chatService.disconnect());
|
|
||||||
},
|
|
||||||
},
|
|
||||||
connectAsync()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
public localPort(): number | undefined {
|
public localPort(): number | undefined {
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
@ -348,14 +472,13 @@ export class LibsignalWebSocketResource
|
||||||
public async sendRequestGetDebugInfo(
|
public async sendRequestGetDebugInfo(
|
||||||
options: SendRequestOptions
|
options: SendRequestOptions
|
||||||
): Promise<[Response, ChatServiceDebugInfo]> {
|
): Promise<[Response, ChatServiceDebugInfo]> {
|
||||||
const { response, debugInfo } =
|
const { response, debugInfo } = await this.chatService.fetchAndDebug({
|
||||||
await this.chatService.unauthenticatedFetchAndDebug({
|
verb: options.verb,
|
||||||
verb: options.verb,
|
path: options.path,
|
||||||
path: options.path,
|
headers: options.headers ? options.headers : [],
|
||||||
headers: options.headers ? options.headers : [],
|
body: options.body,
|
||||||
body: options.body,
|
timeoutMillis: options.timeout,
|
||||||
timeoutMillis: options.timeout,
|
});
|
||||||
});
|
|
||||||
return [
|
return [
|
||||||
new Response(response.body, {
|
new Response(response.body, {
|
||||||
status: response.status,
|
status: response.status,
|
||||||
|
@ -765,7 +888,7 @@ export default class WebSocketResource
|
||||||
this.options.handleRequest ||
|
this.options.handleRequest ||
|
||||||
(request => request.respond(404, 'Not found'));
|
(request => request.respond(404, 'Not found'));
|
||||||
|
|
||||||
const incomingRequest = new IncomingWebSocketRequest(
|
const incomingRequest = new IncomingWebSocketRequestLegacy(
|
||||||
message.request,
|
message.request,
|
||||||
(bytes: Buffer): void => {
|
(bytes: Buffer): void => {
|
||||||
this.removeActive(incomingRequest);
|
this.removeActive(incomingRequest);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue