Compare commits
3 commits
0afd1de14e
...
8fa30c7a15
Author | SHA1 | Date | |
---|---|---|---|
8fa30c7a15 | |||
9cd3d474ae | |||
|
a7fc8f22c1 |
13 changed files with 248 additions and 237 deletions
133
Cargo.lock
generated
133
Cargo.lock
generated
|
@ -30,9 +30,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "ahash"
|
||||
version = "0.8.7"
|
||||
version = "0.8.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "77c3a9648d43b9cd48db467b3f87fdd6e146bcc88ab0180006cef2179fe11d01"
|
||||
checksum = "42cd52102d3df161c77a887b608d7a4897d7cc112886a9537b738a887a03aaff"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"getrandom",
|
||||
|
@ -80,9 +80,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "anstream"
|
||||
version = "0.6.11"
|
||||
version = "0.6.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6e2e1ebcb11de5c03c67de28a7df593d32191b44939c482e97702baaaa6ab6a5"
|
||||
checksum = "96b09b5178381e0874812a9b157f7fe84982617e48f71f4e3235482775e5b540"
|
||||
dependencies = [
|
||||
"anstyle",
|
||||
"anstyle-parse",
|
||||
|
@ -128,9 +128,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "anyhow"
|
||||
version = "1.0.79"
|
||||
version = "1.0.80"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "080e9890a082662b09c1ad45f567faeeb47f22b5fb23895fbe1e651e718e25ca"
|
||||
checksum = "5ad32ce52e4161730f7098c077cd2ed6229b5804ccf99e5366be1ab72a98b4e1"
|
||||
|
||||
[[package]]
|
||||
name = "argon2"
|
||||
|
@ -169,7 +169,7 @@ checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.48",
|
||||
"syn 2.0.49",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -180,7 +180,7 @@ checksum = "c980ee35e870bd1a4d2c8294d4c04d0499e67bca1e4b5cefcc693c2fa00caea9"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.48",
|
||||
"syn 2.0.49",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -387,15 +387,15 @@ dependencies = [
|
|||
"proc-macro-crate",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.48",
|
||||
"syn 2.0.49",
|
||||
"syn_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bumpalo"
|
||||
version = "3.14.0"
|
||||
version = "3.15.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec"
|
||||
checksum = "d32a994c2b3ca201d9b263612a374263f05e7adde37c4707f693dcd375076d1f"
|
||||
|
||||
[[package]]
|
||||
name = "bytecheck"
|
||||
|
@ -460,9 +460,9 @@ checksum = "fd16c4719339c4530435d38e511904438d07cce7950afa3718a84ac36c10e89e"
|
|||
|
||||
[[package]]
|
||||
name = "chrono"
|
||||
version = "0.4.33"
|
||||
version = "0.4.34"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9f13690e35a5e4ace198e7beea2895d29f3a9cc55015fcebe6336bd2010af9eb"
|
||||
checksum = "5bc015644b92d5890fab7489e49d21f879d5c990186827d42ec511919404f38b"
|
||||
dependencies = [
|
||||
"android-tzdata",
|
||||
"iana-time-zone",
|
||||
|
@ -485,9 +485,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "clap"
|
||||
version = "4.5.0"
|
||||
version = "4.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "80c21025abd42669a92efc996ef13cfb2c5c627858421ea58d5c3b331a6c134f"
|
||||
checksum = "c918d541ef2913577a0f9566e9ce27cb35b6df072075769e0b26cb5a554520da"
|
||||
dependencies = [
|
||||
"clap_builder",
|
||||
"clap_derive",
|
||||
|
@ -495,9 +495,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "clap_builder"
|
||||
version = "4.5.0"
|
||||
version = "4.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "458bf1f341769dfcf849846f65dffdf9146daa56bcd2a47cb4e1de9915567c99"
|
||||
checksum = "9f3e7391dad68afb0c2ede1bf619f579a3dc9c2ec67f089baa397123a2f3d1eb"
|
||||
dependencies = [
|
||||
"anstream",
|
||||
"anstyle",
|
||||
|
@ -514,7 +514,7 @@ dependencies = [
|
|||
"heck",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.48",
|
||||
"syn 2.0.49",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -616,7 +616,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "30d2b3721e861707777e3195b0158f950ae6dc4a27e4d02ff9f67e3eb3de199e"
|
||||
dependencies = [
|
||||
"quote",
|
||||
"syn 2.0.48",
|
||||
"syn 2.0.49",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -964,7 +964,7 @@ version = "0.14.3"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604"
|
||||
dependencies = [
|
||||
"ahash 0.8.7",
|
||||
"ahash 0.8.8",
|
||||
"allocator-api2",
|
||||
]
|
||||
|
||||
|
@ -988,9 +988,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "hermit-abi"
|
||||
version = "0.3.5"
|
||||
version = "0.3.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d0c62115964e08cb8039170eb33c1d0e2388a256930279edca206fff675f82c3"
|
||||
checksum = "bd5256b483761cd23699d0da46cc6fd2ee3be420bbe6d020ae4a091e70b7e9fd"
|
||||
|
||||
[[package]]
|
||||
name = "hex"
|
||||
|
@ -1118,9 +1118,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "indexmap"
|
||||
version = "2.2.2"
|
||||
version = "2.2.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "824b2ae422412366ba479e8111fd301f7b5faece8149317bb81925979a53f520"
|
||||
checksum = "233cf39063f058ea2caae4091bf4a3ef70a653afbc026f5c4a4135d114e3c177"
|
||||
dependencies = [
|
||||
"equivalent",
|
||||
"hashbrown 0.14.3",
|
||||
|
@ -1134,7 +1134,7 @@ checksum = "0122b7114117e64a63ac49f752a5ca4624d534c7b1c7de796ac196381cd2d947"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.48",
|
||||
"syn 2.0.49",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1191,7 +1191,7 @@ version = "0.17.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2a071f4f7efc9a9118dfb627a0a94ef247986e1ab8606a4c806ae2b3aa3b6978"
|
||||
dependencies = [
|
||||
"ahash 0.8.7",
|
||||
"ahash 0.8.8",
|
||||
"anyhow",
|
||||
"base64",
|
||||
"bytecount",
|
||||
|
@ -1355,9 +1355,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "napi-build"
|
||||
version = "2.1.0"
|
||||
version = "2.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d4b4532cf86bfef556348ac65e561e3123879f0e7566cca6d43a6ff5326f13df"
|
||||
checksum = "2f9130fccc5f763cf2069b34a089a18f0d0883c66aceb81f2fad541a3d823c43"
|
||||
|
||||
[[package]]
|
||||
name = "napi-derive"
|
||||
|
@ -1370,14 +1370,14 @@ dependencies = [
|
|||
"napi-derive-backend",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.48",
|
||||
"syn 2.0.49",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "napi-derive-backend"
|
||||
version = "1.0.60"
|
||||
version = "1.0.61"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6cf2d74ac66fd1cccb646be75fdd1c1dce8acfe20a68f61566a31da0d3eb9786"
|
||||
checksum = "d03b8f403a37007cad225039fc0323b961bb40d697eea744140920ebb689ff1d"
|
||||
dependencies = [
|
||||
"convert_case",
|
||||
"once_cell",
|
||||
|
@ -1385,7 +1385,7 @@ dependencies = [
|
|||
"quote",
|
||||
"regex",
|
||||
"semver",
|
||||
"syn 2.0.48",
|
||||
"syn 2.0.49",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1578,7 +1578,7 @@ dependencies = [
|
|||
"proc-macro-error",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.48",
|
||||
"syn 2.0.49",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1627,7 +1627,7 @@ dependencies = [
|
|||
"regex",
|
||||
"regex-syntax 0.7.5",
|
||||
"structmeta",
|
||||
"syn 2.0.48",
|
||||
"syn 2.0.49",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1697,9 +1697,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "pkg-config"
|
||||
version = "0.3.29"
|
||||
version = "0.3.30"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2900ede94e305130c13ddd391e0ab7cbaeb783945ae07a279c268cb05109c6cb"
|
||||
checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec"
|
||||
|
||||
[[package]]
|
||||
name = "powerfmt"
|
||||
|
@ -1921,16 +1921,17 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "ring"
|
||||
version = "0.17.7"
|
||||
version = "0.17.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "688c63d65483050968b2a8937f7995f443e27041a0f7700aa59b0822aedebb74"
|
||||
checksum = "c17fa4cb658e3583423e915b9f3acc01cceaee1860e33d59ebae66adc3a2dc0d"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"cfg-if",
|
||||
"getrandom",
|
||||
"libc",
|
||||
"spin 0.9.8",
|
||||
"untrusted",
|
||||
"windows-sys 0.48.0",
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -2049,9 +2050,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "ryu"
|
||||
version = "1.0.16"
|
||||
version = "1.0.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f98d2aa92eebf49b69786be48e4477826b256916e84a57ff2a4f21923b48eb4c"
|
||||
checksum = "e86697c916019a8588c99b5fac3cead74ec0b4b819707a682fd4d23fa0ce1ba1"
|
||||
|
||||
[[package]]
|
||||
name = "schemars"
|
||||
|
@ -2104,7 +2105,7 @@ dependencies = [
|
|||
"proc-macro-error",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.48",
|
||||
"syn 2.0.49",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -2145,7 +2146,7 @@ dependencies = [
|
|||
"proc-macro2",
|
||||
"quote",
|
||||
"sea-bae",
|
||||
"syn 2.0.48",
|
||||
"syn 2.0.49",
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
|
@ -2190,9 +2191,9 @@ checksum = "1c107b6f4780854c8b126e228ea8869f4d7b71260f962fefb57b996b8959ba6b"
|
|||
|
||||
[[package]]
|
||||
name = "semver"
|
||||
version = "1.0.21"
|
||||
version = "1.0.22"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b97ed7a9823b74f99c7742f5336af7be5ecd3eeafcb1507d1fa93347b1d589b0"
|
||||
checksum = "92d43fe69e652f3df9bdc2b85b2854a0825b86e4fb76bc44d945137d053639ca"
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
|
@ -2211,7 +2212,7 @@ checksum = "33c85360c95e7d137454dc81d9a4ed2b8efd8fbe19cee57357b32b9771fccb67"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.48",
|
||||
"syn 2.0.49",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -2250,9 +2251,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "serde_yaml"
|
||||
version = "0.9.31"
|
||||
version = "0.9.32"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "adf8a49373e98a4c5f0ceb5d05aa7c648d75f63774981ed95b7c7443bbd50c6e"
|
||||
checksum = "8fd075d994154d4a774f95b51fb96bdc2832b0ea48425c92546073816cda1f2f"
|
||||
dependencies = [
|
||||
"indexmap",
|
||||
"itoa",
|
||||
|
@ -2398,7 +2399,7 @@ version = "0.7.3"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d84b0a3c3739e220d94b3239fd69fb1f74bc36e16643423bd99de3b43c21bfbd"
|
||||
dependencies = [
|
||||
"ahash 0.8.7",
|
||||
"ahash 0.8.8",
|
||||
"atoi",
|
||||
"bigdecimal",
|
||||
"byteorder",
|
||||
|
@ -2630,7 +2631,7 @@ dependencies = [
|
|||
"proc-macro2",
|
||||
"quote",
|
||||
"structmeta-derive",
|
||||
"syn 2.0.48",
|
||||
"syn 2.0.49",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -2641,7 +2642,7 @@ checksum = "a60bcaff7397072dca0017d1db428e30d5002e00b6847703e2e42005c95fbe00"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.48",
|
||||
"syn 2.0.49",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -2669,9 +2670,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.48"
|
||||
version = "2.0.49"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0f3531638e407dfc0814761abb7c00a5b54992b849452a0646b7f65c9f770f3f"
|
||||
checksum = "915aea9e586f80826ee59f8453c1101f9d1c4b3964cd2460185ee8e299ada496"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
|
@ -2687,7 +2688,7 @@ dependencies = [
|
|||
"proc-macro-error",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.48",
|
||||
"syn 2.0.49",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -2737,22 +2738,22 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "thiserror"
|
||||
version = "1.0.56"
|
||||
version = "1.0.57"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d54378c645627613241d077a3a79db965db602882668f9136ac42af9ecb730ad"
|
||||
checksum = "1e45bcbe8ed29775f228095caf2cd67af7a4ccf756ebff23a306bf3e8b47b24b"
|
||||
dependencies = [
|
||||
"thiserror-impl",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror-impl"
|
||||
version = "1.0.56"
|
||||
version = "1.0.57"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fa0faa943b50f3db30a20aa7e265dbc66076993efed8463e8de414e5d06d3471"
|
||||
checksum = "a953cb265bef375dae3de6663da4d3804eee9682ea80d8e2542529b73c531c81"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.48",
|
||||
"syn 2.0.49",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -2828,7 +2829,7 @@ checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.48",
|
||||
"syn 2.0.49",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -2899,7 +2900,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.48",
|
||||
"syn 2.0.49",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -3048,7 +3049,7 @@ dependencies = [
|
|||
"once_cell",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.48",
|
||||
"syn 2.0.49",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
||||
|
@ -3082,7 +3083,7 @@ checksum = "642f325be6301eb8107a83d12a8ac6c1e1c54345a7ef1a9261962dfefda09e66"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.48",
|
||||
"syn 2.0.49",
|
||||
"wasm-bindgen-backend",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
@ -3258,9 +3259,9 @@ checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04"
|
|||
|
||||
[[package]]
|
||||
name = "winnow"
|
||||
version = "0.5.39"
|
||||
version = "0.5.40"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5389a154b01683d28c77f8f68f49dea75f0a4da32557a58f68ee51ebba472d29"
|
||||
checksum = "f593a95398737aeed53e489c785df13f3618e41dbcd6718c6addbf1395aa6876"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
@ -3307,7 +3308,7 @@ checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.48",
|
||||
"syn 2.0.49",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use crate::config::server::SERVER_CONFIG;
|
||||
use crate::database::NapiDbErrExt;
|
||||
use crate::prelude::to_napi_error;
|
||||
use sea_orm::{Database, DbConn};
|
||||
use urlencoding::encode;
|
||||
|
||||
|
@ -23,9 +23,7 @@ pub async fn connect_to_database() -> napi::Result<JsDbConn> {
|
|||
SERVER_CONFIG.db.port,
|
||||
SERVER_CONFIG.db.db,
|
||||
);
|
||||
let conn = Database::connect(conn_uri)
|
||||
.await
|
||||
.map_err(NapiDbErrExt::into)?;
|
||||
let conn = Database::connect(conn_uri).await.map_err(to_napi_error)?;
|
||||
Ok(JsDbConn { inner: conn })
|
||||
}
|
||||
|
|
@ -1,22 +0,0 @@
|
|||
use sea_orm::error::DbErr;
|
||||
|
||||
use crate::impl_napi_error_from;
|
||||
|
||||
#[derive(thiserror::Error, Debug, PartialEq, Eq)]
|
||||
pub enum Error {
|
||||
#[error("The database connections have not been initialized yet")]
|
||||
Uninitialized,
|
||||
#[error("ORM error: {0}")]
|
||||
OrmError(#[from] DbErr),
|
||||
}
|
||||
|
||||
impl_napi_error_from!(Error);
|
||||
|
||||
pub trait NapiDbErrExt {
|
||||
fn into(self) -> napi::Error;
|
||||
}
|
||||
impl NapiDbErrExt for DbErr {
|
||||
fn into(self) -> napi::Error {
|
||||
napi::Error::from_reason(self.to_string())
|
||||
}
|
||||
}
|
|
@ -1,5 +0,0 @@
|
|||
pub mod connect;
|
||||
pub mod error;
|
||||
|
||||
pub use connect::JsDbConn;
|
||||
pub use error::NapiDbErrExt;
|
|
@ -4,8 +4,6 @@ use crate::impl_napi_error_from;
|
|||
pub enum Error {
|
||||
#[error("Failed to parse string: {0}")]
|
||||
ParseError(#[from] parse_display::ParseError),
|
||||
#[error("Failed to get database connection: {0}")]
|
||||
DbConnError(#[from] crate::database::error::Error),
|
||||
#[error("Database operation error: {0}")]
|
||||
DbOperationError(#[from] sea_orm::DbErr),
|
||||
#[error("Requested entity not found")]
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
use crate::database::JsDbConn;
|
||||
use crate::model::entity::{drive_file, note};
|
||||
use crate::prelude::*;
|
||||
use once_cell::sync::Lazy;
|
||||
use regex::Regex;
|
||||
use sea_orm::prelude::*;
|
||||
|
||||
// FIXME: remove this type
|
||||
#[napi_derive::napi(object)]
|
||||
pub struct NoteLike {
|
||||
pub file_ids: Vec<String>,
|
||||
|
@ -15,82 +15,76 @@ pub struct NoteLike {
|
|||
pub reply_id: Option<String>,
|
||||
}
|
||||
|
||||
async fn full_text(conn: &JsDbConn, note: NoteLike) -> String {
|
||||
let mut to_return = format!(
|
||||
"{}\n{}\n",
|
||||
note.text.unwrap_or_default(),
|
||||
note.cw.unwrap_or_default(),
|
||||
);
|
||||
async fn all_texts(conn: &JsDbConn, note: NoteLike) -> napi::Result<Vec<String>> {
|
||||
let mut texts: Vec<String> = vec![];
|
||||
|
||||
if let Some(text) = note.text {
|
||||
texts.push(text);
|
||||
}
|
||||
if let Some(cw) = note.cw {
|
||||
texts.push(cw);
|
||||
}
|
||||
|
||||
for file_id in note.file_ids {
|
||||
if let Some(alt_text) = drive_file::Entity::find_by_id(file_id)
|
||||
.one(conn.inner())
|
||||
.await
|
||||
.expect("Failed to connect to the database")
|
||||
.expect("file_id is invalid")
|
||||
.map_err(to_napi_error)?
|
||||
.ok_or_else(|| to_napi_error("file_id is invalid"))?
|
||||
.comment
|
||||
{
|
||||
to_return.push_str(alt_text.as_str());
|
||||
to_return.push('\n');
|
||||
texts.push(alt_text);
|
||||
}
|
||||
}
|
||||
|
||||
if note.renote_id.is_some() {
|
||||
to_return.push_str(
|
||||
note::Entity::find_by_id(note.renote_id.unwrap())
|
||||
if let Some(renote_id) = note.renote_id {
|
||||
if let Some(text) = note::Entity::find_by_id(renote_id)
|
||||
.one(conn.inner())
|
||||
.await
|
||||
.expect("Failed to connect to the database")
|
||||
.expect("renote_id is invalid")
|
||||
.map_err(to_napi_error)?
|
||||
.ok_or_else(|| to_napi_error("renote_id is invalid"))?
|
||||
.text
|
||||
.unwrap_or_default()
|
||||
.as_str(),
|
||||
);
|
||||
to_return.push('\n');
|
||||
{
|
||||
texts.push(text);
|
||||
}
|
||||
}
|
||||
|
||||
if note.reply_id.is_some() {
|
||||
to_return.push_str(
|
||||
note::Entity::find_by_id(note.reply_id.unwrap())
|
||||
if let Some(reply_id) = note.reply_id {
|
||||
if let Some(text) = note::Entity::find_by_id(reply_id)
|
||||
.one(conn.inner())
|
||||
.await
|
||||
.expect("Failed to connect to the database")
|
||||
.expect("reply_id is invalid")
|
||||
.map_err(to_napi_error)?
|
||||
.ok_or_else(|| to_napi_error("reply_id is invalid"))?
|
||||
.text
|
||||
.unwrap_or_default()
|
||||
.as_str(),
|
||||
);
|
||||
{
|
||||
texts.push(text);
|
||||
}
|
||||
}
|
||||
|
||||
to_return.trim().to_owned()
|
||||
Ok(texts)
|
||||
}
|
||||
|
||||
// FIXME: remove this funtion
|
||||
fn convert_regex(js_regex: String) -> String {
|
||||
fn convert_regex(js_regex: &str) -> String {
|
||||
static RE: Lazy<Regex> = Lazy::new(|| Regex::new(r"^/(.+)/(.*)$").unwrap());
|
||||
RE.replace(&js_regex, "(?$2)$1").to_string()
|
||||
RE.replace(js_regex, "(?$2)$1").to_string()
|
||||
}
|
||||
|
||||
async fn check_word_mute_impl(
|
||||
text: String,
|
||||
muted_word_lists: Vec<Vec<String>>,
|
||||
muted_patterns: Vec<String>,
|
||||
fn check_word_mute_impl(
|
||||
texts: &[String],
|
||||
muted_word_lists: &[Vec<String>],
|
||||
muted_patterns: &[String],
|
||||
) -> bool {
|
||||
if text.is_empty() {
|
||||
return false;
|
||||
}
|
||||
|
||||
let text_lowercase = text.to_lowercase();
|
||||
|
||||
muted_word_lists.into_iter().any(|muted_word_list| {
|
||||
muted_word_lists.iter().any(|muted_word_list| {
|
||||
texts.iter().any(|text| {
|
||||
let text_lower = text.to_lowercase();
|
||||
muted_word_list
|
||||
.into_iter()
|
||||
.all(|muted_word| text_lowercase.contains(&muted_word.to_lowercase()))
|
||||
}) || muted_patterns.into_iter().any(|muted_patten| {
|
||||
match Regex::new(convert_regex(muted_patten).as_str()) {
|
||||
Ok(re) => re.is_match(&text),
|
||||
Err(_) => false,
|
||||
}
|
||||
.iter()
|
||||
.all(|muted_word| text_lower.contains(muted_word))
|
||||
})
|
||||
}) || muted_patterns.iter().any(|muted_pattern| {
|
||||
Regex::new(convert_regex(muted_pattern).as_str())
|
||||
.map(|re| texts.iter().any(|text| re.is_match(text)))
|
||||
.unwrap_or(false)
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -100,15 +94,14 @@ pub async fn check_word_mute(
|
|||
note: NoteLike,
|
||||
muted_word_lists: Vec<Vec<String>>,
|
||||
muted_patterns: Vec<String>,
|
||||
) -> bool {
|
||||
) -> napi::Result<bool> {
|
||||
if muted_word_lists.is_empty() && muted_patterns.is_empty() {
|
||||
false
|
||||
Ok(false)
|
||||
} else {
|
||||
check_word_mute_impl(
|
||||
full_text(conn, note).await,
|
||||
muted_word_lists,
|
||||
muted_patterns,
|
||||
)
|
||||
.await
|
||||
Ok(check_word_mute_impl(
|
||||
&all_texts(conn, note).await?,
|
||||
&muted_word_lists,
|
||||
&muted_patterns,
|
||||
))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,44 +1,52 @@
|
|||
use crate::config::server::SERVER_CONFIG;
|
||||
use crate::prelude::to_napi_error;
|
||||
use idna;
|
||||
use url::Url;
|
||||
|
||||
#[napi_derive::napi]
|
||||
pub fn get_full_ap_account(username: String, host: Option<String>) -> String {
|
||||
if host.is_none() {
|
||||
format!("{}@{}", username, extract_host(SERVER_CONFIG.url.clone()))
|
||||
} else {
|
||||
format!("{}@{}", username, to_puny(host.unwrap()))
|
||||
}
|
||||
pub fn get_full_ap_account(username: String, host: Option<String>) -> napi::Result<String> {
|
||||
Ok(match host {
|
||||
Some(host) => format!("{}@{}", username, to_puny(&host)?),
|
||||
None => format!("{}@{}", username, extract_host(&SERVER_CONFIG.url)?),
|
||||
})
|
||||
}
|
||||
|
||||
#[napi_derive::napi]
|
||||
pub fn is_self_host(host: Option<String>) -> bool {
|
||||
if let Some(x) = host {
|
||||
extract_host(SERVER_CONFIG.url.clone()) == to_puny(x)
|
||||
} else {
|
||||
true
|
||||
}
|
||||
pub fn is_self_host(host: Option<String>) -> napi::Result<bool> {
|
||||
Ok(match host {
|
||||
Some(host) => extract_host(&SERVER_CONFIG.url)? == to_puny(&host)?,
|
||||
None => true,
|
||||
})
|
||||
}
|
||||
|
||||
#[napi_derive::napi]
|
||||
pub fn extract_host(uri: String) -> String {
|
||||
to_puny(
|
||||
Url::parse(uri.as_str())
|
||||
.expect("Invalid uri")
|
||||
fn extract_host(uri: &str) -> napi::Result<String> {
|
||||
Url::parse(uri)
|
||||
.map_err(to_napi_error)?
|
||||
.host_str()
|
||||
.unwrap()
|
||||
.to_string(),
|
||||
)
|
||||
.ok_or_else(|| to_napi_error("Hostname is missing"))
|
||||
.and_then(to_puny)
|
||||
}
|
||||
|
||||
#[napi_derive::napi(js_name = "extractHost")]
|
||||
pub fn extract_host_js(uri: String) -> napi::Result<String> {
|
||||
extract_host(&uri)
|
||||
}
|
||||
|
||||
fn to_puny(host: &str) -> napi::Result<String> {
|
||||
idna::domain_to_ascii(host).map_err(to_napi_error)
|
||||
}
|
||||
|
||||
#[napi_derive::napi(js_name = "toPuny")]
|
||||
pub fn to_puny_js(host: String) -> napi::Result<String> {
|
||||
to_puny(&host)
|
||||
}
|
||||
|
||||
#[napi_derive::napi]
|
||||
pub fn to_puny(host: String) -> String {
|
||||
idna::domain_to_ascii(&host).expect("Failed to encode the host to punycode")
|
||||
}
|
||||
|
||||
#[napi_derive::napi]
|
||||
pub fn to_puny_optional(host: Option<String>) -> Option<String> {
|
||||
host.map(to_puny)
|
||||
pub fn to_puny_optional(host: Option<String>) -> napi::Result<Option<String>> {
|
||||
Ok(match host {
|
||||
Some(host) => Some(to_puny(&host)?),
|
||||
None => None,
|
||||
})
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
@ -49,15 +57,15 @@ mod unit_test {
|
|||
#[test]
|
||||
fn extract_host_test() {
|
||||
assert_eq!(
|
||||
extract_host("https://git.joinfirefish.org/firefish/firefish.git".to_string()),
|
||||
"git.joinfirefish.org".to_string()
|
||||
extract_host("https://firefish.dev/firefish/firefish.git").unwrap(),
|
||||
"firefish.dev".to_string()
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn to_puny_test() {
|
||||
assert_eq!(
|
||||
to_puny("何もかも.owari.shop".to_string()),
|
||||
to_puny("何もかも.owari.shop").unwrap(),
|
||||
"xn--u8jyfb5762a.owari.shop".to_string()
|
||||
);
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
use crate::database::{JsDbConn, NapiDbErrExt};
|
||||
use crate::database::JsDbConn;
|
||||
use crate::model::entity::meta;
|
||||
use crate::prelude::to_napi_error;
|
||||
use rand::prelude::*;
|
||||
use sea_orm::{prelude::*, ActiveValue};
|
||||
use std::sync::Mutex;
|
||||
|
@ -22,10 +23,7 @@ pub async fn fetch_meta(conn: &JsDbConn, invalidate_cache: Option<bool>) -> napi
|
|||
|
||||
// try fetching from db
|
||||
let db = conn.inner();
|
||||
let meta = meta::Entity::find()
|
||||
.one(db)
|
||||
.await
|
||||
.map_err(NapiDbErrExt::into)?;
|
||||
let meta = meta::Entity::find().one(db).await.map_err(to_napi_error)?;
|
||||
if let Some(meta) = meta {
|
||||
update_cache(&meta);
|
||||
return Ok(meta);
|
||||
|
@ -38,7 +36,7 @@ pub async fn fetch_meta(conn: &JsDbConn, invalidate_cache: Option<bool>) -> napi
|
|||
})
|
||||
.exec_with_returning(db)
|
||||
.await
|
||||
.map_err(NapiDbErrExt::into)?;
|
||||
.map_err(to_napi_error)?;
|
||||
update_cache(&meta);
|
||||
Ok(meta)
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
use crate::database::{JsDbConn, NapiDbErrExt};
|
||||
use crate::database::JsDbConn;
|
||||
use crate::model::entity::note;
|
||||
use crate::prelude::to_napi_error;
|
||||
use sea_orm::prelude::*;
|
||||
|
||||
/**
|
||||
|
@ -21,5 +22,5 @@ pub async fn has_other_renote_of_this_note(
|
|||
.one(conn.inner())
|
||||
.await
|
||||
.map(|row| row.is_some())
|
||||
.map_err(NapiDbErrExt::into)
|
||||
.map_err(to_napi_error)
|
||||
}
|
||||
|
|
|
@ -65,7 +65,8 @@ export function createSignedGet(args: {
|
|||
method: "GET",
|
||||
headers: objectAssignWithLcKey(
|
||||
{
|
||||
Accept: "application/activity+json, application/ld+json",
|
||||
Accept:
|
||||
'application/activity+json, application/ld+json; profile="https://www.w3.org/ns/activitystreams"',
|
||||
Date: new Date().toUTCString(),
|
||||
Host: new URL(args.url).hostname,
|
||||
},
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
import config from "@/config/index.js";
|
||||
import { getUserKeypair } from "@/misc/keypair-store.js";
|
||||
import type { User } from "@/models/entities/user.js";
|
||||
import { getResponse } from "../../misc/fetch.js";
|
||||
import type { User, ILocalUser } from "@/models/entities/user.js";
|
||||
import { getResponse } from "@/misc/fetch.js";
|
||||
import { createSignedPost, createSignedGet } from "./ap-request.js";
|
||||
import { apLogger } from "@/remote/activitypub/logger.js";
|
||||
import type { Response } from "node-fetch";
|
||||
import type { IObject } from "./type.js";
|
||||
|
||||
export default async (user: { id: User["id"] }, url: string, object: any) => {
|
||||
const body = JSON.stringify(object);
|
||||
|
@ -31,14 +32,15 @@ export default async (user: { id: User["id"] }, url: string, object: any) => {
|
|||
};
|
||||
|
||||
/**
|
||||
* Get AP object with http-signature
|
||||
* Get ActivityPub object
|
||||
* @param user http-signature user
|
||||
* @param url URL to fetch
|
||||
*/
|
||||
export async function signedGet(url: string, user: { id: User["id"] }) {
|
||||
apLogger.debug(`Running signedGet on url: ${url}`);
|
||||
const keypair = await getUserKeypair(user.id);
|
||||
export async function apGet(url: string, user?: ILocalUser): Promise<IObject> {
|
||||
let res: Response;
|
||||
|
||||
if (user != null) {
|
||||
const keypair = await getUserKeypair(user.id);
|
||||
const req = createSignedGet({
|
||||
key: {
|
||||
privateKeyPem: keypair.privateKey,
|
||||
|
@ -50,11 +52,44 @@ export async function signedGet(url: string, user: { id: User["id"] }) {
|
|||
},
|
||||
});
|
||||
|
||||
const res = await getResponse({
|
||||
res = await getResponse({
|
||||
url,
|
||||
method: req.request.method,
|
||||
headers: req.request.headers,
|
||||
});
|
||||
} else {
|
||||
res = await getResponse({
|
||||
url,
|
||||
method: "GET",
|
||||
headers: {
|
||||
Accept:
|
||||
'application/activity+json, application/ld+json; profile="https://www.w3.org/ns/activitystreams"',
|
||||
"User-Agent": config.userAgent,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
return await res.json();
|
||||
const contentType = res.headers.get("content-type");
|
||||
if (contentType == null || !validateContentType(contentType)) {
|
||||
throw new Error("Invalid Content Type");
|
||||
}
|
||||
|
||||
if (res.body == null) throw new Error("body is null");
|
||||
|
||||
const text = await res.text();
|
||||
if (text.length > 65536) throw new Error("too big result");
|
||||
|
||||
return JSON.parse(text) as IObject;
|
||||
}
|
||||
|
||||
function validateContentType(contentType: string): boolean {
|
||||
const parts = contentType.split(/\s*;\s*/);
|
||||
if (parts[0] === "application/activity+json") return true;
|
||||
if (parts[0] !== "application/ld+json") return false;
|
||||
return parts
|
||||
.slice(1)
|
||||
.some(
|
||||
(part) =>
|
||||
part.trim() === 'profile="https://www.w3.org/ns/activitystreams"',
|
||||
);
|
||||
}
|
||||
|
|
|
@ -1,10 +1,9 @@
|
|||
import config from "@/config/index.js";
|
||||
import { getJson } from "@/misc/fetch.js";
|
||||
import type { ILocalUser } from "@/models/entities/user.js";
|
||||
import { getInstanceActor } from "@/services/instance-actor.js";
|
||||
import { fetchMeta } from "@/misc/backend-rs.js";
|
||||
import { extractHost, isSelfHost } from "backend-rs";
|
||||
import { signedGet } from "./request.js";
|
||||
import { apGet } from "./request.js";
|
||||
import type { IObject, ICollection, IOrderedCollection } from "./type.js";
|
||||
import { isCollectionOrOrderedCollection, getApId } from "./type.js";
|
||||
import { Notes, NoteReactions, Polls, Users } from "@/models/index.js";
|
||||
|
@ -114,11 +113,7 @@ export default class Resolver {
|
|||
apLogger.debug("Getting object from remote, authenticated as user:");
|
||||
apLogger.debug(JSON.stringify(this.user, null, 2));
|
||||
|
||||
const object = (
|
||||
this.user
|
||||
? await signedGet(value, this.user)
|
||||
: await getJson(value, "application/activity+json, application/ld+json")
|
||||
) as IObject;
|
||||
const object = await apGet(value, this.user);
|
||||
|
||||
if (
|
||||
object == null ||
|
||||
|
|
|
@ -161,7 +161,17 @@ export default async function (ctx: Koa.Context) {
|
|||
|
||||
// When doing a conditional request, we MUST return a "Cache-Control" header
|
||||
// if a normal 200 response would have included.
|
||||
ctx.set("Cache-Control", "max-age=31536000, immutable");
|
||||
if (contentType === "application/octet-stream") {
|
||||
ctx.vary("Accept");
|
||||
ctx.set("Cache-Control", "private, max-age=0, must-revalidate");
|
||||
|
||||
if (ctx.header.accept?.match(/activity\+json|ld\+json/)) {
|
||||
ctx.status = 400;
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
ctx.set("Cache-Control", "max-age=2592000, s-maxage=172800, immutable");
|
||||
}
|
||||
|
||||
if (ctx.fresh) {
|
||||
ctx.status = 304;
|
||||
|
|
Loading…
Reference in a new issue