mirror of
https://github.com/LemmyNet/lemmy.git
synced 2024-11-22 20:31:19 +00:00
* Federated mentions. Fixes #681 * Changing some todos, adding comments.
This commit is contained in:
parent
3a4973ad68
commit
940dc73f28
19 changed files with 660 additions and 452 deletions
352
server/Cargo.lock
generated
vendored
352
server/Cargo.lock
generated
vendored
|
@ -2,24 +2,24 @@
|
||||||
# It is not intended for manual editing.
|
# It is not intended for manual editing.
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "activitystreams"
|
name = "activitystreams"
|
||||||
version = "0.6.0"
|
version = "0.6.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "dd5b29a0f2c64cc56f2b79ec29cab68a9dab3b714d811a55668d072f18a8638e"
|
checksum = "edf0082191df1d6d39577b28b5daa7b8318b812038d0f7a83f05331f17580934"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"activitystreams-derive",
|
"activitystreams-derive",
|
||||||
"chrono",
|
"chrono",
|
||||||
"mime",
|
"mime",
|
||||||
"serde 1.0.106",
|
"serde 1.0.110",
|
||||||
"serde_json 1.0.51",
|
"serde_json 1.0.53",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
"url",
|
"url",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "activitystreams-derive"
|
name = "activitystreams-derive"
|
||||||
version = "0.6.0"
|
version = "0.6.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "985d3ca1ee226e83f4118e0235bc11d9fce39c4eec8d53739a21b01dd0b3f30f"
|
checksum = "c39ba5929399e9f921055bac76dd8f47419fa5b6b6da1ac4c1e82b94ed0ac7b4"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
|
@ -144,8 +144,8 @@ dependencies = [
|
||||||
"pin-project",
|
"pin-project",
|
||||||
"rand 0.7.3",
|
"rand 0.7.3",
|
||||||
"regex 1.3.7",
|
"regex 1.3.7",
|
||||||
"serde 1.0.106",
|
"serde 1.0.110",
|
||||||
"serde_json 1.0.51",
|
"serde_json 1.0.53",
|
||||||
"serde_urlencoded",
|
"serde_urlencoded",
|
||||||
"sha1",
|
"sha1",
|
||||||
"slab",
|
"slab",
|
||||||
|
@ -172,20 +172,21 @@ dependencies = [
|
||||||
"http",
|
"http",
|
||||||
"log",
|
"log",
|
||||||
"regex 1.3.7",
|
"regex 1.3.7",
|
||||||
"serde 1.0.106",
|
"serde 1.0.110",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "actix-rt"
|
name = "actix-rt"
|
||||||
version = "1.1.0"
|
version = "1.1.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "20066d9200ef8d441ac156c76dd36c3f1e9a15976c34e69ae97f7f570b331882"
|
checksum = "143fcc2912e0d1de2bcf4e2f720d2a60c28652ab4179685a1ee159e0fb3db227"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"actix-macros",
|
"actix-macros",
|
||||||
"actix-threadpool",
|
"actix-threadpool",
|
||||||
"copyless",
|
"copyless",
|
||||||
"futures-channel",
|
"futures-channel",
|
||||||
"futures-util",
|
"futures-util",
|
||||||
|
"smallvec",
|
||||||
"tokio",
|
"tokio",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -311,8 +312,8 @@ dependencies = [
|
||||||
"net2",
|
"net2",
|
||||||
"pin-project",
|
"pin-project",
|
||||||
"regex 1.3.7",
|
"regex 1.3.7",
|
||||||
"serde 1.0.106",
|
"serde 1.0.110",
|
||||||
"serde_json 1.0.51",
|
"serde_json 1.0.53",
|
||||||
"serde_urlencoded",
|
"serde_urlencoded",
|
||||||
"time",
|
"time",
|
||||||
"url",
|
"url",
|
||||||
|
@ -355,6 +356,15 @@ dependencies = [
|
||||||
"syn",
|
"syn",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "addr2line"
|
||||||
|
version = "0.12.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "456d75cbb82da1ad150c8a9d97285ffcd21c9931dcb11e995903e7d75141b38b"
|
||||||
|
dependencies = [
|
||||||
|
"gimli",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "adler32"
|
name = "adler32"
|
||||||
version = "1.0.4"
|
version = "1.0.4"
|
||||||
|
@ -411,9 +421,9 @@ checksum = "71938f30533e4d95a6d17aa530939da3842c2ab6f4f84b9dae68447e4129f74a"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "async-trait"
|
name = "async-trait"
|
||||||
version = "0.1.30"
|
version = "0.1.31"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "da71fef07bc806586090247e971229289f64c210a278ee5ae419314eb386b31d"
|
checksum = "26c4f3195085c36ea8d24d32b2f828d23296a9370a28aa39d111f6f16bef9f3b"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
|
@ -461,33 +471,24 @@ dependencies = [
|
||||||
"mime",
|
"mime",
|
||||||
"percent-encoding",
|
"percent-encoding",
|
||||||
"rand 0.7.3",
|
"rand 0.7.3",
|
||||||
"serde 1.0.106",
|
"serde 1.0.110",
|
||||||
"serde_json 1.0.51",
|
"serde_json 1.0.53",
|
||||||
"serde_urlencoded",
|
"serde_urlencoded",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "backtrace"
|
name = "backtrace"
|
||||||
version = "0.3.46"
|
version = "0.3.48"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b1e692897359247cc6bb902933361652380af0f1b7651ae5c5013407f30e109e"
|
checksum = "0df2f85c8a2abbe3b7d7e748052fdd9b76a0458fdeb16ad4223f5eca78c7c130"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"backtrace-sys",
|
"addr2line",
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
"libc",
|
"libc",
|
||||||
|
"object",
|
||||||
"rustc-demangle",
|
"rustc-demangle",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "backtrace-sys"
|
|
||||||
version = "0.1.36"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "78848718ee1255a2485d1309ad9cdecfc2e7d0362dd11c6829364c6b35ae1bc7"
|
|
||||||
dependencies = [
|
|
||||||
"cc",
|
|
||||||
"libc",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "base64"
|
name = "base64"
|
||||||
version = "0.9.3"
|
version = "0.9.3"
|
||||||
|
@ -515,21 +516,20 @@ checksum = "b41b7ea54a0c9d92199de89e20e58d49f02f8e699814ef3fdf266f6f748d15c7"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "base64"
|
name = "base64"
|
||||||
version = "0.12.0"
|
version = "0.12.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "7d5ca2cd0adc3f48f9e9ea5a6bbdf9ccc0bfade884847e484d452414c7ccffb3"
|
checksum = "53d1ccbaf7d9ec9537465a97bf19edc1a4e158ecb49fc16178202238c569cc42"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bcrypt"
|
name = "bcrypt"
|
||||||
version = "0.6.3"
|
version = "0.8.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f055c8591efe08e03f534ee632672ea3643c3932e485f422107ec6cc1157b0ea"
|
checksum = "41b70db86f3c560199b0dada79a22b9a924622384abb2a756a9707ffcce077f2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"base64 0.12.0",
|
"base64 0.12.1",
|
||||||
"blowfish",
|
"blowfish",
|
||||||
"byteorder",
|
"byteorder",
|
||||||
"lazy_static 1.4.0",
|
"getrandom",
|
||||||
"rand 0.7.3",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -607,9 +607,9 @@ checksum = "40e38929add23cdf8a366df9b0e088953150724bcbe5fc330b0d8eb3b328eec8"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bumpalo"
|
name = "bumpalo"
|
||||||
version = "3.2.1"
|
version = "3.3.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "12ae9db68ad7fac5fe51304d20f016c911539251075a214f8e663babefa35187"
|
checksum = "5356f1d23ee24a1f785a56d1d1a5f0fd5b0f6a0c0fb2412ce11da71649ab78f6"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "byte-tools"
|
name = "byte-tools"
|
||||||
|
@ -640,9 +640,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cc"
|
name = "cc"
|
||||||
version = "1.0.52"
|
version = "1.0.53"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c3d87b23d6a92cd03af510a5ade527033f6aa6fa92161e2d5863a907d4c5e31d"
|
checksum = "404b1fe4f65288577753b17e3b36a04596ee784493ec249bf81c7f2d2acd751c"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cfg-if"
|
name = "cfg-if"
|
||||||
|
@ -658,15 +658,15 @@ checksum = "80094f509cf8b5ae86a4966a39b3ff66cd7e2a3e594accec3743ff3fabeab5b2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"num-integer",
|
"num-integer",
|
||||||
"num-traits 0.2.11",
|
"num-traits 0.2.11",
|
||||||
"serde 1.0.106",
|
"serde 1.0.110",
|
||||||
"time",
|
"time",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "clap"
|
name = "clap"
|
||||||
version = "2.33.0"
|
version = "2.33.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "5067f5bb2d80ef5d68b4c87db81601f0b75bca627bc2ef76b141d7b846a3c6d9"
|
checksum = "bdfa80d47f954d53a35a64987ca1422f495b8d6483c0fe9f7117b36c2a792129"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ansi_term",
|
"ansi_term",
|
||||||
"atty",
|
"atty",
|
||||||
|
@ -712,9 +712,9 @@ dependencies = [
|
||||||
"lazy_static 1.4.0",
|
"lazy_static 1.4.0",
|
||||||
"nom 5.1.1",
|
"nom 5.1.1",
|
||||||
"rust-ini",
|
"rust-ini",
|
||||||
"serde 1.0.106",
|
"serde 1.0.110",
|
||||||
"serde-hjson 0.9.1",
|
"serde-hjson 0.9.1",
|
||||||
"serde_json 1.0.51",
|
"serde_json 1.0.53",
|
||||||
"toml",
|
"toml",
|
||||||
"yaml-rust",
|
"yaml-rust",
|
||||||
]
|
]
|
||||||
|
@ -773,9 +773,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "curl"
|
name = "curl"
|
||||||
version = "0.4.28"
|
version = "0.4.29"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "eda1c0c03cacf3365d84818a40293f0e3f3953db8759c9c565a3b434edf0b52e"
|
checksum = "762e34611d2d5233a506a79072be944fddd057db2f18e04c0d6fa79e3fd466fd"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"curl-sys",
|
"curl-sys",
|
||||||
"libc",
|
"libc",
|
||||||
|
@ -788,9 +788,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "curl-sys"
|
name = "curl-sys"
|
||||||
version = "0.4.30+curl-7.69.1"
|
version = "0.4.31+curl-7.70.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "923b38e423a8f47a4058e96f2a1fa2865a6231097ee860debd678d244277d50c"
|
checksum = "dcd62757cc4f5ab9404bc6ca9f0ae447e729a1403948ce5106bd588ceac6a3b0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cc",
|
"cc",
|
||||||
"libc",
|
"libc",
|
||||||
|
@ -864,9 +864,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "derive_more"
|
name = "derive_more"
|
||||||
version = "0.99.5"
|
version = "0.99.6"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e2323f3f47db9a0e77ce7a300605d8d2098597fc451ed1a97bb1f6411bb550a7"
|
checksum = "46b046a346c374c6c3c84d2070bfe33904504686bdf949c2d8eb22edad3f270c"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
|
@ -885,7 +885,7 @@ dependencies = [
|
||||||
"diesel_derives",
|
"diesel_derives",
|
||||||
"pq-sys",
|
"pq-sys",
|
||||||
"r2d2",
|
"r2d2",
|
||||||
"serde_json 1.0.51",
|
"serde_json 1.0.53",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -1035,9 +1035,9 @@ checksum = "a246d82be1c9d791c5dfde9a2bd045fc3cbba3fa2b11ad558f27d01712f00569"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "encoding_rs"
|
name = "encoding_rs"
|
||||||
version = "0.8.22"
|
version = "0.8.23"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "cd8d03faa7fe0c1431609dfad7bbe827af30f82e1e2ae6f7ee4fca6bd764bc28"
|
checksum = "e8ac63f94732332f44fe654443c46f6375d1939684c17b0afb6cb56b0456e171"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
]
|
]
|
||||||
|
@ -1075,9 +1075,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "failure"
|
name = "failure"
|
||||||
version = "0.1.7"
|
version = "0.1.8"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b8529c2421efa3066a5cbd8063d2244603824daccb6936b079010bb2aa89464b"
|
checksum = "d32e9bd16cc02eae7db7ef620b392808b89f6a5e16bb3497d159c6b92a0f4f86"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"backtrace",
|
"backtrace",
|
||||||
"failure_derive",
|
"failure_derive",
|
||||||
|
@ -1085,9 +1085,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "failure_derive"
|
name = "failure_derive"
|
||||||
version = "0.1.7"
|
version = "0.1.8"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "030a733c8287d6213886dd487564ff5c8f6aae10278b3588ed177f9d18f8d231"
|
checksum = "aa4da3c766cd7a0db8242e326e9e4e081edd567072893ed320008189715366a4"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
|
@ -1124,9 +1124,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "fnv"
|
name = "fnv"
|
||||||
version = "1.0.6"
|
version = "1.0.7"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "2fad85553e09a6f881f739c29f0b00b0f01357c743266d478b68951ce23285f3"
|
checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "foreign-types"
|
name = "foreign-types"
|
||||||
|
@ -1167,9 +1167,9 @@ checksum = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "futures"
|
name = "futures"
|
||||||
version = "0.3.4"
|
version = "0.3.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "5c329ae8753502fb44ae4fc2b622fa2a94652c41e795143765ba0927f92ab780"
|
checksum = "1e05b85ec287aac0dc34db7d4a569323df697f9c55b99b15d6b4ef8cde49f613"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"futures-channel",
|
"futures-channel",
|
||||||
"futures-core",
|
"futures-core",
|
||||||
|
@ -1182,9 +1182,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "futures-channel"
|
name = "futures-channel"
|
||||||
version = "0.3.4"
|
version = "0.3.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f0c77d04ce8edd9cb903932b608268b3fffec4163dc053b3b402bf47eac1f1a8"
|
checksum = "f366ad74c28cca6ba456d95e6422883cfb4b252a83bed929c83abfdbbf2967d5"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"futures-core",
|
"futures-core",
|
||||||
"futures-sink",
|
"futures-sink",
|
||||||
|
@ -1192,15 +1192,15 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "futures-core"
|
name = "futures-core"
|
||||||
version = "0.3.4"
|
version = "0.3.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f25592f769825e89b92358db00d26f965761e094951ac44d3663ef25b7ac464a"
|
checksum = "59f5fff90fd5d971f936ad674802482ba441b6f09ba5e15fd8b39145582ca399"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "futures-executor"
|
name = "futures-executor"
|
||||||
version = "0.3.4"
|
version = "0.3.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f674f3e1bcb15b37284a90cedf55afdba482ab061c407a9c0ebbd0f3109741ba"
|
checksum = "10d6bb888be1153d3abeb9006b11b02cf5e9b209fda28693c31ae1e4e012e314"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"futures-core",
|
"futures-core",
|
||||||
"futures-task",
|
"futures-task",
|
||||||
|
@ -1209,15 +1209,15 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "futures-io"
|
name = "futures-io"
|
||||||
version = "0.3.4"
|
version = "0.3.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a638959aa96152c7a4cddf50fcb1e3fede0583b27157c26e67d6f99904090dc6"
|
checksum = "de27142b013a8e869c14957e6d2edeef89e97c289e69d042ee3a49acd8b51789"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "futures-macro"
|
name = "futures-macro"
|
||||||
version = "0.3.4"
|
version = "0.3.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9a5081aa3de1f7542a794a397cde100ed903b0630152d0973479018fd85423a7"
|
checksum = "d0b5a30a4328ab5473878237c447333c093297bded83a4983d10f4deea240d39"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro-hack",
|
"proc-macro-hack",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
|
@ -1227,21 +1227,24 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "futures-sink"
|
name = "futures-sink"
|
||||||
version = "0.3.4"
|
version = "0.3.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "3466821b4bc114d95b087b850a724c6f83115e929bc88f1fa98a3304a944c8a6"
|
checksum = "3f2032893cb734c7a05d85ce0cc8b8c4075278e93b24b66f9de99d6eb0fa8acc"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "futures-task"
|
name = "futures-task"
|
||||||
version = "0.3.4"
|
version = "0.3.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "7b0a34e53cf6cdcd0178aa573aed466b646eb3db769570841fda0c7ede375a27"
|
checksum = "bdb66b5f09e22019b1ab0830f7785bcea8e7a42148683f99214f73f8ec21a626"
|
||||||
|
dependencies = [
|
||||||
|
"once_cell",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "futures-util"
|
name = "futures-util"
|
||||||
version = "0.3.4"
|
version = "0.3.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "22766cf25d64306bedf0384da004d05c9974ab104fcc4528f1236181c18004c5"
|
checksum = "8764574ff08b701a084482c3c7031349104b07ac897393010494beaa18ce32c6"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"futures-channel",
|
"futures-channel",
|
||||||
"futures-core",
|
"futures-core",
|
||||||
|
@ -1250,6 +1253,7 @@ dependencies = [
|
||||||
"futures-sink",
|
"futures-sink",
|
||||||
"futures-task",
|
"futures-task",
|
||||||
"memchr 2.3.3",
|
"memchr 2.3.3",
|
||||||
|
"pin-project",
|
||||||
"pin-utils",
|
"pin-utils",
|
||||||
"proc-macro-hack",
|
"proc-macro-hack",
|
||||||
"proc-macro-nested",
|
"proc-macro-nested",
|
||||||
|
@ -1286,10 +1290,16 @@ dependencies = [
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "h2"
|
name = "gimli"
|
||||||
version = "0.2.4"
|
version = "0.21.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "377038bf3c89d18d6ca1431e7a5027194fbd724ca10592b9487ede5e8e144f42"
|
checksum = "bcc8e0c9bce37868955864dbecd2b1ab2bdf967e6f28066d65aaac620444b65c"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "h2"
|
||||||
|
version = "0.2.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "79b7246d7e4b979c03fa093da39cfb3617a96bbeee6310af63991668d7e843ff"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bytes",
|
"bytes",
|
||||||
"fnv",
|
"fnv",
|
||||||
|
@ -1374,9 +1384,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "http-signature-normalization"
|
name = "http-signature-normalization"
|
||||||
version = "0.4.2"
|
version = "0.5.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "fde6b0321d465ea2cdc18b5d5ec73eee2ff20177ecee126cd8dd997f6c49e088"
|
checksum = "648233553603e7bb55bc1ea08a514661e212c09c10f6434507894273d8b5e773"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"chrono",
|
"chrono",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
|
@ -1434,9 +1444,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ipconfig"
|
name = "ipconfig"
|
||||||
version = "0.2.1"
|
version = "0.2.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "aa79fa216fbe60834a9c0737d7fcd30425b32d1c58854663e24d4c4b328ed83f"
|
checksum = "f7e2f18aece9709094573a9f24f483c4f65caa4298e2f7ae1b71cc65d853fad7"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"socket2",
|
"socket2",
|
||||||
"widestring",
|
"widestring",
|
||||||
|
@ -1446,9 +1456,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "isahc"
|
name = "isahc"
|
||||||
version = "0.9.1"
|
version = "0.9.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "50bdb3bdcbf6d534daaad1a686eda0d0dc1946818fa71e3edd3124d001adfdc2"
|
checksum = "ee16417863ac2b4869ac774af7ef0322b08c53d952665edc5749ccaa37d68588"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bytes",
|
"bytes",
|
||||||
"crossbeam-channel",
|
"crossbeam-channel",
|
||||||
|
@ -1490,9 +1500,9 @@ checksum = "b8b7a7c0c47db5545ed3fef7468ee7bb5b74691498139e4b3f6a20685dc6dd8e"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "js-sys"
|
name = "js-sys"
|
||||||
version = "0.3.37"
|
version = "0.3.39"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "6a27d435371a2fa5b6d2b028a74bbdb1234f308da363226a2854ca3ff8ba7055"
|
checksum = "fa5a448de267e7358beaf4a5d849518fe9a0c13fce7afd44b06e68550e5562a7"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"wasm-bindgen",
|
"wasm-bindgen",
|
||||||
]
|
]
|
||||||
|
@ -1506,8 +1516,8 @@ dependencies = [
|
||||||
"base64 0.11.0",
|
"base64 0.11.0",
|
||||||
"pem",
|
"pem",
|
||||||
"ring",
|
"ring",
|
||||||
"serde 1.0.106",
|
"serde 1.0.110",
|
||||||
"serde_json 1.0.51",
|
"serde_json 1.0.53",
|
||||||
"simple_asn1",
|
"simple_asn1",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -1549,7 +1559,7 @@ dependencies = [
|
||||||
"actix-rt",
|
"actix-rt",
|
||||||
"actix-web",
|
"actix-web",
|
||||||
"actix-web-actors",
|
"actix-web-actors",
|
||||||
"base64 0.12.0",
|
"base64 0.12.1",
|
||||||
"bcrypt",
|
"bcrypt",
|
||||||
"chrono",
|
"chrono",
|
||||||
"comrak",
|
"comrak",
|
||||||
|
@ -1576,8 +1586,8 @@ dependencies = [
|
||||||
"rand 0.7.3",
|
"rand 0.7.3",
|
||||||
"regex 1.3.7",
|
"regex 1.3.7",
|
||||||
"rss",
|
"rss",
|
||||||
"serde 1.0.106",
|
"serde 1.0.110",
|
||||||
"serde_json 1.0.51",
|
"serde_json 1.0.53",
|
||||||
"sha2",
|
"sha2",
|
||||||
"strum",
|
"strum",
|
||||||
"strum_macros",
|
"strum_macros",
|
||||||
|
@ -1599,9 +1609,9 @@ dependencies = [
|
||||||
"log",
|
"log",
|
||||||
"native-tls",
|
"native-tls",
|
||||||
"nom 4.2.3",
|
"nom 4.2.3",
|
||||||
"serde 1.0.106",
|
"serde 1.0.110",
|
||||||
"serde_derive",
|
"serde_derive",
|
||||||
"serde_json 1.0.51",
|
"serde_json 1.0.53",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -1633,9 +1643,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libc"
|
name = "libc"
|
||||||
version = "0.2.69"
|
version = "0.2.70"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "99e85c08494b21a9054e7fe1374a732aeadaff3980b6990b94bfd3a70f690005"
|
checksum = "3baa92041a6fec78c687fa0cc2b3fae8884f743d672cf551bed1d6dac6988d0f"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "libnghttp2-sys"
|
name = "libnghttp2-sys"
|
||||||
|
@ -1671,9 +1681,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "linked-hash-map"
|
name = "linked-hash-map"
|
||||||
version = "0.5.2"
|
version = "0.5.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ae91b68aebc4ddb91978b11a1b02ddd8602a05ec19002801c5666000e05e0f83"
|
checksum = "8dd5a6d5999d9907cda8ed67bbd137d3af8085216c2ac62de5be860bd41f304a"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "lock_api"
|
name = "lock_api"
|
||||||
|
@ -1699,7 +1709,7 @@ version = "0.1.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "31e24f1ad8321ca0e8a1e0ac13f23cb668e6f5466c2c57319f6a5cf1cc8e3b1c"
|
checksum = "31e24f1ad8321ca0e8a1e0ac13f23cb668e6f5466c2c57319f6a5cf1cc8e3b1c"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"linked-hash-map 0.5.2",
|
"linked-hash-map 0.5.3",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -1789,9 +1799,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "mio"
|
name = "mio"
|
||||||
version = "0.6.21"
|
version = "0.6.22"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "302dec22bcf6bae6dfb69c647187f4b4d0fb6f535521f7bc022430ce8e12008f"
|
checksum = "fce347092656428bc8eaf6201042cb551b8d67855af7374542a92a0fbfcac430"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
"fuchsia-zircon",
|
"fuchsia-zircon",
|
||||||
|
@ -1808,9 +1818,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "mio-uds"
|
name = "mio-uds"
|
||||||
version = "0.6.7"
|
version = "0.6.8"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "966257a94e196b11bb43aca423754d87429960a768de9414f3691d6957abf125"
|
checksum = "afcb699eb26d4332647cc848492bbc15eafb26f08d0304550d5aa1f612e066f0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"iovec",
|
"iovec",
|
||||||
"libc",
|
"libc",
|
||||||
|
@ -1849,9 +1859,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "net2"
|
name = "net2"
|
||||||
version = "0.2.33"
|
version = "0.2.34"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "42550d9fb7b6684a6d404d9fa7250c2eb2646df731d1c06afc06dcee9e1bcf88"
|
checksum = "2ba7c918ac76704fb42afcbbb43891e72731f3dcca3bef2a19786297baf14af7"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
"libc",
|
"libc",
|
||||||
|
@ -1934,6 +1944,18 @@ dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "object"
|
||||||
|
version = "0.19.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9cbca9424c482ee628fa549d9c812e2cd22f1180b9222c9200fdfa6eb31aecb2"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "once_cell"
|
||||||
|
version = "1.4.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0b631f7e854af39a1739f401cf34a8a013dfe09eac4fa4dba91e9768bd28168d"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "opaque-debug"
|
name = "opaque-debug"
|
||||||
version = "0.2.3"
|
version = "0.2.3"
|
||||||
|
@ -1962,9 +1984,9 @@ checksum = "77af24da69f9d9341038eba93a073b1fdaaa1b788221b00a69bce9e762cb32de"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "openssl-sys"
|
name = "openssl-sys"
|
||||||
version = "0.9.55"
|
version = "0.9.56"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "7717097d810a0f2e2323f9e5d11e71608355e24828410b55b9d4f18aa5f9a5d8"
|
checksum = "f02309a7f127000ed50594f0b50ecc69e7c654e16d41b4e8156d1b3df8e0b52e"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"autocfg 1.0.0",
|
"autocfg 1.0.0",
|
||||||
"cc",
|
"cc",
|
||||||
|
@ -2059,18 +2081,18 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pin-project"
|
name = "pin-project"
|
||||||
version = "0.4.9"
|
version = "0.4.16"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "6f6a7f5eee6292c559c793430c55c00aea9d3b3d1905e855806ca4d7253426a2"
|
checksum = "81d480cb4e89522ccda96d0eed9af94180b7a5f93fb28f66e1fd7d68431663d1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"pin-project-internal",
|
"pin-project-internal",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pin-project-internal"
|
name = "pin-project-internal"
|
||||||
version = "0.4.9"
|
version = "0.4.16"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8988430ce790d8682672117bc06dda364c0be32d3abd738234f19f3240bad99a"
|
checksum = "a82996f11efccb19b685b14b5df818de31c1edcee3daa256ab5775dd98e72feb"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
|
@ -2079,9 +2101,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pin-project-lite"
|
name = "pin-project-lite"
|
||||||
version = "0.1.4"
|
version = "0.1.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "237844750cfbb86f67afe27eee600dfbbcb6188d734139b534cbfbf4f96792ae"
|
checksum = "f7505eeebd78492e0f6108f7171c4948dbb120ee8119d9d77d0afa5469bef67f"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pin-utils"
|
name = "pin-utils"
|
||||||
|
@ -2124,9 +2146,9 @@ checksum = "8e946095f9d3ed29ec38de908c22f95d9ac008e424c7bcae54c75a79c527c694"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "proc-macro2"
|
name = "proc-macro2"
|
||||||
version = "1.0.10"
|
version = "1.0.12"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "df246d292ff63439fea9bc8c0a270bed0e390d5ebd4db4ba15aba81111b5abe3"
|
checksum = "8872cf6f48eee44265156c111456a700ab3483686b3f96df4cf5481c89157319"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"unicode-xid",
|
"unicode-xid",
|
||||||
]
|
]
|
||||||
|
@ -2149,9 +2171,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "quote"
|
name = "quote"
|
||||||
version = "1.0.3"
|
version = "1.0.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "2bdc6c187c65bca4260c9011c9e3132efe4909da44726bad24cf7572ae338d7f"
|
checksum = "42934bc9c8ab0d3b273a16d8551c8f0fcff46be73276ca083ec2414c15c4ba5e"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
]
|
]
|
||||||
|
@ -2400,13 +2422,13 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ring"
|
name = "ring"
|
||||||
version = "0.16.12"
|
version = "0.16.13"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1ba5a8ec64ee89a76c98c549af81ff14813df09c3e6dc4766c3856da48597a0c"
|
checksum = "703516ae74571f24b465b4a1431e81e2ad51336cb0ded733a55a1aa3eccac196"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cc",
|
"cc",
|
||||||
"lazy_static 1.4.0",
|
|
||||||
"libc",
|
"libc",
|
||||||
|
"once_cell",
|
||||||
"spin",
|
"spin",
|
||||||
"untrusted",
|
"untrusted",
|
||||||
"web-sys",
|
"web-sys",
|
||||||
|
@ -2464,9 +2486,9 @@ checksum = "ef703b7cb59335eae2eb93ceb664c0eb7ea6bf567079d843e09420219668e072"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "schannel"
|
name = "schannel"
|
||||||
version = "0.1.18"
|
version = "0.1.19"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "039c25b130bd8c1321ee2d7de7fde2659fa9c2744e4bb29711cfc852ea53cd19"
|
checksum = "8f05ba609c234e60bee0d547fe94a4c7e9da733d1c962cf6e59efa4cd9c8bc75"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"lazy_static 1.4.0",
|
"lazy_static 1.4.0",
|
||||||
"winapi 0.3.8",
|
"winapi 0.3.8",
|
||||||
|
@ -2489,9 +2511,9 @@ checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "security-framework"
|
name = "security-framework"
|
||||||
version = "0.4.3"
|
version = "0.4.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "3f331b9025654145cd425b9ded0caf8f5ae0df80d418b326e2dc1c3dc5eb0620"
|
checksum = "64808902d7d99f78eaddd2b4e2509713babc3dc3c85ad6f4c447680f3c01e535"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags",
|
"bitflags",
|
||||||
"core-foundation",
|
"core-foundation",
|
||||||
|
@ -2533,9 +2555,9 @@ checksum = "9dad3f759919b92c3068c696c15c3d17238234498bbdcc80f2c469606f948ac8"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde"
|
name = "serde"
|
||||||
version = "1.0.106"
|
version = "1.0.110"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "36df6ac6412072f67cf767ebbde4133a5b2e88e76dc6187fa7104cd16f783399"
|
checksum = "99e7b308464d16b56eba9964e4972a3eee817760ab60d88c3f86e1fecb08204c"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"serde_derive",
|
"serde_derive",
|
||||||
]
|
]
|
||||||
|
@ -2568,9 +2590,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde_derive"
|
name = "serde_derive"
|
||||||
version = "1.0.106"
|
version = "1.0.110"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9e549e3abf4fb8621bd1609f11dfc9f5e50320802273b12f3811a67e6716ea6c"
|
checksum = "818fbf6bfa9a42d3bfcaca148547aa00c7b915bec71d1757aa2d44ca68771984"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
|
@ -2591,14 +2613,14 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde_json"
|
name = "serde_json"
|
||||||
version = "1.0.51"
|
version = "1.0.53"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "da07b57ee2623368351e9a0488bb0b261322a15a6e0ae53e243cbdc0f4208da9"
|
checksum = "993948e75b189211a9b31a7528f950c6adc21f9720b6438ff80a7fa2f864cea2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"indexmap",
|
"indexmap",
|
||||||
"itoa 0.4.5",
|
"itoa 0.4.5",
|
||||||
"ryu",
|
"ryu",
|
||||||
"serde 1.0.106",
|
"serde 1.0.110",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -2618,7 +2640,7 @@ checksum = "9ec5d77e2d4c73717816afac02670d5c4f534ea95ed430442cad02e7a6e32c97"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"dtoa 0.4.5",
|
"dtoa 0.4.5",
|
||||||
"itoa 0.4.5",
|
"itoa 0.4.5",
|
||||||
"serde 1.0.106",
|
"serde 1.0.110",
|
||||||
"url",
|
"url",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -2759,9 +2781,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "syn"
|
name = "syn"
|
||||||
version = "1.0.18"
|
version = "1.0.21"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "410a7488c0a728c7ceb4ad59b9567eb4053d02e8cc7f5c0e0eeeb39518369213"
|
checksum = "4696caa4048ac7ce2bcd2e484b3cef88c1004e41b8e945a277e2c25dc0b72060"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
|
@ -2814,18 +2836,18 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "thiserror"
|
name = "thiserror"
|
||||||
version = "1.0.16"
|
version = "1.0.17"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d12a1dae4add0f0d568eebc7bf142f145ba1aa2544cafb195c76f0f409091b60"
|
checksum = "467e5ff447618a916519a4e0d62772ab14f434897f3d63f05d8700ef1e9b22c1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"thiserror-impl",
|
"thiserror-impl",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "thiserror-impl"
|
name = "thiserror-impl"
|
||||||
version = "1.0.16"
|
version = "1.0.17"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "3f34e0c1caaa462fd840ec6b768946ea1e7842620d94fe29d5b847138f521269"
|
checksum = "e63c1091225b9834089b429bc4a2e01223470e3183e891582909e9d1c4cb55d9"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
|
@ -2862,9 +2884,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "threadpool"
|
name = "threadpool"
|
||||||
version = "1.8.0"
|
version = "1.8.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e8dae184447c15d5a6916d973c642aec485105a13cd238192a6927ae3e077d66"
|
checksum = "d050e60b33d41c19108b32cea32164033a9013fe3b46cbd4457559bfbf77afaa"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"num_cpus",
|
"num_cpus",
|
||||||
]
|
]
|
||||||
|
@ -2881,9 +2903,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tokio"
|
name = "tokio"
|
||||||
version = "0.2.19"
|
version = "0.2.21"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "7d9c43f1bb96970e153bcbae39a65e249ccb942bd9d36dbdf086024920417c9c"
|
checksum = "d099fa27b9702bed751524694adbe393e18b36b204da91eb1cbbbbb4a5ee2d58"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bytes",
|
"bytes",
|
||||||
"fnv",
|
"fnv",
|
||||||
|
@ -2934,7 +2956,7 @@ version = "0.5.6"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ffc92d160b1eef40665be3a05630d003936a3bc7da7421277846c2613e92c71a"
|
checksum = "ffc92d160b1eef40665be3a05630d003936a3bc7da7421277846c2613e92c71a"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"serde 1.0.106",
|
"serde 1.0.110",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -3063,9 +3085,9 @@ checksum = "39ec24b3121d976906ece63c9daad25b85969647682eee313cb5779fdd69e14e"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "untrusted"
|
name = "untrusted"
|
||||||
version = "0.7.0"
|
version = "0.7.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "60369ef7a31de49bcb3f6ca728d4ba7300d9a1658f94c727d4cab8c8d9f4aece"
|
checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "url"
|
name = "url"
|
||||||
|
@ -3076,7 +3098,7 @@ dependencies = [
|
||||||
"idna",
|
"idna",
|
||||||
"matches",
|
"matches",
|
||||||
"percent-encoding",
|
"percent-encoding",
|
||||||
"serde 1.0.106",
|
"serde 1.0.110",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -3101,7 +3123,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9fde2f6a4bea1d6e007c4ad38c6839fa71cbb63b6dbf5b595aa38dc9b1093c11"
|
checksum = "9fde2f6a4bea1d6e007c4ad38c6839fa71cbb63b6dbf5b595aa38dc9b1093c11"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"rand 0.7.3",
|
"rand 0.7.3",
|
||||||
"serde 1.0.106",
|
"serde 1.0.110",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -3143,9 +3165,9 @@ checksum = "3fc439f2794e98976c88a2a2dafce96b930fe8010b0a256b3c2199a773933168"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "vec_map"
|
name = "vec_map"
|
||||||
version = "0.8.1"
|
version = "0.8.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "05c78687fb1a80548ae3250346c3db86a80a7cdd77bda190189f2d0a0987c81a"
|
checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "version_check"
|
name = "version_check"
|
||||||
|
@ -3167,9 +3189,9 @@ checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasm-bindgen"
|
name = "wasm-bindgen"
|
||||||
version = "0.2.60"
|
version = "0.2.62"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "2cc57ce05287f8376e998cbddfb4c8cb43b84a7ec55cf4551d7c00eef317a47f"
|
checksum = "e3c7d40d09cdbf0f4895ae58cf57d92e1e57a9dd8ed2e8390514b54a47cc5551"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
"wasm-bindgen-macro",
|
"wasm-bindgen-macro",
|
||||||
|
@ -3177,9 +3199,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasm-bindgen-backend"
|
name = "wasm-bindgen-backend"
|
||||||
version = "0.2.60"
|
version = "0.2.62"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d967d37bf6c16cca2973ca3af071d0a2523392e4a594548155d89a678f4237cd"
|
checksum = "c3972e137ebf830900db522d6c8fd74d1900dcfc733462e9a12e942b00b4ac94"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bumpalo",
|
"bumpalo",
|
||||||
"lazy_static 1.4.0",
|
"lazy_static 1.4.0",
|
||||||
|
@ -3192,9 +3214,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasm-bindgen-macro"
|
name = "wasm-bindgen-macro"
|
||||||
version = "0.2.60"
|
version = "0.2.62"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8bd151b63e1ea881bb742cd20e1d6127cef28399558f3b5d415289bc41eee3a4"
|
checksum = "2cd85aa2c579e8892442954685f0d801f9129de24fa2136b2c6a539c76b65776"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"quote",
|
"quote",
|
||||||
"wasm-bindgen-macro-support",
|
"wasm-bindgen-macro-support",
|
||||||
|
@ -3202,9 +3224,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasm-bindgen-macro-support"
|
name = "wasm-bindgen-macro-support"
|
||||||
version = "0.2.60"
|
version = "0.2.62"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d68a5b36eef1be7868f668632863292e37739656a80fc4b9acec7b0bd35a4931"
|
checksum = "8eb197bd3a47553334907ffd2f16507b4f4f01bbec3ac921a7719e0decdfe72a"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
|
@ -3215,15 +3237,15 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasm-bindgen-shared"
|
name = "wasm-bindgen-shared"
|
||||||
version = "0.2.60"
|
version = "0.2.62"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "daf76fe7d25ac79748a37538b7daeed1c7a6867c92d3245c12c6222e4a20d639"
|
checksum = "a91c2916119c17a8e316507afaaa2dd94b47646048014bbdf6bef098c1bb58ad"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "web-sys"
|
name = "web-sys"
|
||||||
version = "0.3.37"
|
version = "0.3.39"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "2d6f51648d8c56c366144378a33290049eafdd784071077f6fe37dae64c1c4cb"
|
checksum = "8bc359e5dd3b46cb9687a051d50a2fdd228e4ba7cf6fcf861a5365c3d671a642"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"js-sys",
|
"js-sys",
|
||||||
"wasm-bindgen",
|
"wasm-bindgen",
|
||||||
|
@ -3312,5 +3334,5 @@ version = "0.4.3"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "65923dd1784f44da1d2c3dbbc5e822045628c590ba72123e1c73d3c230c4434d"
|
checksum = "65923dd1784f44da1d2c3dbbc5e822045628c590ba72123e1c73d3c230c4434d"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"linked-hash-map 0.5.2",
|
"linked-hash-map 0.5.3",
|
||||||
]
|
]
|
||||||
|
|
18
server/Cargo.toml
vendored
18
server/Cargo.toml
vendored
|
@ -8,17 +8,17 @@ edition = "2018"
|
||||||
diesel = { version = "1.4.4", features = ["postgres","chrono","r2d2","64-column-tables","serde_json"] }
|
diesel = { version = "1.4.4", features = ["postgres","chrono","r2d2","64-column-tables","serde_json"] }
|
||||||
diesel_migrations = "1.4.0"
|
diesel_migrations = "1.4.0"
|
||||||
dotenv = "0.15.0"
|
dotenv = "0.15.0"
|
||||||
activitystreams = "0.6.0"
|
activitystreams = "0.6.1"
|
||||||
bcrypt = "0.6.2"
|
bcrypt = "0.8.0"
|
||||||
chrono = { version = "0.4.7", features = ["serde"] }
|
chrono = { version = "0.4.7", features = ["serde"] }
|
||||||
failure = "0.1.5"
|
failure = "0.1.8"
|
||||||
serde_json = { version = "1.0.48", features = ["preserve_order"]}
|
serde_json = { version = "1.0.48", features = ["preserve_order"]}
|
||||||
serde = { version = "1.0.105", features = ["derive"] }
|
serde = { version = "1.0.105", features = ["derive"] }
|
||||||
actix = "0.9.0"
|
actix = "0.9.0"
|
||||||
actix-web = "2.0.0"
|
actix-web = "2.0.0"
|
||||||
actix-files = "0.2.1"
|
actix-files = "0.2.1"
|
||||||
actix-web-actors = "2.0.0"
|
actix-web-actors = "2.0.0"
|
||||||
actix-rt = "1.0.0"
|
actix-rt = "1.1.1"
|
||||||
log = "0.4.0"
|
log = "0.4.0"
|
||||||
env_logger = "0.7.1"
|
env_logger = "0.7.1"
|
||||||
rand = "0.7.3"
|
rand = "0.7.3"
|
||||||
|
@ -36,13 +36,13 @@ config = "0.10.1"
|
||||||
hjson = "0.8.2"
|
hjson = "0.8.2"
|
||||||
url = { version = "2.1.1", features = ["serde"] }
|
url = { version = "2.1.1", features = ["serde"] }
|
||||||
percent-encoding = "2.1.0"
|
percent-encoding = "2.1.0"
|
||||||
isahc = "0.9"
|
isahc = "0.9.2"
|
||||||
comrak = "0.7"
|
comrak = "0.7"
|
||||||
openssl = "0.10"
|
openssl = "0.10"
|
||||||
http = "0.2.1"
|
http = "0.2.1"
|
||||||
http-signature-normalization = "0.4.1"
|
http-signature-normalization = "0.5.1"
|
||||||
base64 = "0.12.0"
|
base64 = "0.12.1"
|
||||||
tokio = "0.2.18"
|
tokio = "0.2.21"
|
||||||
futures = "0.3.4"
|
futures = "0.3.5"
|
||||||
itertools = "0.9.0"
|
itertools = "0.9.0"
|
||||||
uuid = { version = "0.8", features = ["serde", "v4"] }
|
uuid = { version = "0.8", features = ["serde", "v4"] }
|
||||||
|
|
|
@ -76,8 +76,6 @@ impl Perform for Oper<CreateComment> {
|
||||||
|
|
||||||
let user_id = claims.id;
|
let user_id = claims.id;
|
||||||
|
|
||||||
let hostname = &format!("https://{}", Settings::get().hostname);
|
|
||||||
|
|
||||||
let conn = pool.get()?;
|
let conn = pool.get()?;
|
||||||
|
|
||||||
// Check for a community ban
|
// Check for a community ban
|
||||||
|
@ -120,107 +118,9 @@ impl Perform for Oper<CreateComment> {
|
||||||
|
|
||||||
updated_comment.send_create(&user, &conn)?;
|
updated_comment.send_create(&user, &conn)?;
|
||||||
|
|
||||||
let mut recipient_ids = Vec::new();
|
|
||||||
|
|
||||||
// Scan the comment for user mentions, add those rows
|
// Scan the comment for user mentions, add those rows
|
||||||
let extracted_usernames = extract_usernames(&comment_form.content);
|
let mentions = scrape_text_for_mentions(&comment_form.content);
|
||||||
|
let recipient_ids = send_local_notifs(&conn, &mentions, &updated_comment, &user, &post);
|
||||||
for username_mention in &extracted_usernames {
|
|
||||||
if let Ok(mention_user) = User_::read_from_name(&conn, username_mention) {
|
|
||||||
// You can't mention yourself
|
|
||||||
// At some point, make it so you can't tag the parent creator either
|
|
||||||
// This can cause two notifications, one for reply and the other for mention
|
|
||||||
if mention_user.id != user_id {
|
|
||||||
recipient_ids.push(mention_user.id);
|
|
||||||
|
|
||||||
let user_mention_form = UserMentionForm {
|
|
||||||
recipient_id: mention_user.id,
|
|
||||||
comment_id: inserted_comment.id,
|
|
||||||
read: None,
|
|
||||||
};
|
|
||||||
|
|
||||||
// Allow this to fail softly, since comment edits might re-update or replace it
|
|
||||||
// Let the uniqueness handle this fail
|
|
||||||
match UserMention::create(&conn, &user_mention_form) {
|
|
||||||
Ok(_mention) => (),
|
|
||||||
Err(_e) => error!("{}", &_e),
|
|
||||||
};
|
|
||||||
|
|
||||||
// Send an email to those users that have notifications on
|
|
||||||
if mention_user.send_notifications_to_email {
|
|
||||||
if let Some(mention_email) = mention_user.email {
|
|
||||||
let subject = &format!(
|
|
||||||
"{} - Mentioned by {}",
|
|
||||||
Settings::get().hostname,
|
|
||||||
claims.username
|
|
||||||
);
|
|
||||||
let html = &format!(
|
|
||||||
"<h1>User Mention</h1><br><div>{} - {}</div><br><a href={}/inbox>inbox</a>",
|
|
||||||
claims.username, comment_form.content, hostname
|
|
||||||
);
|
|
||||||
match send_email(subject, &mention_email, &mention_user.name, html) {
|
|
||||||
Ok(_o) => _o,
|
|
||||||
Err(e) => error!("{}", e),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Send notifs to the parent commenter / poster
|
|
||||||
match data.parent_id {
|
|
||||||
Some(parent_id) => {
|
|
||||||
let parent_comment = Comment::read(&conn, parent_id)?;
|
|
||||||
if parent_comment.creator_id != user_id {
|
|
||||||
let parent_user = User_::read(&conn, parent_comment.creator_id)?;
|
|
||||||
recipient_ids.push(parent_user.id);
|
|
||||||
|
|
||||||
if parent_user.send_notifications_to_email {
|
|
||||||
if let Some(comment_reply_email) = parent_user.email {
|
|
||||||
let subject = &format!(
|
|
||||||
"{} - Reply from {}",
|
|
||||||
Settings::get().hostname,
|
|
||||||
claims.username
|
|
||||||
);
|
|
||||||
let html = &format!(
|
|
||||||
"<h1>Comment Reply</h1><br><div>{} - {}</div><br><a href={}/inbox>inbox</a>",
|
|
||||||
claims.username, comment_form.content, hostname
|
|
||||||
);
|
|
||||||
match send_email(subject, &comment_reply_email, &parent_user.name, html) {
|
|
||||||
Ok(_o) => _o,
|
|
||||||
Err(e) => error!("{}", e),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Its a post
|
|
||||||
None => {
|
|
||||||
if post.creator_id != user_id {
|
|
||||||
let parent_user = User_::read(&conn, post.creator_id)?;
|
|
||||||
recipient_ids.push(parent_user.id);
|
|
||||||
|
|
||||||
if parent_user.send_notifications_to_email {
|
|
||||||
if let Some(post_reply_email) = parent_user.email {
|
|
||||||
let subject = &format!(
|
|
||||||
"{} - Reply from {}",
|
|
||||||
Settings::get().hostname,
|
|
||||||
claims.username
|
|
||||||
);
|
|
||||||
let html = &format!(
|
|
||||||
"<h1>Post Reply</h1><br><div>{} - {}</div><br><a href={}/inbox>inbox</a>",
|
|
||||||
claims.username, comment_form.content, hostname
|
|
||||||
);
|
|
||||||
match send_email(subject, &post_reply_email, &parent_user.name, html) {
|
|
||||||
Ok(_o) => _o,
|
|
||||||
Err(e) => error!("{}", e),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// You like your own comment by default
|
// You like your own comment by default
|
||||||
let like_form = CommentLikeForm {
|
let like_form = CommentLikeForm {
|
||||||
|
@ -353,53 +253,10 @@ impl Perform for Oper<EditComment> {
|
||||||
updated_comment.send_update(&user, &conn)?;
|
updated_comment.send_update(&user, &conn)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut recipient_ids = Vec::new();
|
|
||||||
|
|
||||||
// Scan the comment for user mentions, add those rows
|
|
||||||
let extracted_usernames = extract_usernames(&comment_form.content);
|
|
||||||
|
|
||||||
for username_mention in &extracted_usernames {
|
|
||||||
let mention_user = User_::read_from_name(&conn, username_mention);
|
|
||||||
|
|
||||||
if mention_user.is_ok() {
|
|
||||||
let mention_user_id = mention_user?.id;
|
|
||||||
|
|
||||||
// You can't mention yourself
|
|
||||||
// At some point, make it so you can't tag the parent creator either
|
|
||||||
// This can cause two notifications, one for reply and the other for mention
|
|
||||||
if mention_user_id != user_id {
|
|
||||||
recipient_ids.push(mention_user_id);
|
|
||||||
|
|
||||||
let user_mention_form = UserMentionForm {
|
|
||||||
recipient_id: mention_user_id,
|
|
||||||
comment_id: data.edit_id,
|
|
||||||
read: None,
|
|
||||||
};
|
|
||||||
|
|
||||||
// Allow this to fail softly, since comment edits might re-update or replace it
|
|
||||||
// Let the uniqueness handle this fail
|
|
||||||
match UserMention::create(&conn, &user_mention_form) {
|
|
||||||
Ok(_mention) => (),
|
|
||||||
Err(_e) => error!("{}", &_e),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add to recipient ids
|
|
||||||
match data.parent_id {
|
|
||||||
Some(parent_id) => {
|
|
||||||
let parent_comment = Comment::read(&conn, parent_id)?;
|
|
||||||
if parent_comment.creator_id != user_id {
|
|
||||||
let parent_user = User_::read(&conn, parent_comment.creator_id)?;
|
|
||||||
recipient_ids.push(parent_user.id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
None => {
|
|
||||||
let post = Post::read(&conn, data.post_id)?;
|
let post = Post::read(&conn, data.post_id)?;
|
||||||
recipient_ids.push(post.creator_id);
|
|
||||||
}
|
let mentions = scrape_text_for_mentions(&comment_form.content);
|
||||||
}
|
let recipient_ids = send_local_notifs(&conn, &mentions, &updated_comment, &user, &post);
|
||||||
|
|
||||||
// Mod tables
|
// Mod tables
|
||||||
if let Some(removed) = data.removed.to_owned() {
|
if let Some(removed) = data.removed.to_owned() {
|
||||||
|
@ -646,3 +503,106 @@ impl Perform for Oper<GetComments> {
|
||||||
Ok(GetCommentsResponse { comments })
|
Ok(GetCommentsResponse { comments })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn send_local_notifs(
|
||||||
|
conn: &PgConnection,
|
||||||
|
mentions: &[MentionData],
|
||||||
|
comment: &Comment,
|
||||||
|
user: &User_,
|
||||||
|
post: &Post,
|
||||||
|
) -> Vec<i32> {
|
||||||
|
let mut recipient_ids = Vec::new();
|
||||||
|
let hostname = &format!("https://{}", Settings::get().hostname);
|
||||||
|
|
||||||
|
// Send the local mentions
|
||||||
|
for mention in mentions
|
||||||
|
.iter()
|
||||||
|
.filter(|m| m.is_local() && m.name.ne(&user.name))
|
||||||
|
.collect::<Vec<&MentionData>>()
|
||||||
|
{
|
||||||
|
if let Ok(mention_user) = User_::read_from_name(&conn, &mention.name) {
|
||||||
|
// TODO
|
||||||
|
// At some point, make it so you can't tag the parent creator either
|
||||||
|
// This can cause two notifications, one for reply and the other for mention
|
||||||
|
recipient_ids.push(mention_user.id);
|
||||||
|
|
||||||
|
let user_mention_form = UserMentionForm {
|
||||||
|
recipient_id: mention_user.id,
|
||||||
|
comment_id: comment.id,
|
||||||
|
read: None,
|
||||||
|
};
|
||||||
|
|
||||||
|
// Allow this to fail softly, since comment edits might re-update or replace it
|
||||||
|
// Let the uniqueness handle this fail
|
||||||
|
match UserMention::create(&conn, &user_mention_form) {
|
||||||
|
Ok(_mention) => (),
|
||||||
|
Err(_e) => error!("{}", &_e),
|
||||||
|
};
|
||||||
|
|
||||||
|
// Send an email to those users that have notifications on
|
||||||
|
if mention_user.send_notifications_to_email {
|
||||||
|
if let Some(mention_email) = mention_user.email {
|
||||||
|
let subject = &format!("{} - Mentioned by {}", Settings::get().hostname, user.name,);
|
||||||
|
let html = &format!(
|
||||||
|
"<h1>User Mention</h1><br><div>{} - {}</div><br><a href={}/inbox>inbox</a>",
|
||||||
|
user.name, comment.content, hostname
|
||||||
|
);
|
||||||
|
match send_email(subject, &mention_email, &mention_user.name, html) {
|
||||||
|
Ok(_o) => _o,
|
||||||
|
Err(e) => error!("{}", e),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Send notifs to the parent commenter / poster
|
||||||
|
match comment.parent_id {
|
||||||
|
Some(parent_id) => {
|
||||||
|
if let Ok(parent_comment) = Comment::read(&conn, parent_id) {
|
||||||
|
if parent_comment.creator_id != user.id {
|
||||||
|
if let Ok(parent_user) = User_::read(&conn, parent_comment.creator_id) {
|
||||||
|
recipient_ids.push(parent_user.id);
|
||||||
|
|
||||||
|
if parent_user.send_notifications_to_email {
|
||||||
|
if let Some(comment_reply_email) = parent_user.email {
|
||||||
|
let subject = &format!("{} - Reply from {}", Settings::get().hostname, user.name,);
|
||||||
|
let html = &format!(
|
||||||
|
"<h1>Comment Reply</h1><br><div>{} - {}</div><br><a href={}/inbox>inbox</a>",
|
||||||
|
user.name, comment.content, hostname
|
||||||
|
);
|
||||||
|
match send_email(subject, &comment_reply_email, &parent_user.name, html) {
|
||||||
|
Ok(_o) => _o,
|
||||||
|
Err(e) => error!("{}", e),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Its a post
|
||||||
|
None => {
|
||||||
|
if post.creator_id != user.id {
|
||||||
|
if let Ok(parent_user) = User_::read(&conn, post.creator_id) {
|
||||||
|
recipient_ids.push(parent_user.id);
|
||||||
|
|
||||||
|
if parent_user.send_notifications_to_email {
|
||||||
|
if let Some(post_reply_email) = parent_user.email {
|
||||||
|
let subject = &format!("{} - Reply from {}", Settings::get().hostname, user.name,);
|
||||||
|
let html = &format!(
|
||||||
|
"<h1>Post Reply</h1><br><div>{} - {}</div><br><a href={}/inbox>inbox</a>",
|
||||||
|
user.name, comment.content, hostname
|
||||||
|
);
|
||||||
|
match send_email(subject, &post_reply_email, &parent_user.name, html) {
|
||||||
|
Ok(_o) => _o,
|
||||||
|
Err(e) => error!("{}", e),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
recipient_ids
|
||||||
|
}
|
||||||
|
|
|
@ -18,8 +18,8 @@ use crate::db::user_mention_view::*;
|
||||||
use crate::db::user_view::*;
|
use crate::db::user_view::*;
|
||||||
use crate::db::*;
|
use crate::db::*;
|
||||||
use crate::{
|
use crate::{
|
||||||
extract_usernames, fetch_iframely_and_pictshare_data, generate_random_string, naive_from_unix,
|
fetch_iframely_and_pictshare_data, generate_random_string, naive_from_unix, naive_now,
|
||||||
naive_now, remove_slurs, send_email, slur_check, slurs_vec_to_str,
|
remove_slurs, scrape_text_for_mentions, send_email, slur_check, slurs_vec_to_str, MentionData,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::apub::{
|
use crate::apub::{
|
||||||
|
|
|
@ -2,7 +2,7 @@ use super::*;
|
||||||
|
|
||||||
pub fn populate_object_props(
|
pub fn populate_object_props(
|
||||||
props: &mut ObjectProperties,
|
props: &mut ObjectProperties,
|
||||||
addressed_to: &str,
|
addressed_ccs: Vec<String>,
|
||||||
object_id: &str,
|
object_id: &str,
|
||||||
) -> Result<(), Error> {
|
) -> Result<(), Error> {
|
||||||
props
|
props
|
||||||
|
@ -12,7 +12,7 @@ pub fn populate_object_props(
|
||||||
// TODO: should to/cc go on the Create, or on the Post? or on both?
|
// TODO: should to/cc go on the Create, or on the Post? or on both?
|
||||||
// TODO: handle privacy on the receiving side (at least ignore anything thats not public)
|
// TODO: handle privacy on the receiving side (at least ignore anything thats not public)
|
||||||
.set_to_xsd_any_uri(public())?
|
.set_to_xsd_any_uri(public())?
|
||||||
.set_cc_xsd_any_uri(addressed_to)?;
|
.set_many_cc_xsd_any_uris(addressed_ccs)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -88,6 +88,8 @@ impl FromApub for CommentForm {
|
||||||
None => None,
|
None => None,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// TODO this failed because a mention on a post that wasn't on this server yet. Has to do with
|
||||||
|
// fetching replytos
|
||||||
let post = Post::read_from_apub_id(&conn, &post_ap_id)?;
|
let post = Post::read_from_apub_id(&conn, &post_ap_id)?;
|
||||||
|
|
||||||
Ok(CommentForm {
|
Ok(CommentForm {
|
||||||
|
@ -121,12 +123,15 @@ impl ApubObjectType for Comment {
|
||||||
let community = Community::read(conn, post.community_id)?;
|
let community = Community::read(conn, post.community_id)?;
|
||||||
let id = format!("{}/create/{}", self.ap_id, uuid::Uuid::new_v4());
|
let id = format!("{}/create/{}", self.ap_id, uuid::Uuid::new_v4());
|
||||||
|
|
||||||
|
let maa: MentionsAndAddresses =
|
||||||
|
collect_non_local_mentions_and_addresses(&conn, &self.content, &community)?;
|
||||||
|
|
||||||
let mut create = Create::new();
|
let mut create = Create::new();
|
||||||
populate_object_props(
|
populate_object_props(&mut create.object_props, maa.addressed_ccs, &id)?;
|
||||||
&mut create.object_props,
|
|
||||||
&community.get_followers_url(),
|
// Set the mention tags
|
||||||
&id,
|
create.object_props.set_many_tag_base_boxes(maa.tags)?;
|
||||||
)?;
|
|
||||||
create
|
create
|
||||||
.create_props
|
.create_props
|
||||||
.set_actor_xsd_any_uri(creator.actor_id.to_owned())?
|
.set_actor_xsd_any_uri(creator.actor_id.to_owned())?
|
||||||
|
@ -134,7 +139,7 @@ impl ApubObjectType for Comment {
|
||||||
|
|
||||||
insert_activity(&conn, creator.id, &create, true)?;
|
insert_activity(&conn, creator.id, &create, true)?;
|
||||||
|
|
||||||
send_activity(&create, creator, community.get_follower_inboxes(&conn)?)?;
|
send_activity(&create, creator, maa.inboxes)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -145,12 +150,15 @@ impl ApubObjectType for Comment {
|
||||||
let community = Community::read(&conn, post.community_id)?;
|
let community = Community::read(&conn, post.community_id)?;
|
||||||
let id = format!("{}/update/{}", self.ap_id, uuid::Uuid::new_v4());
|
let id = format!("{}/update/{}", self.ap_id, uuid::Uuid::new_v4());
|
||||||
|
|
||||||
|
let maa: MentionsAndAddresses =
|
||||||
|
collect_non_local_mentions_and_addresses(&conn, &self.content, &community)?;
|
||||||
|
|
||||||
let mut update = Update::new();
|
let mut update = Update::new();
|
||||||
populate_object_props(
|
populate_object_props(&mut update.object_props, maa.addressed_ccs, &id)?;
|
||||||
&mut update.object_props,
|
|
||||||
&community.get_followers_url(),
|
// Set the mention tags
|
||||||
&id,
|
update.object_props.set_many_tag_base_boxes(maa.tags)?;
|
||||||
)?;
|
|
||||||
update
|
update
|
||||||
.update_props
|
.update_props
|
||||||
.set_actor_xsd_any_uri(creator.actor_id.to_owned())?
|
.set_actor_xsd_any_uri(creator.actor_id.to_owned())?
|
||||||
|
@ -158,7 +166,7 @@ impl ApubObjectType for Comment {
|
||||||
|
|
||||||
insert_activity(&conn, creator.id, &update, true)?;
|
insert_activity(&conn, creator.id, &update, true)?;
|
||||||
|
|
||||||
send_activity(&update, creator, community.get_follower_inboxes(&conn)?)?;
|
send_activity(&update, creator, maa.inboxes)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -171,7 +179,7 @@ impl ApubObjectType for Comment {
|
||||||
|
|
||||||
populate_object_props(
|
populate_object_props(
|
||||||
&mut delete.object_props,
|
&mut delete.object_props,
|
||||||
&community.get_followers_url(),
|
vec![community.get_followers_url()],
|
||||||
&id,
|
&id,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
|
@ -197,7 +205,7 @@ impl ApubObjectType for Comment {
|
||||||
|
|
||||||
populate_object_props(
|
populate_object_props(
|
||||||
&mut delete.object_props,
|
&mut delete.object_props,
|
||||||
&community.get_followers_url(),
|
vec![community.get_followers_url()],
|
||||||
&id,
|
&id,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
|
@ -213,7 +221,7 @@ impl ApubObjectType for Comment {
|
||||||
|
|
||||||
populate_object_props(
|
populate_object_props(
|
||||||
&mut undo.object_props,
|
&mut undo.object_props,
|
||||||
&community.get_followers_url(),
|
vec![community.get_followers_url()],
|
||||||
&undo_id,
|
&undo_id,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
|
@ -237,7 +245,7 @@ impl ApubObjectType for Comment {
|
||||||
|
|
||||||
populate_object_props(
|
populate_object_props(
|
||||||
&mut remove.object_props,
|
&mut remove.object_props,
|
||||||
&community.get_followers_url(),
|
vec![community.get_followers_url()],
|
||||||
&id,
|
&id,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
|
@ -263,7 +271,7 @@ impl ApubObjectType for Comment {
|
||||||
|
|
||||||
populate_object_props(
|
populate_object_props(
|
||||||
&mut remove.object_props,
|
&mut remove.object_props,
|
||||||
&community.get_followers_url(),
|
vec![community.get_followers_url()],
|
||||||
&id,
|
&id,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
|
@ -278,7 +286,7 @@ impl ApubObjectType for Comment {
|
||||||
|
|
||||||
populate_object_props(
|
populate_object_props(
|
||||||
&mut undo.object_props,
|
&mut undo.object_props,
|
||||||
&community.get_followers_url(),
|
vec![community.get_followers_url()],
|
||||||
&undo_id,
|
&undo_id,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
|
@ -302,7 +310,11 @@ impl ApubLikeableType for Comment {
|
||||||
let id = format!("{}/like/{}", self.ap_id, uuid::Uuid::new_v4());
|
let id = format!("{}/like/{}", self.ap_id, uuid::Uuid::new_v4());
|
||||||
|
|
||||||
let mut like = Like::new();
|
let mut like = Like::new();
|
||||||
populate_object_props(&mut like.object_props, &community.get_followers_url(), &id)?;
|
populate_object_props(
|
||||||
|
&mut like.object_props,
|
||||||
|
vec![community.get_followers_url()],
|
||||||
|
&id,
|
||||||
|
)?;
|
||||||
like
|
like
|
||||||
.like_props
|
.like_props
|
||||||
.set_actor_xsd_any_uri(creator.actor_id.to_owned())?
|
.set_actor_xsd_any_uri(creator.actor_id.to_owned())?
|
||||||
|
@ -323,7 +335,7 @@ impl ApubLikeableType for Comment {
|
||||||
let mut dislike = Dislike::new();
|
let mut dislike = Dislike::new();
|
||||||
populate_object_props(
|
populate_object_props(
|
||||||
&mut dislike.object_props,
|
&mut dislike.object_props,
|
||||||
&community.get_followers_url(),
|
vec![community.get_followers_url()],
|
||||||
&id,
|
&id,
|
||||||
)?;
|
)?;
|
||||||
dislike
|
dislike
|
||||||
|
@ -344,7 +356,11 @@ impl ApubLikeableType for Comment {
|
||||||
let id = format!("{}/dislike/{}", self.ap_id, uuid::Uuid::new_v4());
|
let id = format!("{}/dislike/{}", self.ap_id, uuid::Uuid::new_v4());
|
||||||
|
|
||||||
let mut like = Like::new();
|
let mut like = Like::new();
|
||||||
populate_object_props(&mut like.object_props, &community.get_followers_url(), &id)?;
|
populate_object_props(
|
||||||
|
&mut like.object_props,
|
||||||
|
vec![community.get_followers_url()],
|
||||||
|
&id,
|
||||||
|
)?;
|
||||||
like
|
like
|
||||||
.like_props
|
.like_props
|
||||||
.set_actor_xsd_any_uri(creator.actor_id.to_owned())?
|
.set_actor_xsd_any_uri(creator.actor_id.to_owned())?
|
||||||
|
@ -357,7 +373,7 @@ impl ApubLikeableType for Comment {
|
||||||
|
|
||||||
populate_object_props(
|
populate_object_props(
|
||||||
&mut undo.object_props,
|
&mut undo.object_props,
|
||||||
&community.get_followers_url(),
|
vec![community.get_followers_url()],
|
||||||
&undo_id,
|
&undo_id,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
|
@ -372,3 +388,57 @@ impl ApubLikeableType for Comment {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct MentionsAndAddresses {
|
||||||
|
addressed_ccs: Vec<String>,
|
||||||
|
inboxes: Vec<String>,
|
||||||
|
tags: Vec<Mention>,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// This takes a comment, and builds a list of to_addresses, inboxes,
|
||||||
|
/// and mention tags, so they know where to be sent to.
|
||||||
|
/// Addresses are the users / addresses that go in the cc field.
|
||||||
|
fn collect_non_local_mentions_and_addresses(
|
||||||
|
conn: &PgConnection,
|
||||||
|
content: &str,
|
||||||
|
community: &Community,
|
||||||
|
) -> Result<MentionsAndAddresses, Error> {
|
||||||
|
let mut addressed_ccs = vec![community.get_followers_url()];
|
||||||
|
|
||||||
|
// Add the mention tag
|
||||||
|
let mut tags = Vec::new();
|
||||||
|
|
||||||
|
// Get the inboxes for any mentions
|
||||||
|
let mentions = scrape_text_for_mentions(&content)
|
||||||
|
.into_iter()
|
||||||
|
// Filter only the non-local ones
|
||||||
|
.filter(|m| !m.is_local())
|
||||||
|
.collect::<Vec<MentionData>>();
|
||||||
|
let mut mention_inboxes = Vec::new();
|
||||||
|
for mention in &mentions {
|
||||||
|
// TODO should it be fetching it every time?
|
||||||
|
if let Ok(actor_id) = fetch_webfinger_url(mention) {
|
||||||
|
debug!("mention actor_id: {}", actor_id);
|
||||||
|
addressed_ccs.push(actor_id.to_owned());
|
||||||
|
let mention_user = get_or_fetch_and_upsert_remote_user(&actor_id, &conn)?;
|
||||||
|
let shared_inbox = mention_user.get_shared_inbox_url();
|
||||||
|
mention_inboxes.push(shared_inbox);
|
||||||
|
let mut mention_tag = Mention::new();
|
||||||
|
mention_tag
|
||||||
|
.link_props
|
||||||
|
.set_href(actor_id)?
|
||||||
|
.set_name_xsd_string(mention.full_name())?;
|
||||||
|
tags.push(mention_tag);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut inboxes = community.get_follower_inboxes(&conn)?;
|
||||||
|
inboxes.extend(mention_inboxes);
|
||||||
|
inboxes = inboxes.into_iter().unique().collect();
|
||||||
|
|
||||||
|
Ok(MentionsAndAddresses {
|
||||||
|
addressed_ccs,
|
||||||
|
inboxes,
|
||||||
|
tags,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
|
@ -114,7 +114,11 @@ impl ActorType for Community {
|
||||||
let id = format!("{}/delete/{}", self.actor_id, uuid::Uuid::new_v4());
|
let id = format!("{}/delete/{}", self.actor_id, uuid::Uuid::new_v4());
|
||||||
|
|
||||||
let mut delete = Delete::default();
|
let mut delete = Delete::default();
|
||||||
populate_object_props(&mut delete.object_props, &self.get_followers_url(), &id)?;
|
populate_object_props(
|
||||||
|
&mut delete.object_props,
|
||||||
|
vec![self.get_followers_url()],
|
||||||
|
&id,
|
||||||
|
)?;
|
||||||
|
|
||||||
delete
|
delete
|
||||||
.delete_props
|
.delete_props
|
||||||
|
@ -135,7 +139,11 @@ impl ActorType for Community {
|
||||||
let id = format!("{}/delete/{}", self.actor_id, uuid::Uuid::new_v4());
|
let id = format!("{}/delete/{}", self.actor_id, uuid::Uuid::new_v4());
|
||||||
|
|
||||||
let mut delete = Delete::default();
|
let mut delete = Delete::default();
|
||||||
populate_object_props(&mut delete.object_props, &self.get_followers_url(), &id)?;
|
populate_object_props(
|
||||||
|
&mut delete.object_props,
|
||||||
|
vec![self.get_followers_url()],
|
||||||
|
&id,
|
||||||
|
)?;
|
||||||
|
|
||||||
delete
|
delete
|
||||||
.delete_props
|
.delete_props
|
||||||
|
@ -147,7 +155,11 @@ impl ActorType for Community {
|
||||||
let undo_id = format!("{}/undo/delete/{}", self.actor_id, uuid::Uuid::new_v4());
|
let undo_id = format!("{}/undo/delete/{}", self.actor_id, uuid::Uuid::new_v4());
|
||||||
let mut undo = Undo::default();
|
let mut undo = Undo::default();
|
||||||
|
|
||||||
populate_object_props(&mut undo.object_props, &self.get_followers_url(), &undo_id)?;
|
populate_object_props(
|
||||||
|
&mut undo.object_props,
|
||||||
|
vec![self.get_followers_url()],
|
||||||
|
&undo_id,
|
||||||
|
)?;
|
||||||
|
|
||||||
undo
|
undo
|
||||||
.undo_props
|
.undo_props
|
||||||
|
@ -168,7 +180,11 @@ impl ActorType for Community {
|
||||||
let id = format!("{}/remove/{}", self.actor_id, uuid::Uuid::new_v4());
|
let id = format!("{}/remove/{}", self.actor_id, uuid::Uuid::new_v4());
|
||||||
|
|
||||||
let mut remove = Remove::default();
|
let mut remove = Remove::default();
|
||||||
populate_object_props(&mut remove.object_props, &self.get_followers_url(), &id)?;
|
populate_object_props(
|
||||||
|
&mut remove.object_props,
|
||||||
|
vec![self.get_followers_url()],
|
||||||
|
&id,
|
||||||
|
)?;
|
||||||
|
|
||||||
remove
|
remove
|
||||||
.remove_props
|
.remove_props
|
||||||
|
@ -189,7 +205,11 @@ impl ActorType for Community {
|
||||||
let id = format!("{}/remove/{}", self.actor_id, uuid::Uuid::new_v4());
|
let id = format!("{}/remove/{}", self.actor_id, uuid::Uuid::new_v4());
|
||||||
|
|
||||||
let mut remove = Remove::default();
|
let mut remove = Remove::default();
|
||||||
populate_object_props(&mut remove.object_props, &self.get_followers_url(), &id)?;
|
populate_object_props(
|
||||||
|
&mut remove.object_props,
|
||||||
|
vec![self.get_followers_url()],
|
||||||
|
&id,
|
||||||
|
)?;
|
||||||
|
|
||||||
remove
|
remove
|
||||||
.remove_props
|
.remove_props
|
||||||
|
@ -200,7 +220,11 @@ impl ActorType for Community {
|
||||||
let undo_id = format!("{}/undo/remove/{}", self.actor_id, uuid::Uuid::new_v4());
|
let undo_id = format!("{}/undo/remove/{}", self.actor_id, uuid::Uuid::new_v4());
|
||||||
let mut undo = Undo::default();
|
let mut undo = Undo::default();
|
||||||
|
|
||||||
populate_object_props(&mut undo.object_props, &self.get_followers_url(), &undo_id)?;
|
populate_object_props(
|
||||||
|
&mut undo.object_props,
|
||||||
|
vec![self.get_followers_url()],
|
||||||
|
&undo_id,
|
||||||
|
)?;
|
||||||
|
|
||||||
undo
|
undo
|
||||||
.undo_props
|
.undo_props
|
||||||
|
|
|
@ -55,7 +55,7 @@ pub fn sign(request: &Builder, actor: &dyn ActorType) -> Result<String, Error> {
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.as_str(),
|
.as_str(),
|
||||||
headers,
|
headers,
|
||||||
)
|
)?
|
||||||
.sign(signing_key_id, |signing_string| {
|
.sign(signing_key_id, |signing_string| {
|
||||||
let private_key = PKey::private_key_from_pem(actor.private_key().as_bytes())?;
|
let private_key = PKey::private_key_from_pem(actor.private_key().as_bytes())?;
|
||||||
let mut signer = Signer::new(MessageDigest::sha256(), &private_key).unwrap();
|
let mut signer = Signer::new(MessageDigest::sha256(), &private_key).unwrap();
|
||||||
|
|
|
@ -9,7 +9,6 @@ pub mod private_message;
|
||||||
pub mod shared_inbox;
|
pub mod shared_inbox;
|
||||||
pub mod user;
|
pub mod user;
|
||||||
pub mod user_inbox;
|
pub mod user_inbox;
|
||||||
|
|
||||||
use crate::api::community::CommunityResponse;
|
use crate::api::community::CommunityResponse;
|
||||||
use crate::db::activity::insert_activity;
|
use crate::db::activity::insert_activity;
|
||||||
use crate::websocket::server::SendCommunityRoomMessage;
|
use crate::websocket::server::SendCommunityRoomMessage;
|
||||||
|
@ -21,6 +20,7 @@ use activitystreams::{
|
||||||
context,
|
context,
|
||||||
endpoint::EndpointProperties,
|
endpoint::EndpointProperties,
|
||||||
ext::{Ext, Extensible},
|
ext::{Ext, Extensible},
|
||||||
|
link::Mention,
|
||||||
object::{properties::ObjectProperties, Note, Page, Tombstone},
|
object::{properties::ObjectProperties, Note, Page, Tombstone},
|
||||||
public, BaseBox,
|
public, BaseBox,
|
||||||
};
|
};
|
||||||
|
@ -38,7 +38,7 @@ use serde::{Deserialize, Serialize};
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
use url::Url;
|
use url::Url;
|
||||||
|
|
||||||
use crate::api::comment::CommentResponse;
|
use crate::api::comment::{send_local_notifs, CommentResponse};
|
||||||
use crate::api::post::PostResponse;
|
use crate::api::post::PostResponse;
|
||||||
use crate::api::site::SearchResponse;
|
use crate::api::site::SearchResponse;
|
||||||
use crate::api::user::PrivateMessageResponse;
|
use crate::api::user::PrivateMessageResponse;
|
||||||
|
@ -57,12 +57,13 @@ use crate::db::user::{UserForm, User_};
|
||||||
use crate::db::user_view::UserView;
|
use crate::db::user_view::UserView;
|
||||||
use crate::db::{Crud, Followable, Joinable, Likeable, SearchType};
|
use crate::db::{Crud, Followable, Joinable, Likeable, SearchType};
|
||||||
use crate::routes::nodeinfo::{NodeInfo, NodeInfoWellKnown};
|
use crate::routes::nodeinfo::{NodeInfo, NodeInfoWellKnown};
|
||||||
|
use crate::routes::webfinger::WebFingerResponse;
|
||||||
use crate::routes::{ChatServerParam, DbPoolParam};
|
use crate::routes::{ChatServerParam, DbPoolParam};
|
||||||
use crate::websocket::{
|
use crate::websocket::{
|
||||||
server::{SendComment, SendPost, SendUserRoomMessage},
|
server::{SendComment, SendPost, SendUserRoomMessage},
|
||||||
UserOperation,
|
UserOperation,
|
||||||
};
|
};
|
||||||
use crate::{convert_datetime, naive_now, Settings};
|
use crate::{convert_datetime, naive_now, scrape_text_for_mentions, MentionData, Settings};
|
||||||
|
|
||||||
use crate::apub::extensions::group_extensions::GroupExtension;
|
use crate::apub::extensions::group_extensions::GroupExtension;
|
||||||
use crate::apub::extensions::page_extension::PageExtension;
|
use crate::apub::extensions::page_extension::PageExtension;
|
||||||
|
@ -280,3 +281,25 @@ pub trait ActorType {
|
||||||
.to_ext()
|
.to_ext()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn fetch_webfinger_url(mention: &MentionData) -> Result<String, Error> {
|
||||||
|
let fetch_url = format!(
|
||||||
|
"{}://{}/.well-known/webfinger?resource=acct:{}@{}",
|
||||||
|
get_apub_protocol_string(),
|
||||||
|
mention.domain,
|
||||||
|
mention.name,
|
||||||
|
mention.domain
|
||||||
|
);
|
||||||
|
debug!("Fetching webfinger url: {}", &fetch_url);
|
||||||
|
let text = isahc::get(&fetch_url)?.text()?;
|
||||||
|
let res: WebFingerResponse = serde_json::from_str(&text)?;
|
||||||
|
let link = res
|
||||||
|
.links
|
||||||
|
.iter()
|
||||||
|
.find(|l| l.type_.eq(&Some("application/activity+json".to_string())))
|
||||||
|
.ok_or_else(|| format_err!("No application/activity+json link found."))?;
|
||||||
|
link
|
||||||
|
.href
|
||||||
|
.to_owned()
|
||||||
|
.ok_or_else(|| format_err!("No href found."))
|
||||||
|
}
|
||||||
|
|
|
@ -124,7 +124,7 @@ impl ApubObjectType for Post {
|
||||||
let mut create = Create::new();
|
let mut create = Create::new();
|
||||||
populate_object_props(
|
populate_object_props(
|
||||||
&mut create.object_props,
|
&mut create.object_props,
|
||||||
&community.get_followers_url(),
|
vec![community.get_followers_url()],
|
||||||
&id,
|
&id,
|
||||||
)?;
|
)?;
|
||||||
create
|
create
|
||||||
|
@ -147,7 +147,7 @@ impl ApubObjectType for Post {
|
||||||
let mut update = Update::new();
|
let mut update = Update::new();
|
||||||
populate_object_props(
|
populate_object_props(
|
||||||
&mut update.object_props,
|
&mut update.object_props,
|
||||||
&community.get_followers_url(),
|
vec![community.get_followers_url()],
|
||||||
&id,
|
&id,
|
||||||
)?;
|
)?;
|
||||||
update
|
update
|
||||||
|
@ -169,7 +169,7 @@ impl ApubObjectType for Post {
|
||||||
|
|
||||||
populate_object_props(
|
populate_object_props(
|
||||||
&mut delete.object_props,
|
&mut delete.object_props,
|
||||||
&community.get_followers_url(),
|
vec![community.get_followers_url()],
|
||||||
&id,
|
&id,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
|
@ -193,7 +193,7 @@ impl ApubObjectType for Post {
|
||||||
|
|
||||||
populate_object_props(
|
populate_object_props(
|
||||||
&mut delete.object_props,
|
&mut delete.object_props,
|
||||||
&community.get_followers_url(),
|
vec![community.get_followers_url()],
|
||||||
&id,
|
&id,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
|
@ -209,7 +209,7 @@ impl ApubObjectType for Post {
|
||||||
|
|
||||||
populate_object_props(
|
populate_object_props(
|
||||||
&mut undo.object_props,
|
&mut undo.object_props,
|
||||||
&community.get_followers_url(),
|
vec![community.get_followers_url()],
|
||||||
&undo_id,
|
&undo_id,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
|
@ -233,7 +233,7 @@ impl ApubObjectType for Post {
|
||||||
|
|
||||||
populate_object_props(
|
populate_object_props(
|
||||||
&mut remove.object_props,
|
&mut remove.object_props,
|
||||||
&community.get_followers_url(),
|
vec![community.get_followers_url()],
|
||||||
&id,
|
&id,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
|
@ -256,7 +256,7 @@ impl ApubObjectType for Post {
|
||||||
|
|
||||||
populate_object_props(
|
populate_object_props(
|
||||||
&mut remove.object_props,
|
&mut remove.object_props,
|
||||||
&community.get_followers_url(),
|
vec![community.get_followers_url()],
|
||||||
&id,
|
&id,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
|
@ -271,7 +271,7 @@ impl ApubObjectType for Post {
|
||||||
|
|
||||||
populate_object_props(
|
populate_object_props(
|
||||||
&mut undo.object_props,
|
&mut undo.object_props,
|
||||||
&community.get_followers_url(),
|
vec![community.get_followers_url()],
|
||||||
&undo_id,
|
&undo_id,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
|
@ -295,7 +295,11 @@ impl ApubLikeableType for Post {
|
||||||
let id = format!("{}/like/{}", self.ap_id, uuid::Uuid::new_v4());
|
let id = format!("{}/like/{}", self.ap_id, uuid::Uuid::new_v4());
|
||||||
|
|
||||||
let mut like = Like::new();
|
let mut like = Like::new();
|
||||||
populate_object_props(&mut like.object_props, &community.get_followers_url(), &id)?;
|
populate_object_props(
|
||||||
|
&mut like.object_props,
|
||||||
|
vec![community.get_followers_url()],
|
||||||
|
&id,
|
||||||
|
)?;
|
||||||
like
|
like
|
||||||
.like_props
|
.like_props
|
||||||
.set_actor_xsd_any_uri(creator.actor_id.to_owned())?
|
.set_actor_xsd_any_uri(creator.actor_id.to_owned())?
|
||||||
|
@ -315,7 +319,7 @@ impl ApubLikeableType for Post {
|
||||||
let mut dislike = Dislike::new();
|
let mut dislike = Dislike::new();
|
||||||
populate_object_props(
|
populate_object_props(
|
||||||
&mut dislike.object_props,
|
&mut dislike.object_props,
|
||||||
&community.get_followers_url(),
|
vec![community.get_followers_url()],
|
||||||
&id,
|
&id,
|
||||||
)?;
|
)?;
|
||||||
dislike
|
dislike
|
||||||
|
@ -335,7 +339,11 @@ impl ApubLikeableType for Post {
|
||||||
let id = format!("{}/like/{}", self.ap_id, uuid::Uuid::new_v4());
|
let id = format!("{}/like/{}", self.ap_id, uuid::Uuid::new_v4());
|
||||||
|
|
||||||
let mut like = Like::new();
|
let mut like = Like::new();
|
||||||
populate_object_props(&mut like.object_props, &community.get_followers_url(), &id)?;
|
populate_object_props(
|
||||||
|
&mut like.object_props,
|
||||||
|
vec![community.get_followers_url()],
|
||||||
|
&id,
|
||||||
|
)?;
|
||||||
like
|
like
|
||||||
.like_props
|
.like_props
|
||||||
.set_actor_xsd_any_uri(creator.actor_id.to_owned())?
|
.set_actor_xsd_any_uri(creator.actor_id.to_owned())?
|
||||||
|
@ -348,7 +356,7 @@ impl ApubLikeableType for Post {
|
||||||
|
|
||||||
populate_object_props(
|
populate_object_props(
|
||||||
&mut undo.object_props,
|
&mut undo.object_props,
|
||||||
&community.get_followers_url(),
|
vec![community.get_followers_url()],
|
||||||
&undo_id,
|
&undo_id,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
|
|
|
@ -167,12 +167,18 @@ fn receive_create_comment(
|
||||||
|
|
||||||
let comment = CommentForm::from_apub(¬e, &conn)?;
|
let comment = CommentForm::from_apub(¬e, &conn)?;
|
||||||
let inserted_comment = Comment::create(conn, &comment)?;
|
let inserted_comment = Comment::create(conn, &comment)?;
|
||||||
|
let post = Post::read(&conn, inserted_comment.post_id)?;
|
||||||
|
|
||||||
|
// Note:
|
||||||
|
// Although mentions could be gotten from the post tags (they are included there), or the ccs,
|
||||||
|
// Its much easier to scrape them from the comment body, since the API has to do that
|
||||||
|
// anyway.
|
||||||
|
let mentions = scrape_text_for_mentions(&inserted_comment.content);
|
||||||
|
let recipient_ids = send_local_notifs(&conn, &mentions, &inserted_comment, &user, &post);
|
||||||
|
|
||||||
// Refetch the view
|
// Refetch the view
|
||||||
let comment_view = CommentView::read(&conn, inserted_comment.id, None)?;
|
let comment_view = CommentView::read(&conn, inserted_comment.id, None)?;
|
||||||
|
|
||||||
// TODO get those recipient actor ids from somewhere
|
|
||||||
let recipient_ids = vec![];
|
|
||||||
let res = CommentResponse {
|
let res = CommentResponse {
|
||||||
comment: comment_view,
|
comment: comment_view,
|
||||||
recipient_ids,
|
recipient_ids,
|
||||||
|
@ -353,13 +359,15 @@ fn receive_update_comment(
|
||||||
|
|
||||||
let comment = CommentForm::from_apub(¬e, &conn)?;
|
let comment = CommentForm::from_apub(¬e, &conn)?;
|
||||||
let comment_id = Comment::read_from_apub_id(conn, &comment.ap_id)?.id;
|
let comment_id = Comment::read_from_apub_id(conn, &comment.ap_id)?.id;
|
||||||
Comment::update(conn, comment_id, &comment)?;
|
let updated_comment = Comment::update(conn, comment_id, &comment)?;
|
||||||
|
let post = Post::read(&conn, updated_comment.post_id)?;
|
||||||
|
|
||||||
|
let mentions = scrape_text_for_mentions(&updated_comment.content);
|
||||||
|
let recipient_ids = send_local_notifs(&conn, &mentions, &updated_comment, &user, &post);
|
||||||
|
|
||||||
// Refetch the view
|
// Refetch the view
|
||||||
let comment_view = CommentView::read(&conn, comment_id, None)?;
|
let comment_view = CommentView::read(&conn, comment_id, None)?;
|
||||||
|
|
||||||
// TODO get those recipient actor ids from somewhere
|
|
||||||
let recipient_ids = vec![];
|
|
||||||
let res = CommentResponse {
|
let res = CommentResponse {
|
||||||
comment: comment_view,
|
comment: comment_view,
|
||||||
recipient_ids,
|
recipient_ids,
|
||||||
|
|
|
@ -92,10 +92,6 @@ impl Community {
|
||||||
use crate::schema::community::dsl::*;
|
use crate::schema::community::dsl::*;
|
||||||
community.filter(local.eq(true)).load::<Community>(conn)
|
community.filter(local.eq(true)).load::<Community>(conn)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_url(&self) -> String {
|
|
||||||
format!("https://{}/c/{}", Settings::get().hostname, self.name)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Identifiable, Queryable, Associations, PartialEq, Debug)]
|
#[derive(Identifiable, Queryable, Associations, PartialEq, Debug)]
|
||||||
|
|
|
@ -40,6 +40,7 @@ use crate::settings::Settings;
|
||||||
use actix_web::dev::ConnectionInfo;
|
use actix_web::dev::ConnectionInfo;
|
||||||
use chrono::{DateTime, FixedOffset, Local, NaiveDateTime, Utc};
|
use chrono::{DateTime, FixedOffset, Local, NaiveDateTime, Utc};
|
||||||
use isahc::prelude::*;
|
use isahc::prelude::*;
|
||||||
|
use itertools::Itertools;
|
||||||
use lettre::smtp::authentication::{Credentials, Mechanism};
|
use lettre::smtp::authentication::{Credentials, Mechanism};
|
||||||
use lettre::smtp::extension::ClientId;
|
use lettre::smtp::extension::ClientId;
|
||||||
use lettre::smtp::ConnectionReuseParameters;
|
use lettre::smtp::ConnectionReuseParameters;
|
||||||
|
@ -103,20 +104,6 @@ pub fn slurs_vec_to_str(slurs: Vec<&str>) -> String {
|
||||||
[start, combined].concat()
|
[start, combined].concat()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn extract_usernames(test: &str) -> Vec<&str> {
|
|
||||||
let mut matches: Vec<&str> = USERNAME_MATCHES_REGEX
|
|
||||||
.find_iter(test)
|
|
||||||
.map(|mat| mat.as_str())
|
|
||||||
.collect();
|
|
||||||
|
|
||||||
// Unique
|
|
||||||
matches.sort_unstable();
|
|
||||||
matches.dedup();
|
|
||||||
|
|
||||||
// Remove /u/
|
|
||||||
matches.iter().map(|t| &t[3..]).collect()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn generate_random_string() -> String {
|
pub fn generate_random_string() -> String {
|
||||||
thread_rng().sample_iter(&Alphanumeric).take(30).collect()
|
thread_rng().sample_iter(&Alphanumeric).take(30).collect()
|
||||||
}
|
}
|
||||||
|
@ -249,9 +236,48 @@ pub fn get_ip(conn_info: &ConnectionInfo) -> String {
|
||||||
.to_string()
|
.to_string()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO nothing is done with community / group webfingers yet, so just ignore those for now
|
||||||
|
#[derive(Clone, PartialEq, Eq, Hash)]
|
||||||
|
pub struct MentionData {
|
||||||
|
pub name: String,
|
||||||
|
pub domain: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl MentionData {
|
||||||
|
pub fn is_local(&self) -> bool {
|
||||||
|
Settings::get().hostname.eq(&self.domain)
|
||||||
|
}
|
||||||
|
pub fn full_name(&self) -> String {
|
||||||
|
format!("@{}@{}", &self.name, &self.domain)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn scrape_text_for_mentions(text: &str) -> Vec<MentionData> {
|
||||||
|
let mut out: Vec<MentionData> = Vec::new();
|
||||||
|
for caps in WEBFINGER_USER_REGEX.captures_iter(text) {
|
||||||
|
out.push(MentionData {
|
||||||
|
name: caps["name"].to_string(),
|
||||||
|
domain: caps["domain"].to_string(),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
out.into_iter().unique().collect()
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use crate::{extract_usernames, is_email_regex, remove_slurs, slur_check, slurs_vec_to_str};
|
use crate::{
|
||||||
|
is_email_regex, remove_slurs, scrape_text_for_mentions, slur_check, slurs_vec_to_str,
|
||||||
|
};
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_mentions_regex() {
|
||||||
|
let text = "Just read a great blog post by [@tedu@honk.teduangst.com](/u/test). And another by !test_community@fish.teduangst.com . Another [@lemmy@lemmy_alpha:8540](/u/fish)";
|
||||||
|
let mentions = scrape_text_for_mentions(text);
|
||||||
|
|
||||||
|
assert_eq!(mentions[0].name, "tedu".to_string());
|
||||||
|
assert_eq!(mentions[0].domain, "honk.teduangst.com".to_string());
|
||||||
|
assert_eq!(mentions[1].domain, "lemmy_alpha:8540".to_string());
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_email() {
|
fn test_email() {
|
||||||
|
@ -287,13 +313,6 @@ mod tests {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_extract_usernames() {
|
|
||||||
let usernames = extract_usernames("this is a user mention for [/u/testme](/u/testme) and thats all. Oh [/u/another](/u/another) user. And the first again [/u/testme](/u/testme) okay");
|
|
||||||
let expected = vec!["another", "testme"];
|
|
||||||
assert_eq!(usernames, expected);
|
|
||||||
}
|
|
||||||
|
|
||||||
// These helped with testing
|
// These helped with testing
|
||||||
// #[test]
|
// #[test]
|
||||||
// fn test_iframely() {
|
// fn test_iframely() {
|
||||||
|
@ -320,4 +339,7 @@ lazy_static! {
|
||||||
static ref EMAIL_REGEX: Regex = Regex::new(r"^[a-zA-Z0-9.!#$%&’*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$").unwrap();
|
static ref EMAIL_REGEX: Regex = Regex::new(r"^[a-zA-Z0-9.!#$%&’*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$").unwrap();
|
||||||
static ref SLUR_REGEX: Regex = RegexBuilder::new(r"(fag(g|got|tard)?|maricos?|cock\s?sucker(s|ing)?|nig(\b|g?(a|er)?(s|z)?)\b|dindu(s?)|mudslime?s?|kikes?|mongoloids?|towel\s*heads?|\bspi(c|k)s?\b|\bchinks?|niglets?|beaners?|\bnips?\b|\bcoons?\b|jungle\s*bunn(y|ies?)|jigg?aboo?s?|\bpakis?\b|rag\s*heads?|gooks?|cunts?|bitch(es|ing|y)?|puss(y|ies?)|twats?|feminazis?|whor(es?|ing)|\bslut(s|t?y)?|\btrann?(y|ies?)|ladyboy(s?)|\b(b|re|r)tard(ed)?s?)").case_insensitive(true).build().unwrap();
|
static ref SLUR_REGEX: Regex = RegexBuilder::new(r"(fag(g|got|tard)?|maricos?|cock\s?sucker(s|ing)?|nig(\b|g?(a|er)?(s|z)?)\b|dindu(s?)|mudslime?s?|kikes?|mongoloids?|towel\s*heads?|\bspi(c|k)s?\b|\bchinks?|niglets?|beaners?|\bnips?\b|\bcoons?\b|jungle\s*bunn(y|ies?)|jigg?aboo?s?|\bpakis?\b|rag\s*heads?|gooks?|cunts?|bitch(es|ing|y)?|puss(y|ies?)|twats?|feminazis?|whor(es?|ing)|\bslut(s|t?y)?|\btrann?(y|ies?)|ladyboy(s?)|\b(b|re|r)tard(ed)?s?)").case_insensitive(true).build().unwrap();
|
||||||
static ref USERNAME_MATCHES_REGEX: Regex = Regex::new(r"/u/[a-zA-Z][0-9a-zA-Z_]*").unwrap();
|
static ref USERNAME_MATCHES_REGEX: Regex = Regex::new(r"/u/[a-zA-Z][0-9a-zA-Z_]*").unwrap();
|
||||||
|
// TODO keep this old one, it didn't work with port well tho
|
||||||
|
// static ref WEBFINGER_USER_REGEX: Regex = Regex::new(r"@(?P<name>[\w.]+)@(?P<domain>[a-zA-Z0-9._-]+\.[a-zA-Z0-9_-]+)").unwrap();
|
||||||
|
static ref WEBFINGER_USER_REGEX: Regex = Regex::new(r"@(?P<name>[\w.]+)@(?P<domain>[a-zA-Z0-9._:-]+)").unwrap();
|
||||||
}
|
}
|
||||||
|
|
|
@ -142,7 +142,6 @@ fn get_feed_community(
|
||||||
) -> Result<ChannelBuilder, failure::Error> {
|
) -> Result<ChannelBuilder, failure::Error> {
|
||||||
let site_view = SiteView::read(&conn)?;
|
let site_view = SiteView::read(&conn)?;
|
||||||
let community = Community::read_from_name(&conn, &community_name)?;
|
let community = Community::read_from_name(&conn, &community_name)?;
|
||||||
let community_url = community.get_url();
|
|
||||||
|
|
||||||
let posts = PostQueryBuilder::create(&conn)
|
let posts = PostQueryBuilder::create(&conn)
|
||||||
.listing_type(ListingType::All)
|
.listing_type(ListingType::All)
|
||||||
|
@ -155,7 +154,7 @@ fn get_feed_community(
|
||||||
let mut channel_builder = ChannelBuilder::default();
|
let mut channel_builder = ChannelBuilder::default();
|
||||||
channel_builder
|
channel_builder
|
||||||
.title(&format!("{} - {}", site_view.name, community.name))
|
.title(&format!("{} - {}", site_view.name, community.name))
|
||||||
.link(community_url)
|
.link(community.actor_id)
|
||||||
.items(items);
|
.items(items);
|
||||||
|
|
||||||
if let Some(community_desc) = community.description {
|
if let Some(community_desc) = community.description {
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
use crate::api::{Oper, Perform};
|
use crate::api::{Oper, Perform};
|
||||||
use crate::apub::get_apub_protocol_string;
|
use crate::apub::get_apub_protocol_string;
|
||||||
|
use crate::db::community::Community;
|
||||||
use crate::db::site_view::SiteView;
|
use crate::db::site_view::SiteView;
|
||||||
|
use crate::db::user::User_;
|
||||||
use crate::rate_limit::rate_limiter::RateLimiter;
|
use crate::rate_limit::rate_limiter::RateLimiter;
|
||||||
use crate::websocket::{server::ChatServer, WebsocketInfo};
|
use crate::websocket::{server::ChatServer, WebsocketInfo};
|
||||||
use crate::{get_ip, markdown_to_html, version, Settings};
|
use crate::{get_ip, markdown_to_html, version, Settings};
|
||||||
|
@ -13,11 +15,10 @@ use diesel::{
|
||||||
r2d2::{ConnectionManager, Pool},
|
r2d2::{ConnectionManager, Pool},
|
||||||
PgConnection,
|
PgConnection,
|
||||||
};
|
};
|
||||||
use log::{error, info};
|
use log::{debug, error, info};
|
||||||
use regex::Regex;
|
use regex::Regex;
|
||||||
use rss::{CategoryBuilder, ChannelBuilder, GuidBuilder, Item, ItemBuilder};
|
use rss::{CategoryBuilder, ChannelBuilder, GuidBuilder, Item, ItemBuilder};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use serde_json::json;
|
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
use std::sync::{Arc, Mutex};
|
use std::sync::{Arc, Mutex};
|
||||||
use std::time::{Duration, Instant};
|
use std::time::{Duration, Instant};
|
||||||
|
|
|
@ -1,11 +1,27 @@
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::db::community::Community;
|
|
||||||
|
|
||||||
#[derive(Deserialize)]
|
#[derive(Deserialize)]
|
||||||
pub struct Params {
|
pub struct Params {
|
||||||
resource: String,
|
resource: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Debug)]
|
||||||
|
pub struct WebFingerResponse {
|
||||||
|
pub subject: String,
|
||||||
|
pub aliases: Vec<String>,
|
||||||
|
pub links: Vec<WebFingerLink>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Debug)]
|
||||||
|
pub struct WebFingerLink {
|
||||||
|
pub rel: Option<String>,
|
||||||
|
#[serde(rename(serialize = "type", deserialize = "type"))]
|
||||||
|
pub type_: Option<String>,
|
||||||
|
pub href: Option<String>,
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub template: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
pub fn config(cfg: &mut web::ServiceConfig) {
|
pub fn config(cfg: &mut web::ServiceConfig) {
|
||||||
if Settings::get().federation.enabled {
|
if Settings::get().federation.enabled {
|
||||||
cfg.route(
|
cfg.route(
|
||||||
|
@ -21,6 +37,11 @@ lazy_static! {
|
||||||
Settings::get().hostname
|
Settings::get().hostname
|
||||||
))
|
))
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
static ref WEBFINGER_USER_REGEX: Regex = Regex::new(&format!(
|
||||||
|
"^acct:([a-z0-9_]{{3, 20}})@{}$",
|
||||||
|
Settings::get().hostname
|
||||||
|
))
|
||||||
|
.unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Responds to webfinger requests of the following format. There isn't any real documentation for
|
/// Responds to webfinger requests of the following format. There isn't any real documentation for
|
||||||
|
@ -36,46 +57,58 @@ async fn get_webfinger_response(
|
||||||
let res = web::block(move || {
|
let res = web::block(move || {
|
||||||
let conn = db.get()?;
|
let conn = db.get()?;
|
||||||
|
|
||||||
let regex_parsed = WEBFINGER_COMMUNITY_REGEX
|
let community_regex_parsed = WEBFINGER_COMMUNITY_REGEX
|
||||||
.captures(&info.resource)
|
.captures(&info.resource)
|
||||||
.map(|c| c.get(1))
|
.map(|c| c.get(1))
|
||||||
.flatten();
|
.flatten();
|
||||||
let community_name = match regex_parsed {
|
|
||||||
Some(c) => c.as_str(),
|
|
||||||
None => return Err(format_err!("not_found")),
|
|
||||||
};
|
|
||||||
|
|
||||||
|
let user_regex_parsed = WEBFINGER_USER_REGEX
|
||||||
|
.captures(&info.resource)
|
||||||
|
.map(|c| c.get(1))
|
||||||
|
.flatten();
|
||||||
|
|
||||||
|
let url = if let Some(community_name) = community_regex_parsed {
|
||||||
// Make sure the requested community exists.
|
// Make sure the requested community exists.
|
||||||
let community = match Community::read_from_name(&conn, &community_name) {
|
let community = match Community::read_from_name(&conn, &community_name.as_str()) {
|
||||||
Ok(o) => o,
|
Ok(o) => o,
|
||||||
Err(_) => return Err(format_err!("not_found")),
|
Err(_) => return Err(format_err!("not_found")),
|
||||||
};
|
};
|
||||||
|
community.actor_id
|
||||||
|
} else if let Some(user_name) = user_regex_parsed {
|
||||||
|
// Make sure the requested user exists.
|
||||||
|
let user = match User_::read_from_name(&conn, &user_name.as_str()) {
|
||||||
|
Ok(o) => o,
|
||||||
|
Err(_) => return Err(format_err!("not_found")),
|
||||||
|
};
|
||||||
|
user.actor_id
|
||||||
|
} else {
|
||||||
|
return Err(format_err!("not_found"));
|
||||||
|
};
|
||||||
|
|
||||||
let community_url = community.get_url();
|
let wf_res = WebFingerResponse {
|
||||||
|
subject: info.resource.to_owned(),
|
||||||
Ok(json!({
|
aliases: vec![url.to_owned()],
|
||||||
"subject": info.resource,
|
links: vec![
|
||||||
"aliases": [
|
WebFingerLink {
|
||||||
community_url,
|
rel: Some("http://webfinger.net/rel/profile-page".to_string()),
|
||||||
],
|
type_: Some("text/html".to_string()),
|
||||||
"links": [
|
href: Some(url.to_owned()),
|
||||||
{
|
template: None,
|
||||||
"rel": "http://webfinger.net/rel/profile-page",
|
|
||||||
"type": "text/html",
|
|
||||||
"href": community.get_url(),
|
|
||||||
},
|
},
|
||||||
{
|
WebFingerLink {
|
||||||
"rel": "self",
|
rel: Some("self".to_string()),
|
||||||
"type": "application/activity+json",
|
type_: Some("application/activity+json".to_string()),
|
||||||
"href": community_url
|
href: Some(url),
|
||||||
}
|
template: None,
|
||||||
// TODO: this also needs to return the subscribe link once that's implemented
|
}, // TODO: this also needs to return the subscribe link once that's implemented
|
||||||
//{
|
//{
|
||||||
// "rel": "http://ostatus.org/schema/1.0/subscribe",
|
// "rel": "http://ostatus.org/schema/1.0/subscribe",
|
||||||
// "template": "https://my_instance.com/authorize_interaction?uri={uri}"
|
// "template": "https://my_instance.com/authorize_interaction?uri={uri}"
|
||||||
//}
|
//}
|
||||||
]
|
],
|
||||||
}))
|
};
|
||||||
|
|
||||||
|
Ok(wf_res)
|
||||||
})
|
})
|
||||||
.await
|
.await
|
||||||
.map(|json| HttpResponse::Ok().json(json))
|
.map(|json| HttpResponse::Ok().json(json))
|
||||||
|
|
|
@ -143,7 +143,7 @@ impl WSSession {
|
||||||
// check client heartbeats
|
// check client heartbeats
|
||||||
if Instant::now().duration_since(act.hb) > CLIENT_TIMEOUT {
|
if Instant::now().duration_since(act.hb) > CLIENT_TIMEOUT {
|
||||||
// heartbeat timed out
|
// heartbeat timed out
|
||||||
error!("Websocket Client heartbeat failed, disconnecting!");
|
debug!("Websocket Client heartbeat failed, disconnecting!");
|
||||||
|
|
||||||
// notify chat server
|
// notify chat server
|
||||||
act.cs_addr.do_send(Disconnect {
|
act.cs_addr.do_send(Disconnect {
|
||||||
|
|
45
ui/src/api_tests/api.spec.ts
vendored
45
ui/src/api_tests/api.spec.ts
vendored
|
@ -22,6 +22,7 @@ import {
|
||||||
EditPrivateMessageForm,
|
EditPrivateMessageForm,
|
||||||
PrivateMessageResponse,
|
PrivateMessageResponse,
|
||||||
PrivateMessagesResponse,
|
PrivateMessagesResponse,
|
||||||
|
GetUserMentionsResponse,
|
||||||
} from '../interfaces';
|
} from '../interfaces';
|
||||||
|
|
||||||
let lemmyAlphaUrl = 'http://localhost:8540';
|
let lemmyAlphaUrl = 'http://localhost:8540';
|
||||||
|
@ -379,6 +380,44 @@ describe('main', () => {
|
||||||
expect(getPostResAlpha.comments[0].community_local).toBe(false);
|
expect(getPostResAlpha.comments[0].community_local).toBe(false);
|
||||||
expect(getPostResAlpha.comments[0].creator_local).toBe(false);
|
expect(getPostResAlpha.comments[0].creator_local).toBe(false);
|
||||||
expect(getPostResAlpha.comments[0].score).toBe(1);
|
expect(getPostResAlpha.comments[0].score).toBe(1);
|
||||||
|
|
||||||
|
// Lemmy alpha responds to their own comment, but mentions lemmy beta.
|
||||||
|
// Make sure lemmy beta gets that in their inbox.
|
||||||
|
let mentionContent = 'A test mention of @lemmy_beta@lemmy_beta:8550';
|
||||||
|
let mentionCommentForm: CommentForm = {
|
||||||
|
content: mentionContent,
|
||||||
|
post_id: 2,
|
||||||
|
parent_id: createResponse.comment.id,
|
||||||
|
auth: lemmyAlphaAuth,
|
||||||
|
};
|
||||||
|
|
||||||
|
let createMentionRes: CommentResponse = await fetch(
|
||||||
|
`${lemmyAlphaApiUrl}/comment`,
|
||||||
|
{
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
},
|
||||||
|
body: wrapper(mentionCommentForm),
|
||||||
|
}
|
||||||
|
).then(d => d.json());
|
||||||
|
|
||||||
|
expect(createMentionRes.comment.content).toBe(mentionContent);
|
||||||
|
expect(createMentionRes.comment.community_local).toBe(false);
|
||||||
|
expect(createMentionRes.comment.creator_local).toBe(true);
|
||||||
|
expect(createMentionRes.comment.score).toBe(1);
|
||||||
|
|
||||||
|
// Make sure lemmy beta sees that new mention
|
||||||
|
let getMentionUrl = `${lemmyBetaApiUrl}/user/mention?sort=New&unread_only=false&auth=${lemmyBetaAuth}`;
|
||||||
|
let getMentionsRes: GetUserMentionsResponse = await fetch(getMentionUrl, {
|
||||||
|
method: 'GET',
|
||||||
|
}).then(d => d.json());
|
||||||
|
|
||||||
|
// The newest show up first
|
||||||
|
expect(getMentionsRes.mentions[0].content).toBe(mentionContent);
|
||||||
|
expect(getMentionsRes.mentions[0].community_local).toBe(true);
|
||||||
|
expect(getMentionsRes.mentions[0].creator_local).toBe(false);
|
||||||
|
expect(getMentionsRes.mentions[0].score).toBe(1);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -413,9 +452,9 @@ describe('main', () => {
|
||||||
method: 'GET',
|
method: 'GET',
|
||||||
}).then(d => d.json());
|
}).then(d => d.json());
|
||||||
|
|
||||||
expect(getPostRes.comments[1].content).toBe(content);
|
expect(getPostRes.comments[2].content).toBe(content);
|
||||||
expect(getPostRes.comments[1].community_local).toBe(true);
|
expect(getPostRes.comments[2].community_local).toBe(true);
|
||||||
expect(getPostRes.comments[1].creator_local).toBe(false);
|
expect(getPostRes.comments[2].creator_local).toBe(false);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
21
ui/src/utils.ts
vendored
21
ui/src/utils.ts
vendored
|
@ -502,8 +502,8 @@ export function setupTribute(): Tribute {
|
||||||
trigger: '@',
|
trigger: '@',
|
||||||
selectTemplate: (item: any) => {
|
selectTemplate: (item: any) => {
|
||||||
let link = item.original.local
|
let link = item.original.local
|
||||||
? `[@${item.original.key}](/u/${item.original.key})`
|
? `[${item.original.key}](/u/${item.original.name})`
|
||||||
: `[@${item.original.key}](/user/${item.original.id})`;
|
: `[${item.original.key}](/user/${item.original.id})`;
|
||||||
return link;
|
return link;
|
||||||
},
|
},
|
||||||
values: (text: string, cb: any) => {
|
values: (text: string, cb: any) => {
|
||||||
|
@ -520,8 +520,8 @@ export function setupTribute(): Tribute {
|
||||||
trigger: '!',
|
trigger: '!',
|
||||||
selectTemplate: (item: any) => {
|
selectTemplate: (item: any) => {
|
||||||
let link = item.original.local
|
let link = item.original.local
|
||||||
? `[!${item.original.key}](/c/${item.original.key})`
|
? `[${item.original.key}](/c/${item.original.name})`
|
||||||
: `[!${item.original.key}](/community/${item.original.id})`;
|
: `[${item.original.key}](/community/${item.original.id})`;
|
||||||
return link;
|
return link;
|
||||||
},
|
},
|
||||||
values: (text: string, cb: any) => {
|
values: (text: string, cb: any) => {
|
||||||
|
@ -565,9 +565,9 @@ function userSearch(text: string, cb: any) {
|
||||||
if (res.op == UserOperation.Search) {
|
if (res.op == UserOperation.Search) {
|
||||||
let data = res.data as SearchResponse;
|
let data = res.data as SearchResponse;
|
||||||
let users = data.users.map(u => {
|
let users = data.users.map(u => {
|
||||||
let name_ = u.local ? u.name : `${u.name}@${hostname(u.actor_id)}`;
|
|
||||||
return {
|
return {
|
||||||
key: name_,
|
key: `@${u.name}@${hostname(u.actor_id)}`,
|
||||||
|
name: u.name,
|
||||||
local: u.local,
|
local: u.local,
|
||||||
id: u.id,
|
id: u.id,
|
||||||
};
|
};
|
||||||
|
@ -602,9 +602,9 @@ function communitySearch(text: string, cb: any) {
|
||||||
if (res.op == UserOperation.Search) {
|
if (res.op == UserOperation.Search) {
|
||||||
let data = res.data as SearchResponse;
|
let data = res.data as SearchResponse;
|
||||||
let communities = data.communities.map(c => {
|
let communities = data.communities.map(c => {
|
||||||
let name_ = c.local ? c.name : `${c.name}@${hostname(c.actor_id)}`;
|
|
||||||
return {
|
return {
|
||||||
key: name_,
|
key: `!${c.name}@${hostname(c.actor_id)}`,
|
||||||
|
name: c.name,
|
||||||
local: c.local,
|
local: c.local,
|
||||||
id: c.id,
|
id: c.id,
|
||||||
};
|
};
|
||||||
|
@ -859,5 +859,8 @@ export function previewLines(text: string, lines: number = 3): string {
|
||||||
}
|
}
|
||||||
|
|
||||||
export function hostname(url: string): string {
|
export function hostname(url: string): string {
|
||||||
return new URL(url).hostname;
|
let cUrl = new URL(url);
|
||||||
|
return window.location.port
|
||||||
|
? `${cUrl.hostname}:${cUrl.port}`
|
||||||
|
: `${cUrl.hostname}`;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue