diff --git a/Cargo.lock b/Cargo.lock index 56b60df..0b07e51 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,6 +1,6 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. -version = 3 +version = 4 [[package]] name = "addr2line" @@ -17,19 +17,6 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" -[[package]] -name = "ahash" -version = "0.8.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" -dependencies = [ - "cfg-if", - "getrandom", - "once_cell", - "version_check", - "zerocopy", -] - [[package]] name = "aho-corasick" version = "1.1.3" @@ -128,57 +115,44 @@ dependencies = [ [[package]] name = "askama" -version = "0.12.1" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b79091df18a97caea757e28cd2d5fda49c6cd4bd01ddffd7ff01ace0c0ad2c28" +checksum = "f75363874b771be265f4ffe307ca705ef6f3baa19011c149da8674a87f1b75c4" dependencies = [ "askama_derive", - "askama_escape", - "humansize", - "num-traits", + "itoa", "percent-encoding", -] - -[[package]] -name = "askama_axum" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a41603f7cdbf5ac4af60760f17253eb6adf6ec5b6f14a7ed830cf687d375f163" -dependencies = [ - "askama", - "axum-core", - "http 1.1.0", + "serde", + "serde_json", ] [[package]] name = "askama_derive" -version = "0.12.5" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "19fe8d6cb13c4714962c072ea496f3392015f0989b1a2847bb4b2d9effd71d83" +checksum = "129397200fe83088e8a68407a8e2b1f826cf0086b21ccdb866a722c8bcd3a94f" dependencies = [ "askama_parser", "basic-toml", - "mime", - "mime_guess", + "memchr", "proc-macro2", "quote", + "rustc-hash", "serde", - "syn 2.0.59", + "serde_derive", + "syn 2.0.106", ] -[[package]] -name = "askama_escape" -version = "0.10.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "619743e34b5ba4e9703bba34deac3427c72507c7159f5fd030aea8cac0cfe341" - [[package]] name = "askama_parser" -version = "0.2.1" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "acb1161c6b64d1c3d83108213c2a2533a342ac225aabd0bda218278c2ddb00c0" +checksum = "d6ab5630b3d5eaf232620167977f95eb51f3432fc76852328774afbd242d4358" dependencies = [ - "nom", + "memchr", + "serde", + "serde_derive", + "winnow 0.7.13", ] [[package]] @@ -189,7 +163,7 @@ checksum = "c6fa2087f2753a7da8cc1c0dbfcf89579dd57458e36769de5ac750b4671737ca" dependencies = [ "proc-macro2", "quote", - "syn 2.0.59", + "syn 2.0.106", ] [[package]] @@ -220,8 +194,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3a6c9af12842a67734c9a2e355436e5d03b22383ed60cf13cd0c18fbfe3dcbcf" dependencies = [ "async-trait", - "axum-core", - "axum-macros", + "axum-core 0.4.3", "bytes", "futures-util", "http 1.1.0", @@ -230,7 +203,7 @@ dependencies = [ "hyper", "hyper-util", "itoa", - "matchit", + "matchit 0.7.3", "memchr", "mime", "percent-encoding", @@ -242,7 +215,42 @@ dependencies = [ "serde_urlencoded", "sync_wrapper 1.0.1", "tokio", - "tower", + "tower 0.4.13", + "tower-layer", + "tower-service", + "tracing", +] + +[[package]] +name = "axum" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "021e862c184ae977658b36c4500f7feac3221ca5da43e3f25bd04ab6c79a29b5" +dependencies = [ + "axum-core 0.5.2", + "axum-macros", + "bytes", + "form_urlencoded", + "futures-util", + "http 1.1.0", + "http-body", + "http-body-util", + "hyper", + "hyper-util", + "itoa", + "matchit 0.8.4", + "memchr", + "mime", + "percent-encoding", + "pin-project-lite", + "rustversion", + "serde", + "serde_json", + "serde_path_to_error", + "serde_urlencoded", + "sync_wrapper 1.0.1", + "tokio", + "tower 0.5.2", "tower-layer", "tower-service", "tracing", @@ -270,17 +278,36 @@ dependencies = [ ] [[package]] -name = "axum-login" -version = "0.14.0" +name = "axum-core" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf7d8260dd72d25b5d97f47a0ac6436fb7d07237ff6df10620ee21351de7df5a" +checksum = "68464cd0412f486726fb3373129ef5d2993f90c34bc2bc1c1e9943b2f4fc7ca6" dependencies = [ - "async-trait", - "axum", + "bytes", + "futures-core", + "http 1.1.0", + "http-body", + "http-body-util", + "mime", + "pin-project-lite", + "rustversion", + "sync_wrapper 1.0.1", + "tower-layer", + "tower-service", + "tracing", +] + +[[package]] +name = "axum-login" +version = "0.18.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "964ea6eb764a227baa8c3368e45c94d23b6863cc7b880c6c9e341c143c5a5ff7" +dependencies = [ + "axum 0.8.4", "form_urlencoded", - "ring", "serde", - "thiserror", + "subtle", + "thiserror 2.0.16", "tower-cookies", "tower-layer", "tower-service", @@ -291,14 +318,13 @@ dependencies = [ [[package]] name = "axum-macros" -version = "0.4.1" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00c055ee2d014ae5981ce1016374e8213682aa14d9bf40e48ab48b5f3ef20eaa" +checksum = "604fde5e028fea851ce1d8570bbdc034bec850d157f7569d10f347d06808c05c" dependencies = [ - "heck 0.4.1", "proc-macro2", "quote", - "syn 2.0.59", + "syn 2.0.106", ] [[package]] @@ -310,7 +336,7 @@ dependencies = [ "anyhow", "async-trait", "auto-future", - "axum", + "axum 0.7.5", "bytes", "cookie", "http 1.1.0", @@ -326,7 +352,7 @@ dependencies = [ "serde_urlencoded", "smallvec", "tokio", - "tower", + "tower 0.4.13", "url", ] @@ -345,12 +371,6 @@ dependencies = [ "rustc-demangle", ] -[[package]] -name = "base64" -version = "0.21.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" - [[package]] name = "base64" version = "0.22.0" @@ -425,9 +445,12 @@ checksum = "514de17de45fdb8dc022b1a7975556c53c86f9f0aa5f534b98977b171857c2c9" [[package]] name = "cc" -version = "1.0.94" +version = "1.2.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17f6e324229dc011159fcc089755d1e2e216a90d43a7dea6853ca740b84f35e7" +checksum = "42bc4aea80032b7bf409b0bc7ccad88853858911b7713a8062fdc0623867bedc" +dependencies = [ + "shlex", +] [[package]] name = "cfg-if" @@ -437,16 +460,15 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "chrono" -version = "0.4.29" +version = "0.4.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d87d9d13be47a5b7c3907137f1290b0459a7f80efb26be8c52afb11963bccb02" +checksum = "c469d952047f47f91b68d1cba3f10d63c11d73e4636f24f08daf0278abf01c4d" dependencies = [ "android-tzdata", "iana-time-zone", "num-traits", "serde", - "time 0.1.45", - "windows-targets 0.48.5", + "windows-link", ] [[package]] @@ -479,10 +501,10 @@ version = "4.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "528131438037fd55894f62d6e9f068b8f45ac57ffa77517819645d10aed04f64" dependencies = [ - "heck 0.5.0", + "heck", "proc-macro2", "quote", - "syn 2.0.59", + "syn 2.0.106", ] [[package]] @@ -498,14 +520,23 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "acbf1af155f9b9ef647e42cdc158db4b64a1b61f743629225fde6f3e0be2a7c7" [[package]] -name = "confy" -version = "0.6.1" +name = "concurrent-queue" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45b1f4c00870f07dc34adcac82bb6a72cc5aabca8536ba1797e01df51d2ce9a0" +checksum = "4ca0197aee26d1ae37445ee532fefce43251d24cc7c166799f4d46817f1d3973" +dependencies = [ + "crossbeam-utils", +] + +[[package]] +name = "confy" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f29222b549d4e3ded127989d523da9e928918d0d0d7f7c1690b439d0d538bae9" dependencies = [ "directories", "serde", - "thiserror", + "thiserror 2.0.16", "toml", ] @@ -522,7 +553,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4ddef33a339a91ea89fb53151bd0a4689cfce27055c291dfa69945475d22c747" dependencies = [ "percent-encoding", - "time 0.3.36", + "time", "version_check", ] @@ -622,32 +653,32 @@ dependencies = [ [[package]] name = "directories" -version = "5.0.1" +version = "6.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a49173b84e034382284f27f1af4dcbbd231ffa358c0fe316541a7337f376a35" +checksum = "16f5094c54661b38d03bd7e50df373292118db60b585c08a411c6d840017fe7d" dependencies = [ "dirs-sys", ] [[package]] name = "dirs" -version = "5.0.1" +version = "6.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44c45a9d03d6676652bcb5e724c7e988de1acad23a711b5217ab9cbecbec2225" +checksum = "c3e8aa94d75141228480295a7d0e7feb620b1a5ad9f12bc40be62411e38cce4e" dependencies = [ "dirs-sys", ] [[package]] name = "dirs-sys" -version = "0.4.1" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "520f05a5cbd335fae5a99ff7a6ab8627577660ee5cfd6a94a6a929b52ff0321c" +checksum = "e01a3366d27ee9890022452ee61b2b63a67e6f13f58900b651ff5665f0bb1fab" dependencies = [ "libc", "option-ext", "redox_users", - "windows-sys 0.48.0", + "windows-sys 0.60.2", ] [[package]] @@ -671,16 +702,6 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" -[[package]] -name = "errno" -version = "0.3.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a258e46cdc063eb8519c00b9fc845fc47bcfca4130e2f08e88665ceda8474245" -dependencies = [ - "libc", - "windows-sys 0.52.0", -] - [[package]] name = "etcetera" version = "0.8.0" @@ -694,15 +715,14 @@ dependencies = [ [[package]] name = "event-listener" -version = "2.5.3" +version = "5.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" - -[[package]] -name = "fastrand" -version = "2.0.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "658bd65b1cf4c852a3cc96f18a8ce7b5640f6b703f905c7d74532294c2a63984" +checksum = "e13b66accf52311f30a0db42147dadea9850cb48cd070028831ae5f5d4b856ab" +dependencies = [ + "concurrent-queue", + "parking", + "pin-project-lite", +] [[package]] name = "finl_unicode" @@ -727,6 +747,12 @@ version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" +[[package]] +name = "foldhash" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" + [[package]] name = "form_urlencoded" version = "1.2.1" @@ -802,7 +828,7 @@ checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" dependencies = [ "proc-macro2", "quote", - "syn 2.0.59", + "syn 2.0.106", ] [[package]] @@ -853,7 +879,7 @@ dependencies = [ "cfg-if", "js-sys", "libc", - "wasi 0.11.0+wasi-snapshot-preview1", + "wasi", "wasm-bindgen", ] @@ -868,27 +894,25 @@ name = "hashbrown" version = "0.14.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" + +[[package]] +name = "hashbrown" +version = "0.15.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1" dependencies = [ - "ahash", "allocator-api2", + "equivalent", + "foldhash", ] [[package]] name = "hashlink" -version = "0.8.4" +version = "0.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8094feaf31ff591f651a2664fb9cfd92bba7a60ce3197265e9482ebe753c8f7" +checksum = "7382cf6263419f2d8df38c55d7da83da5c18aef87fc7a7fc1fb1e344edfe14c1" dependencies = [ - "hashbrown", -] - -[[package]] -name = "heck" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" -dependencies = [ - "unicode-segmentation", + "hashbrown 0.15.5", ] [[package]] @@ -897,12 +921,6 @@ version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" -[[package]] -name = "hermit-abi" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d231dfb89cfffdbc30e7fc41579ed6066ad03abda9e567ccafae602b97ec5024" - [[package]] name = "hex" version = "0.4.3" @@ -999,15 +1017,6 @@ version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" -[[package]] -name = "humansize" -version = "2.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6cb51c9a029ddc91b07a787f1d86b53ccfa49b0e86688c946ebe8d3555685dd7" -dependencies = [ - "libm", -] - [[package]] name = "hyper" version = "1.2.0" @@ -1043,7 +1052,7 @@ dependencies = [ "pin-project-lite", "socket2", "tokio", - "tower", + "tower 0.4.13", "tower-service", "tracing", ] @@ -1088,16 +1097,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26" dependencies = [ "equivalent", - "hashbrown", + "hashbrown 0.14.3", ] [[package]] -name = "itertools" -version = "0.12.1" +name = "io-uring" +version = "0.7.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba291022dbbd398a455acf126c1e341954079855bc60dfdda641363bd6922569" +checksum = "046fa2d4d00aea763528b4950358d0ead425372445dc8ff86312b3c69ff7727b" dependencies = [ - "either", + "bitflags 2.5.0", + "cfg-if", + "libc", ] [[package]] @@ -1117,9 +1128,9 @@ dependencies = [ [[package]] name = "julid-rs" -version = "1.6.18033988" +version = "1.6.1803398874989" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "82f75e4d7184b798c5b8e3b9ead1a3d1ea121091a84089bb39138e6a5500ca61" +checksum = "45d220e514a000f51e153655b164326d07e0bceb731345ee27b69f2fa843ea9b" dependencies = [ "chrono", "clap", @@ -1150,9 +1161,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.153" +version = "0.2.175" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd" +checksum = "6a82ae493e598baaea5209805c49bbf2ea7de956d50d7da0da1164f9c6d28543" [[package]] name = "libm" @@ -1172,21 +1183,15 @@ dependencies = [ [[package]] name = "libsqlite3-sys" -version = "0.27.0" +version = "0.30.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf4e226dcd58b4be396f7bd3c20da8fdee2911400705297ba7d2d7cc2c30f716" +checksum = "2e99fb7a497b1e3339bc746195567ed8d3e24945ecd636e3619d20b9de9e9149" dependencies = [ "cc", "pkg-config", "vcpkg", ] -[[package]] -name = "linux-raw-sys" -version = "0.4.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c" - [[package]] name = "lock_api" version = "0.4.11" @@ -1219,6 +1224,12 @@ version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0e7465ac9959cc2b1404e8e2367b43684a6d13790fe23056cc8c6c5a6b7bcb94" +[[package]] +name = "matchit" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "47e1ffaa40ddd1f3ed91f717a33c8c0ee23fff369e3aa8772b9605cc1d22f4c3" + [[package]] name = "md-5" version = "0.10.6" @@ -1251,12 +1262,6 @@ dependencies = [ "unicase", ] -[[package]] -name = "minimal-lexical" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" - [[package]] name = "miniz_oxide" version = "0.7.2" @@ -1268,23 +1273,13 @@ dependencies = [ [[package]] name = "mio" -version = "0.8.11" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c" +checksum = "2886843bf800fba2e3377cff24abf6379b4c4d5c6681eaf9ea5b0d15090450bd" dependencies = [ "libc", - "wasi 0.11.0+wasi-snapshot-preview1", - "windows-sys 0.48.0", -] - -[[package]] -name = "nom" -version = "7.1.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" -dependencies = [ - "memchr", - "minimal-lexical", + "wasi", + "windows-sys 0.52.0", ] [[package]] @@ -1397,16 +1392,6 @@ dependencies = [ "libm", ] -[[package]] -name = "num_cpus" -version = "1.16.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4161fcb6d602d4d2081af7c3a45852d875a03dd337a6bfdd6e06407b61342a43" -dependencies = [ - "hermit-abi", - "libc", -] - [[package]] name = "object" version = "0.32.2" @@ -1433,7 +1418,7 @@ name = "optional_optional_user" version = "0.1.0" dependencies = [ "quote", - "syn 2.0.59", + "syn 2.0.106", ] [[package]] @@ -1442,6 +1427,12 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" +[[package]] +name = "parking" +version = "2.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f38d5652c16fde515bb1ecef450ab0f6a219d619a7274976324d5e377f7dceba" + [[package]] name = "parking_lot" version = "0.12.1" @@ -1537,7 +1528,7 @@ checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" dependencies = [ "proc-macro2", "quote", - "syn 2.0.59", + "syn 2.0.106", ] [[package]] @@ -1603,9 +1594,9 @@ dependencies = [ [[package]] name = "proc-macro2" -version = "1.0.80" +version = "1.0.101" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a56dea16b0a29e94408b9aa5e2940a4eedbd128a1ba20e8f7ae60fd3d465af0e" +checksum = "89ae43fd86e4158d6db51ad8e2b80f313af9cc74f5c0e03ccb87de09998732de" dependencies = [ "unicode-ident", ] @@ -1660,13 +1651,13 @@ dependencies = [ [[package]] name = "redox_users" -version = "0.4.5" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd283d9651eeda4b2a83a43c1c91b266c40fd76ecd39a50a8c630ae69dc72891" +checksum = "a4e608c6638b9c18977b00b475ac1f28d14e84b27d8d42f70e0bf1e3dec127ac" dependencies = [ "getrandom", "libredox", - "thiserror", + "thiserror 2.0.16", ] [[package]] @@ -1720,22 +1711,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9838134a2bfaa8e1f40738fcc972ac799de6e0e06b5157acb95fc2b05a0ea283" dependencies = [ "lazy_static", - "thiserror", -] - -[[package]] -name = "ring" -version = "0.17.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c17fa4cb658e3583423e915b9f3acc01cceaee1860e33d59ebae66adc3a2dc0d" -dependencies = [ - "cc", - "cfg-if", - "getrandom", - "libc", - "spin 0.9.8", - "untrusted", - "windows-sys 0.52.0", + "thiserror 1.0.58", ] [[package]] @@ -1793,7 +1769,7 @@ dependencies = [ "mime", "mime_guess", "rand", - "thiserror", + "thiserror 1.0.58", ] [[package]] @@ -1803,17 +1779,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" [[package]] -name = "rustix" -version = "0.38.32" +name = "rustc-hash" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "65e04861e65f21776e67888bfbea442b3642beaa0138fdb1dd7a84a52dffdb89" -dependencies = [ - "bitflags 2.5.0", - "errno", - "libc", - "linux-raw-sys", - "windows-sys 0.52.0", -] +checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d" [[package]] name = "rustversion" @@ -1850,7 +1819,7 @@ checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.59", + "syn 2.0.106", ] [[package]] @@ -1938,6 +1907,12 @@ dependencies = [ "lazy_static", ] +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + [[package]] name = "signal-hook-registry" version = "1.4.1" @@ -1971,6 +1946,9 @@ name = "smallvec" version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" +dependencies = [ + "serde", +] [[package]] name = "socket2" @@ -2007,22 +1985,11 @@ dependencies = [ "der", ] -[[package]] -name = "sqlformat" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce81b7bd7c4493975347ef60d8c7e8b742d4694f4c49f93e0a12ea263938176c" -dependencies = [ - "itertools", - "nom", - "unicode_categories", -] - [[package]] name = "sqlx" -version = "0.7.4" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c9a2ccff1a000a5a59cd33da541d9f2fdcd9e6e8229cc200565942bff36d0aaa" +checksum = "1fefb893899429669dcdd979aff487bd78f4064e5e7907e4269081e0ef7d97dc" dependencies = [ "sqlx-core", "sqlx-macros", @@ -2033,39 +2000,34 @@ dependencies = [ [[package]] name = "sqlx-core" -version = "0.7.4" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24ba59a9342a3d9bab6c56c118be528b27c9b60e490080e9711a04dccac83ef6" +checksum = "ee6798b1838b6a0f69c007c133b8df5866302197e404e8b6ee8ed3e3a5e68dc6" dependencies = [ - "ahash", - "atoi", - "byteorder", + "base64", "bytes", "chrono", "crc", "crossbeam-queue", "either", "event-listener", - "futures-channel", "futures-core", "futures-intrusive", "futures-io", "futures-util", + "hashbrown 0.15.5", "hashlink", - "hex", "indexmap", "log", "memchr", "once_cell", - "paste", "percent-encoding", "serde", "serde_json", "sha2", "smallvec", - "sqlformat", - "thiserror", - "time 0.3.36", + "thiserror 2.0.16", + "time", "tokio", "tokio-stream", "tracing", @@ -2074,26 +2036,26 @@ dependencies = [ [[package]] name = "sqlx-macros" -version = "0.7.4" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ea40e2345eb2faa9e1e5e326db8c34711317d2b5e08d0d5741619048a803127" +checksum = "a2d452988ccaacfbf5e0bdbc348fb91d7c8af5bee192173ac3636b5fb6e6715d" dependencies = [ "proc-macro2", "quote", "sqlx-core", "sqlx-macros-core", - "syn 1.0.109", + "syn 2.0.106", ] [[package]] name = "sqlx-macros-core" -version = "0.7.4" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5833ef53aaa16d860e92123292f1f6a3d53c34ba8b1969f152ef1a7bb803f3c8" +checksum = "19a9c1841124ac5a61741f96e1d9e2ec77424bf323962dd894bdb93f37d5219b" dependencies = [ "dotenvy", "either", - "heck 0.4.1", + "heck", "hex", "once_cell", "proc-macro2", @@ -2105,20 +2067,19 @@ dependencies = [ "sqlx-mysql", "sqlx-postgres", "sqlx-sqlite", - "syn 1.0.109", - "tempfile", + "syn 2.0.106", "tokio", "url", ] [[package]] name = "sqlx-mysql" -version = "0.7.4" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ed31390216d20e538e447a7a9b959e06ed9fc51c37b514b46eb758016ecd418" +checksum = "aa003f0038df784eb8fecbbac13affe3da23b45194bd57dba231c8f48199c526" dependencies = [ "atoi", - "base64 0.21.7", + "base64", "bitflags 2.5.0", "byteorder", "bytes", @@ -2149,20 +2110,20 @@ dependencies = [ "smallvec", "sqlx-core", "stringprep", - "thiserror", - "time 0.3.36", + "thiserror 2.0.16", + "time", "tracing", "whoami", ] [[package]] name = "sqlx-postgres" -version = "0.7.4" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c824eb80b894f926f89a0b9da0c7f435d27cdd35b8c655b114e58223918577e" +checksum = "db58fcd5a53cf07c184b154801ff91347e4c30d17a3562a635ff028ad5deda46" dependencies = [ "atoi", - "base64 0.21.7", + "base64", "bitflags 2.5.0", "byteorder", "chrono", @@ -2171,7 +2132,6 @@ dependencies = [ "etcetera", "futures-channel", "futures-core", - "futures-io", "futures-util", "hex", "hkdf", @@ -2189,17 +2149,17 @@ dependencies = [ "smallvec", "sqlx-core", "stringprep", - "thiserror", - "time 0.3.36", + "thiserror 2.0.16", + "time", "tracing", "whoami", ] [[package]] name = "sqlx-sqlite" -version = "0.7.4" +version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b244ef0a8414da0bed4bb1910426e890b19e5e9bccc27ada6b797d05c55ae0aa" +checksum = "c2d12fe70b2c1b4401038055f90f151b78208de1f9f89a7dbfd41587a10c3eea" dependencies = [ "atoi", "chrono", @@ -2213,11 +2173,12 @@ dependencies = [ "log", "percent-encoding", "serde", + "serde_urlencoded", "sqlx-core", - "time 0.3.36", + "thiserror 2.0.16", + "time", "tracing", "url", - "urlencoding", ] [[package]] @@ -2256,9 +2217,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.59" +version = "2.0.106" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4a6531ffc7b071655e4ce2e04bd464c4830bb585a61cabb96cf808f05172615a" +checksum = "ede7c438028d4436d71104916910f5bb611972c5cfd7f89b8300a8186e6fada6" dependencies = [ "proc-macro2", "quote", @@ -2277,25 +2238,22 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a7065abeca94b6a8a577f9bd45aa0867a2238b74e8eb67cf10d492bc39351394" -[[package]] -name = "tempfile" -version = "3.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85b77fafb263dd9d05cbeac119526425676db3784113aa9295c88498cbf8bff1" -dependencies = [ - "cfg-if", - "fastrand", - "rustix", - "windows-sys 0.52.0", -] - [[package]] name = "thiserror" version = "1.0.58" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "03468839009160513471e86a034bb2c5c0e4baae3b43f79ffc55c4a5427b3297" dependencies = [ - "thiserror-impl", + "thiserror-impl 1.0.58", +] + +[[package]] +name = "thiserror" +version = "2.0.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3467d614147380f2e4e374161426ff399c91084acd2363eaf549172b3d5e60c0" +dependencies = [ + "thiserror-impl 2.0.16", ] [[package]] @@ -2306,7 +2264,18 @@ checksum = "c61f3ba182994efc43764a46c018c347bc492c79f024e705f46567b418f6d4f7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.59", + "syn 2.0.106", +] + +[[package]] +name = "thiserror-impl" +version = "2.0.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c5e1be1c48b9172ee610da68fd9cd2770e7a4056cb3fc98710ee6906f0c7960" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.106", ] [[package]] @@ -2319,17 +2288,6 @@ dependencies = [ "once_cell", ] -[[package]] -name = "time" -version = "0.1.45" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b797afad3f312d1c66a56d11d0316f916356d11bd158fbc6ca6389ff6bf805a" -dependencies = [ - "libc", - "wasi 0.10.0+wasi-snapshot-preview1", - "winapi", -] - [[package]] name = "time" version = "0.3.36" @@ -2378,32 +2336,33 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.37.0" +version = "1.46.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1adbebffeca75fcfd058afa480fb6c0b81e165a0323f9c9d39c9697e37c46787" +checksum = "0cc3a2344dafbe23a245241fe8b09735b521110d30fcefbbd5feb1797ca35d17" dependencies = [ "backtrace", "bytes", + "io-uring", "libc", "mio", - "num_cpus", "pin-project-lite", "signal-hook-registry", + "slab", "socket2", "tokio-macros", "tracing", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] name = "tokio-macros" -version = "2.2.0" +version = "2.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" +checksum = "6e06d43f1345a3bcd39f6a56dbb7dcab2ba47e68e8ac134855e7e2bdbaf8cab8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.59", + "syn 2.0.106", ] [[package]] @@ -2461,7 +2420,7 @@ dependencies = [ "serde", "serde_spanned", "toml_datetime", - "winnow", + "winnow 0.6.6", ] [[package]] @@ -2481,13 +2440,28 @@ dependencies = [ ] [[package]] -name = "tower-cookies" -version = "0.10.0" +name = "tower" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fd0118512cf0b3768f7fcccf0bef1ae41d68f2b45edc1e77432b36c97c56c6d" +checksum = "d039ad9159c98b70ecfd540b2573b97f7f52c3e8d9f8ad57a24b916a536975f9" dependencies = [ - "async-trait", - "axum-core", + "futures-core", + "futures-util", + "pin-project-lite", + "sync_wrapper 1.0.1", + "tokio", + "tower-layer", + "tower-service", + "tracing", +] + +[[package]] +name = "tower-cookies" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "151b5a3e3c45df17466454bb74e9ecedecc955269bdedbf4d150dfa393b55a36" +dependencies = [ + "axum-core 0.5.2", "cookie", "futures-util", "http 1.1.0", @@ -2499,12 +2473,13 @@ dependencies = [ [[package]] name = "tower-http" -version = "0.5.2" +version = "0.6.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e9cd434a998747dd2c4276bc96ee2e0c7a2eadf3cae88e52be55a05fa9053f5" +checksum = "adc82fd73de2a9722ac5da747f12383d2bfdb93591ee6c58486e0097890f05f2" dependencies = [ "bitflags 2.5.0", "bytes", + "futures-core", "futures-util", "http 1.1.0", "http-body", @@ -2524,78 +2499,64 @@ dependencies = [ [[package]] name = "tower-layer" -version = "0.3.2" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c20c8dbed6283a09604c3e69b4b7eeb54e298b8a600d4d5ecb5ad39de609f1d0" +checksum = "121c2a6cda46980bb0fcd1647ffaf6cd3fc79a013de288782836f6df9c48780e" [[package]] name = "tower-service" -version = "0.3.2" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" +checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" [[package]] name = "tower-sessions" -version = "0.11.1" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b27326208b21807803c5f5aa1020d30ca0432b78cfe251b51a67a05e0baea102" +checksum = "43a05911f23e8fae446005fe9b7b97e66d95b6db589dc1c4d59f6a2d4d4927d3" dependencies = [ "async-trait", "http 1.1.0", - "time 0.3.36", + "time", "tokio", "tower-cookies", "tower-layer", "tower-service", "tower-sessions-core", - "tower-sessions-memory-store", "tracing", ] [[package]] name = "tower-sessions-core" -version = "0.11.1" +version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "afd1c5040577134115d8cc758d7757da29e171f83102de3ed1b86e3a2405533f" +checksum = "ce8cce604865576b7751b7a6bc3058f754569a60d689328bb74c52b1d87e355b" dependencies = [ "async-trait", - "axum-core", - "base64 0.22.0", + "base64", "futures", "http 1.1.0", "parking_lot", "rand", "serde", "serde_json", - "thiserror", - "time 0.3.36", + "thiserror 2.0.16", + "time", "tokio", "tracing", ] -[[package]] -name = "tower-sessions-memory-store" -version = "0.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "88ac75309918b8f6ba16d09865a2a64f81e01b05cf42d5e88e5d3c6cbf775486" -dependencies = [ - "async-trait", - "time 0.3.36", - "tokio", - "tower-sessions-core", -] - [[package]] name = "tower-sessions-sqlx-store" -version = "0.11.0" +version = "0.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d7ac8c2edae9edad541f4087865e811565d124c9048eda7004537832066ede6" +checksum = "e054622079f57fc1a7d6a6089c9334f963d62028fe21dc9eddd58af9a78480b3" dependencies = [ "async-trait", "rmp-serde", "sqlx", - "thiserror", - "time 0.3.36", + "thiserror 1.0.58", + "time", "tower-sessions-core", ] @@ -2619,7 +2580,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.59", + "syn 2.0.106", ] [[package]] @@ -2715,18 +2676,6 @@ version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e51733f11c9c4f72aa0c160008246859e340b00807569a0da0e7a1079b27ba85" -[[package]] -name = "unicode_categories" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39ec24b3121d976906ece63c9daad25b85969647682eee313cb5779fdd69e14e" - -[[package]] -name = "untrusted" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" - [[package]] name = "url" version = "2.5.0" @@ -2777,12 +2726,6 @@ dependencies = [ "try-lock", ] -[[package]] -name = "wasi" -version = "0.10.0+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f" - [[package]] name = "wasi" version = "0.11.0+wasi-snapshot-preview1" @@ -2816,7 +2759,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.59", + "syn 2.0.106", "wasm-bindgen-shared", ] @@ -2838,7 +2781,7 @@ checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" dependencies = [ "proc-macro2", "quote", - "syn 2.0.59", + "syn 2.0.106", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -2855,9 +2798,7 @@ version = "0.0.1" dependencies = [ "argon2", "askama", - "askama_axum", - "async-trait", - "axum", + "axum 0.8.4", "axum-login", "axum-macros", "axum-test", @@ -2876,9 +2817,9 @@ dependencies = [ "serde", "sha256", "sqlx", - "thiserror", + "thiserror 1.0.58", "tokio", - "tower", + "tower 0.5.2", "tower-http", "tower-sessions", "tower-sessions-sqlx-store", @@ -2928,6 +2869,12 @@ dependencies = [ "windows-targets 0.52.5", ] +[[package]] +name = "windows-link" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e6ad25900d524eaabdbbb96d20b4311e1e7ae1699af4fb28c17ae66c80d798a" + [[package]] name = "windows-sys" version = "0.48.0" @@ -2946,6 +2893,15 @@ dependencies = [ "windows-targets 0.52.5", ] +[[package]] +name = "windows-sys" +version = "0.60.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f2f500e4d28234f72040990ec9d39e3a6b950f9f22d3dba18416c35882612bcb" +dependencies = [ + "windows-targets 0.53.3", +] + [[package]] name = "windows-targets" version = "0.48.5" @@ -2970,13 +2926,30 @@ dependencies = [ "windows_aarch64_gnullvm 0.52.5", "windows_aarch64_msvc 0.52.5", "windows_i686_gnu 0.52.5", - "windows_i686_gnullvm", + "windows_i686_gnullvm 0.52.5", "windows_i686_msvc 0.52.5", "windows_x86_64_gnu 0.52.5", "windows_x86_64_gnullvm 0.52.5", "windows_x86_64_msvc 0.52.5", ] +[[package]] +name = "windows-targets" +version = "0.53.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d5fe6031c4041849d7c496a8ded650796e7b6ecc19df1a431c1a363342e5dc91" +dependencies = [ + "windows-link", + "windows_aarch64_gnullvm 0.53.0", + "windows_aarch64_msvc 0.53.0", + "windows_i686_gnu 0.53.0", + "windows_i686_gnullvm 0.53.0", + "windows_i686_msvc 0.53.0", + "windows_x86_64_gnu 0.53.0", + "windows_x86_64_gnullvm 0.53.0", + "windows_x86_64_msvc 0.53.0", +] + [[package]] name = "windows_aarch64_gnullvm" version = "0.48.5" @@ -2989,6 +2962,12 @@ version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7088eed71e8b8dda258ecc8bac5fb1153c5cffaf2578fc8ff5d61e23578d3263" +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86b8d5f90ddd19cb4a147a5fa63ca848db3df085e25fee3cc10b39b6eebae764" + [[package]] name = "windows_aarch64_msvc" version = "0.48.5" @@ -3001,6 +2980,12 @@ version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9985fd1504e250c615ca5f281c3f7a6da76213ebd5ccc9561496568a2752afb6" +[[package]] +name = "windows_aarch64_msvc" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c7651a1f62a11b8cbd5e0d42526e55f2c99886c77e007179efff86c2b137e66c" + [[package]] name = "windows_i686_gnu" version = "0.48.5" @@ -3013,12 +2998,24 @@ version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "88ba073cf16d5372720ec942a8ccbf61626074c6d4dd2e745299726ce8b89670" +[[package]] +name = "windows_i686_gnu" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1dc67659d35f387f5f6c479dc4e28f1d4bb90ddd1a5d3da2e5d97b42d6272c3" + [[package]] name = "windows_i686_gnullvm" version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "87f4261229030a858f36b459e748ae97545d6f1ec60e5e0d6a3d32e0dc232ee9" +[[package]] +name = "windows_i686_gnullvm" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ce6ccbdedbf6d6354471319e781c0dfef054c81fbc7cf83f338a4296c0cae11" + [[package]] name = "windows_i686_msvc" version = "0.48.5" @@ -3031,6 +3028,12 @@ version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "db3c2bf3d13d5b658be73463284eaf12830ac9a26a90c717b7f771dfe97487bf" +[[package]] +name = "windows_i686_msvc" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "581fee95406bb13382d2f65cd4a908ca7b1e4c2f1917f143ba16efe98a589b5d" + [[package]] name = "windows_x86_64_gnu" version = "0.48.5" @@ -3043,6 +3046,12 @@ version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4e4246f76bdeff09eb48875a0fd3e2af6aada79d409d33011886d3e1581517d9" +[[package]] +name = "windows_x86_64_gnu" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2e55b5ac9ea33f2fc1716d1742db15574fd6fc8dadc51caab1c16a3d3b4190ba" + [[package]] name = "windows_x86_64_gnullvm" version = "0.48.5" @@ -3055,6 +3064,12 @@ version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "852298e482cd67c356ddd9570386e2862b5673c85bd5f88df9ab6802b334c596" +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a6e035dd0599267ce1ee132e51c27dd29437f63325753051e71dd9e42406c57" + [[package]] name = "windows_x86_64_msvc" version = "0.48.5" @@ -3067,6 +3082,12 @@ version = "0.52.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0" +[[package]] +name = "windows_x86_64_msvc" +version = "0.53.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "271414315aff87387382ec3d271b52d7ae78726f5d44ac98b4f4030c91880486" + [[package]] name = "winnow" version = "0.6.6" @@ -3076,32 +3097,21 @@ dependencies = [ "memchr", ] +[[package]] +name = "winnow" +version = "0.7.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21a0236b59786fed61e2a80582dd500fe61f18b5dca67a4a067d0bc9039339cf" +dependencies = [ + "memchr", +] + [[package]] name = "yansi" version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "09041cd90cf85f7f8b2df60c646f853b7f535ce68f85244eb6731cf89fa498ec" -[[package]] -name = "zerocopy" -version = "0.7.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "74d4d3961e53fa4c9a25a8637fc2bfaf2595b3d3ae34875568a5cf64787716be" -dependencies = [ - "zerocopy-derive", -] - -[[package]] -name = "zerocopy-derive" -version = "0.7.32" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.59", -] - [[package]] name = "zeroize" version = "1.7.0" diff --git a/Cargo.toml b/Cargo.toml index cfdaa01..50de63d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "what2watch" version = "0.0.1" -edition = "2021" +edition = "2024" default-run = "what2watch" [dependencies] @@ -10,16 +10,14 @@ optional_optional_user = {path = "optional_optional_user"} # regular external deps argon2 = "0.5" -askama = { version = "0.12", features = ["with-axum"] } -askama_axum = "0.4" -async-trait = "0.1" -axum = { version = "0.7", features = ["macros"] } -axum-login = "0.14" -axum-macros = "0.4" +askama = { version = "0.14" } +axum = { version = "0.8", features = ["macros"] } +axum-login = "0.18" +axum-macros = "0.5" chrono = { version = "0.4", default-features = false, features = ["std", "clock", "serde"] } clap = { version = "4", features = ["derive", "env", "unicode", "suggestions", "usage"] } -confy = "0.6" -dirs = "5" +confy = "1" +dirs = "6" http = "1" julid-rs = "1" justerror = "1" @@ -29,18 +27,16 @@ password-hash = { version = "0.5", features = ["std", "getrandom"] } rand = "0.8" serde = { version = "1", features = ["derive"] } sha256 = { version = "1", default-features = false } -sqlx = { version = "0.7", default-features = false, features = ["runtime-tokio", "sqlite", "tls-none", "migrate", "chrono"] } +sqlx = { version = "0.8", default-features = false, features = ["runtime-tokio", "sqlite", "tls-none", "migrate", "chrono"] } thiserror = "1" tokio = { version = "1", features = ["rt-multi-thread", "signal", "tracing"], default-features = false } -tower = { version = "0.4", features = ["util", "timeout"], default-features = false } -tower-http = { version = "0.5", features = ["add-extension", "trace", "tracing", "fs"], default-features = false } -tower-sessions = { version = "0.11", default-features = false } -tower-sessions-sqlx-store = { version = "0.11.0", default-features = false, features = ["sqlite"] } +tower = { version = "0.5", features = ["util", "timeout"], default-features = false } +tower-http = { version = "0.6", features = ["add-extension", "trace", "tracing", "fs"], default-features = false } +tower-sessions = { version = "0.14", default-features = false } +tower-sessions-sqlx-store = { version = "0.15.0", default-features = false, features = ["sqlite"] } tracing = "0.1" tracing-subscriber = { version = "0.3", features = ["env-filter"] } unicode-segmentation = "1" [dev-dependencies] axum-test = "14" - - diff --git a/src/auth.rs b/src/auth.rs index fce998e..5be38d3 100644 --- a/src/auth.rs +++ b/src/auth.rs @@ -1,4 +1,3 @@ -use async_trait::async_trait; use axum_login::{AuthUser, AuthnBackend, UserId}; use julid::Julid; use password_auth::verify_password; @@ -37,7 +36,6 @@ pub enum AuthErrorKind { Unknown, } -#[async_trait] impl AuthnBackend for AuthStore { type User = User; type Credentials = Credentials; diff --git a/src/generic_handlers.rs b/src/generic_handlers.rs index da80ae3..31e1455 100644 --- a/src/generic_handlers.rs +++ b/src/generic_handlers.rs @@ -1,6 +1,7 @@ +use askama::Template; use axum::response::{IntoResponse, Redirect}; -use crate::{AuthSession, MainPage}; +use crate::{AuthSession, MainPage, Wender}; pub async fn handle_slash_redir() -> impl IntoResponse { Redirect::to("/") @@ -14,7 +15,7 @@ pub async fn handle_slash(auth: AuthSession) -> impl IntoResponse { } else { tracing::debug!("Not logged in."); } - MainPage { user: auth.user } + MainPage { user: auth.user }.render().wender() } #[cfg(test)] diff --git a/src/lib.rs b/src/lib.rs index fb41110..295210a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,8 +1,11 @@ use axum::{ + body::Body, middleware, + response::IntoResponse, routing::{get, post, IntoMakeService}, }; use axum_login::AuthManagerLayerBuilder; +use http::StatusCode; use sqlx::SqlitePool; #[macro_use] extern crate justerror; @@ -42,6 +45,14 @@ use optional_optional_user::OptionalOptionalUser; use templates::*; use watches::templates::*; +#[Error] +pub enum WatchError { + Auth(auth::AuthError), + Signup(signup::SignupError), + Watches(watches::WatchesError), + Render, +} + /// Returns the router to be used as a service or test object, you do you. pub async fn app(db_pool: sqlx::SqlitePool) -> IntoMakeService { // don't bother bringing handlers into the whole crate namespace @@ -71,19 +82,19 @@ pub async fn app(db_pool: sqlx::SqlitePool) -> IntoMakeService { axum::Router::new() .route("/", get(handle_slash).post(handle_slash)) .nest_service("/assets", assets_svc) - .route("/signup", post(post_create_user)) - .route("/signup/:invitation", get(get_create_user)) - .route("/signup_success/:user", get(get_signup_success)) + .route("/signup", get(get_create_user).post(post_create_user)) + .route("/signup/{invitation}", get(get_create_user)) + .route("/signup_success/{user}", get(get_signup_success)) .route("/login", get(get_login).post(post_login)) .route("/logout", get(get_logout).post(post_logout)) .route("/watches", get(get_watches)) .route("/watch", get(get_watch)) - .route("/watch/:watch", get(get_watch)) + .route("/watch/{watch}", get(get_watch)) .route( "/watch/add", get(get_add_new_watch).post(post_add_new_watch), ) - .route("/watch/status/:watch", get(get_watch_status)) + .route("/watch/status/{watch}", get(get_watch_status)) .route( "/quest/add", get(get_search_watch).post(post_add_watch_quest), @@ -100,6 +111,55 @@ pub async fn app(db_pool: sqlx::SqlitePool) -> IntoMakeService { .into_make_service() } +//-************************************************************************ +// internal stuff +//-************************************************************************ + +pub(crate) trait Wender { + fn wender(self) -> Body; +} + +impl Wender for askama::Result { + fn wender(self) -> Body { + let b = self.unwrap_or_else(|e| { + tracing::error!("got error rendering template: {e}"); + "".to_string() + }); + Body::new(b) + } +} + +impl IntoResponse for WatchError { + fn into_response(self) -> axum::response::Response { + match self { + Self::Auth(ae) => ae.into_response(), + Self::Signup(se) => se.into_response(), + Self::Watches(we) => we.into_response(), + Self::Render => { + (StatusCode::INTERNAL_SERVER_ERROR, "could not render page").into_response() + } + } + } +} + +impl From for WatchError { + fn from(value: auth::AuthError) -> Self { + Self::Auth(value) + } +} + +impl From for WatchError { + fn from(value: signup::SignupError) -> Self { + Self::Signup(value) + } +} + +impl From for WatchError { + fn from(value: watches::WatchesError) -> Self { + Self::Watches(value) + } +} + #[cfg(test)] pub mod test_utils; diff --git a/src/login.rs b/src/login.rs index 7e7672f..dcf14a4 100644 --- a/src/login.rs +++ b/src/login.rs @@ -1,3 +1,4 @@ +use askama::Template; use axum::{ http::StatusCode, response::{IntoResponse, Redirect, Response}, @@ -7,7 +8,7 @@ use serde::{Deserialize, Serialize}; use crate::{ auth::{AuthError, AuthErrorKind, Credentials}, - AuthSession, LoginPage, LogoutPage, LogoutSuccessPage, + AuthSession, LoginPage, LogoutPage, LogoutSuccessPage, WatchError, Wender, }; //-************************************************************************ @@ -53,16 +54,20 @@ impl From for Credentials { pub async fn post_login( mut auth: AuthSession, Form(mut login_form): Form, -) -> Result { +) -> Result { let dest = login_form.destination.take(); let user = match auth.authenticate(login_form.clone().into()).await { Ok(Some(user)) => user, - Ok(None) => return Ok(LoginPage::default().into_response()), - Err(_) => return Err(AuthErrorKind::Internal.into()), + Ok(None) => return Ok(LoginPage::default().render().wender().into_response()), + Err(_) => { + let err: AuthError = AuthErrorKind::Internal.into(); + return Err(err.into()); + } }; if auth.login(&user).await.is_err() { - return Err(AuthErrorKind::Internal.into()); + let err: AuthError = AuthErrorKind::Internal.into(); + return Err(err.into()); } if let Some(ref next) = dest { @@ -73,16 +78,16 @@ pub async fn post_login( } pub async fn get_login() -> impl IntoResponse { - LoginPage::default() + LoginPage::default().render().wender() } pub async fn get_logout() -> impl IntoResponse { - LogoutPage + LogoutPage.render().wender() } pub async fn post_logout(mut auth: AuthSession) -> impl IntoResponse { match auth.logout().await { - Ok(_) => LogoutSuccessPage.into_response(), + Ok(_) => LogoutSuccessPage.render().wender().into_response(), Err(e) => { tracing::debug!("{e}"); let e: AuthError = AuthErrorKind::Internal.into(); diff --git a/src/search.rs b/src/search.rs index f6d6baa..ba32908 100644 --- a/src/search.rs +++ b/src/search.rs @@ -7,7 +7,7 @@ use serde::{Deserialize, Serialize}; use sqlx::SqlitePool; use crate::{ - misc_util::empty_string_as_none, AuthSession, OptionalOptionalUser, Star, User, Watch, + misc_util::empty_string_as_none, AuthSession, OptionalOptionalUser, Star, User, Watch, Wender, }; #[derive(Debug, Default, Template, Deserialize, Serialize, PartialEq, Eq, OptionalOptionalUser)] @@ -60,6 +60,8 @@ pub async fn get_search_watch( results: watches, user, } + .render() + .wender() } pub async fn get_search_star( @@ -83,4 +85,6 @@ pub async fn get_search_star( results: watches, user, } + .render() + .wender() } diff --git a/src/signup/handlers.rs b/src/signup/handlers.rs index 112dc7a..8ea9b4a 100644 --- a/src/signup/handlers.rs +++ b/src/signup/handlers.rs @@ -2,6 +2,7 @@ use argon2::{ password_hash::{rand_core::OsRng, PasswordHasher, SaltString}, Argon2, }; +use askama::Template; use axum::{ extract::{Form, Path, State}, http::StatusCode, @@ -12,48 +13,8 @@ use serde::Deserialize; use sqlx::{query_as, Sqlite, SqlitePool}; use unicode_segmentation::UnicodeSegmentation; -use super::{templates::*, Invitation}; -use crate::{misc_util::empty_string_as_none, User}; - -//-************************************************************************ -// Error types for user creation -//-************************************************************************ - -#[Error(desc = "Could not create user.")] -#[non_exhaustive] -pub struct CreateUserError(#[from] CreateUserErrorKind); - -impl IntoResponse for CreateUserError { - fn into_response(self) -> Response { - match self.0 { - CreateUserErrorKind::UnknownDBError => { - (StatusCode::INTERNAL_SERVER_ERROR, format!("{self}")).into_response() - } - CreateUserErrorKind::BadInvitation => ( - StatusCode::OK, - SignupErrorPage("Sorry, that invitation isn't valid.".to_string()), - ) - .into_response(), - _ => (StatusCode::OK, format!("{self}")).into_response(), - } - } -} - -#[Error] -#[non_exhaustive] -pub enum CreateUserErrorKind { - BadInvitation, - AlreadyExists, - #[error(desc = "Usernames must be between 1 and 20 characters long")] - BadUsername, - PasswordMismatch, - #[error(desc = "Password must have at least 4 and at most 50 characters")] - BadPassword, - #[error(desc = "Display name must be less than 100 characters long")] - BadDisplayname, - BadEmail, - UnknownDBError, -} +use super::{templates::*, CreateUserError, CreateUserErrorKind, Invitation, SignupError}; +use crate::{misc_util::empty_string_as_none, User, WatchError, Wender}; #[derive(Debug, Default, Deserialize, PartialEq, Eq)] pub struct SignupForm { @@ -76,15 +37,25 @@ pub struct SignupForm { pub async fn get_create_user( State(_pool): State, invitation: Option>, -) -> Result { - let invitation = invitation.ok_or(CreateUserErrorKind::BadInvitation)?; - let invitation = - Julid::from_str(&invitation.0).map_err(|_| CreateUserErrorKind::BadInvitation)?; +) -> Result { + let Path(invitation) = invitation.ok_or_else(|| { + let e: CreateUserError = CreateUserErrorKind::BadInvitation.into(); + let e: SignupError = e.into(); + e + })?; + let invitation = Julid::from_str(&invitation).map_err(|_| { + let e: CreateUserError = CreateUserErrorKind::BadInvitation.into(); + let e: SignupError = e.into(); + e + })?; Ok(SignupPage { invitation, ..Default::default() - }) + } + .render() + .wender() + .into_response()) } /// Post Handler: validates form values and calls the actual, private user @@ -93,7 +64,7 @@ pub async fn get_create_user( pub async fn post_create_user( State(pool): State, Form(signup): Form, -) -> Result { +) -> Result { use crate::misc_util::validate_optional_length; let username = signup.username.trim(); let password = signup.password.trim(); @@ -156,7 +127,10 @@ pub async fn get_signup_success( .unwrap_or_default() }; - let mut resp = SignupSuccessPage(user.clone()).into_response(); + let mut resp = SignupSuccessPage(user.clone()) + .render() + .wender() + .into_response(); if user.username.is_empty() || id.is_alpha() { // redirect to front page if we got here without a valid user ID @@ -178,7 +152,7 @@ pub(crate) async fn create_user( password: &[u8], pool: &SqlitePool, invitation: &str, -) -> Result { +) -> Result { const CREATE_QUERY: &str = "insert into users (username, displayname, email, pwhash, invited_by) values ($1, $2, $3, $4, $5) returning *"; @@ -192,7 +166,7 @@ pub(crate) async fn create_user( let mut tx = pool.begin().await.map_err(|e| { tracing::debug!("db error: {e}"); - CreateUserErrorKind::UnknownDBError + CreateUserErrorKind::DBError })?; let invitation = Julid::from_str(invitation).map_err(|_| CreateUserErrorKind::BadInvitation)?; @@ -215,16 +189,16 @@ pub(crate) async fn create_user( if exit == 2067u32 || exit == 1555 { CreateUserErrorKind::AlreadyExists } else { - CreateUserErrorKind::UnknownDBError + CreateUserErrorKind::DBError } } - _ => CreateUserErrorKind::UnknownDBError, + _ => CreateUserErrorKind::DBError, } })?; tx.commit().await.map_err(|e| { tracing::debug!("db error: {e}"); - CreateUserErrorKind::UnknownDBError + CreateUserErrorKind::DBError })?; Ok(user) @@ -240,7 +214,7 @@ async fn validate_invitation( .await .map_err(|e| { tracing::debug!("db error: {e}"); - CreateUserErrorKind::UnknownDBError + CreateUserErrorKind::DBError })? .ok_or(CreateUserErrorKind::BadInvitation)?; @@ -263,7 +237,7 @@ async fn validate_invitation( .await .map_err(|e| { tracing::debug!("db error: {e}"); - CreateUserErrorKind::UnknownDBError + CreateUserErrorKind::DBError })?; Ok(invitation.owner) diff --git a/src/signup/mod.rs b/src/signup/mod.rs index e07e1b5..e8e6e26 100644 --- a/src/signup/mod.rs +++ b/src/signup/mod.rs @@ -1,15 +1,29 @@ use std::time::Duration; +use askama::Template; +use axum::response::{IntoResponse, Response}; +use http::StatusCode; use julid::Julid; use serde::{Deserialize, Serialize}; use sqlx::SqlitePool; +use templates::{SignupErrorPage, SignupPage}; -use crate::WatchDate; +use crate::{WatchDate, WatchError}; pub mod handlers; pub mod templates; -#[Error(desc = "Could not create user.")] +//-************************************************************************ +// Error types for user creation +//-************************************************************************ + +#[Error] +pub enum SignupError { + Invite(CreateInviteError), + User(CreateUserError), +} + +#[Error(desc = "Could not create invitation.")] #[non_exhaustive] #[derive(PartialEq, Eq)] pub struct CreateInviteError(#[from] CreateInviteErrorKind); @@ -23,6 +37,26 @@ pub enum CreateInviteErrorKind { Unknown, } +#[Error(desc = "Could not create user.")] +#[non_exhaustive] +pub struct CreateUserError(#[from] CreateUserErrorKind); + +#[Error] +#[non_exhaustive] +pub enum CreateUserErrorKind { + BadInvitation, + AlreadyExists, + #[error(desc = "Usernames must be between 1 and 20 characters long")] + BadUsername, + PasswordMismatch, + #[error(desc = "Password must have at least 4 and at most 50 characters")] + BadPassword, + #[error(desc = "Display name must be less than 100 characters long")] + BadDisplayname, + BadEmail, + DBError, +} + #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, sqlx::FromRow)] pub struct Invitation { id: Julid, @@ -95,6 +129,87 @@ impl Invitation { } } +//-************************************************************************ +// internal impls +//-************************************************************************ + +impl From for SignupError { + fn from(value: CreateUserError) -> Self { + SignupError::User(value) + } +} + +impl From for SignupError { + fn from(value: CreateUserErrorKind) -> Self { + let e: CreateUserError = value.into(); + e.into() + } +} + +impl From for SignupError { + fn from(value: CreateInviteError) -> Self { + SignupError::Invite(value) + } +} + +impl From for SignupError { + fn from(value: CreateInviteErrorKind) -> Self { + let e: CreateInviteError = value.into(); + e.into() + } +} + +impl IntoResponse for SignupError { + fn into_response(self) -> Response { + match self { + Self::Invite(ie) => ie.into_response(), + Self::User(ue) => ue.into_response(), + } + } +} + +impl IntoResponse for CreateInviteError { + fn into_response(self) -> Response { + match self.0 { + CreateInviteErrorKind::DBError => { + (StatusCode::INTERNAL_SERVER_ERROR, format!("{self}")).into_response() + } + CreateInviteErrorKind::NoOwner => ( + StatusCode::OK, + SignupErrorPage("Sorry, invitations require an owner".to_string()) + .render() + .map_err(|e| { + tracing::error!("could not render create user error page, got {e}"); + StatusCode::INTERNAL_SERVER_ERROR + }), + ) + .into_response(), + _ => (StatusCode::OK, format!("{self}")).into_response(), + } + } +} + +impl IntoResponse for CreateUserError { + fn into_response(self) -> Response { + match self.0 { + CreateUserErrorKind::DBError => { + (StatusCode::INTERNAL_SERVER_ERROR, format!("{self}")).into_response() + } + CreateUserErrorKind::BadInvitation => ( + StatusCode::OK, + SignupErrorPage("Sorry, that invitation isn't valid.".to_string()) + .render() + .map_err(|e| { + tracing::error!("could not render create user error page, got {e}"); + StatusCode::INTERNAL_SERVER_ERROR + }), + ) + .into_response(), + _ => (StatusCode::OK, format!("{self}")).into_response(), + } + } +} + #[cfg(test)] mod test { use tokio::runtime::Runtime; diff --git a/src/watches/handlers.rs b/src/watches/handlers.rs index 799ab67..637d817 100644 --- a/src/watches/handlers.rs +++ b/src/watches/handlers.rs @@ -1,16 +1,21 @@ +use askama::Template; use axum::{ extract::{Form, Path, State}, http::StatusCode, - response::{IntoResponse, Redirect, Response}, + response::{IntoResponse, Redirect}, }; use http::HeaderValue; use julid::Julid; use serde::Deserialize; use sqlx::{query, query_as, query_scalar, SqlitePool}; -use super::templates::{AddNewWatchPage, GetWatchPage, WatchStatusMenus}; +use super::{ + templates::{AddNewWatchPage, GetWatchPage, WatchStatusMenus}, + AddError, AddErrorKind, EditError, EditErrorKind, WatchesError, +}; use crate::{ - misc_util::empty_string_as_none, AuthSession, MyWatchesPage, ShowKind, Watch, WatchQuest, + misc_util::empty_string_as_none, AuthSession, MyWatchesPage, ShowKind, Watch, WatchError, + WatchQuest, Wender, }; //-************************************************************************ @@ -28,62 +33,6 @@ const ADD_WATCH_QUEST_QUERY: &str = const CHECKMARK: &str = "✓"; -//-************************************************************************ -// Error types for Watch creation -//-************************************************************************ - -#[Error] -pub struct AddError(#[from] AddErrorKind); - -#[Error] -#[non_exhaustive] -pub enum AddErrorKind { - UnknownDBError, - NotSignedIn, -} - -impl IntoResponse for AddError { - fn into_response(self) -> Response { - match &self.0 { - AddErrorKind::UnknownDBError => { - (StatusCode::INTERNAL_SERVER_ERROR, format!("{self}")).into_response() - } - AddErrorKind::NotSignedIn => ( - StatusCode::OK, - "Ope, you need to sign in first!".to_string(), - ) - .into_response(), - } - } -} - -#[Error] -pub struct EditError(#[from] EditErrorKind); - -#[Error] -#[non_exhaustive] -pub enum EditErrorKind { - UnknownDBError, - NotSignedIn, - NotFound, -} - -impl IntoResponse for EditError { - fn into_response(self) -> Response { - match &self.0 { - EditErrorKind::UnknownDBError => { - (StatusCode::INTERNAL_SERVER_ERROR, format!("{self}")).into_response() - } - EditErrorKind::NotSignedIn => ( - StatusCode::OK, - "Ope, you need to sign in first!".to_string(), - ) - .into_response(), - EditErrorKind::NotFound => (StatusCode::OK, "Could not find watch").into_response(), - } - } -} - //-************************************************************************ // Types for receiving arguments from forms //-************************************************************************ @@ -120,7 +69,7 @@ pub struct PostEditQuest { //-************************************************************************ pub async fn get_add_new_watch(auth: AuthSession) -> impl IntoResponse { - AddNewWatchPage { user: auth.user } + AddNewWatchPage { user: auth.user }.render().wender() } /// Add a Watch to your watchlist (side effects system-add) @@ -128,7 +77,7 @@ pub async fn post_add_new_watch( auth: AuthSession, State(pool): State, Form(form): Form, -) -> Result { +) -> Result { if let Some(user) = auth.user { { let watch = Watch { @@ -147,15 +96,14 @@ pub async fn post_add_new_watch( watched: false, watch: watch_id, }; - add_watch_quest_impl(&pool, &quest) - .await - .map_err(|_| AddErrorKind::UnknownDBError)?; + add_watch_quest_impl(&pool, &quest).await?; let location = format!("/watch/{watch_id}"); Ok(Redirect::to(&location)) } } else { - Err(AddErrorKind::NotSignedIn.into()) + let e: AddError = AddErrorKind::NotSignedIn.into(); + Err(e.into()) } } @@ -171,7 +119,7 @@ async fn add_new_watch_impl(db_pool: &SqlitePool, watch: &Watch) -> Result, Form(form): Form, -) -> Result { +) -> Result { if let Some(user) = auth.user { let quest = WatchQuest { user: user.id, @@ -189,9 +137,8 @@ pub async fn post_add_watch_quest( public: form.public, watched: false, }; - add_watch_quest_impl(&pool, &quest) - .await - .map_err(|_| AddErrorKind::UnknownDBError)?; + add_watch_quest_impl(&pool, &quest).await?; + let resp = checkmark(form.public); Ok(resp.into_response()) } else { @@ -203,7 +150,7 @@ pub async fn post_add_watch_quest( } } -pub async fn add_watch_quest_impl(pool: &SqlitePool, quest: &WatchQuest) -> Result<(), ()> { +async fn add_watch_quest_impl(pool: &SqlitePool, quest: &WatchQuest) -> Result<(), AddError> { query(ADD_WATCH_QUEST_QUERY) .bind(quest.user) .bind(quest.watch) @@ -213,6 +160,7 @@ pub async fn add_watch_quest_impl(pool: &SqlitePool, quest: &WatchQuest) -> Resu .await .map_err(|err| { tracing::error!("Got error: {err}"); + AddErrorKind::DBError })?; Ok(()) } @@ -222,13 +170,14 @@ pub async fn edit_watch_quest( auth: AuthSession, State(pool): State, Form(form): Form, -) -> Result { +) -> Result { if let Some(user) = auth.user { let watch = Julid::from_str(form.watch.trim()).map_err(|_| EditErrorKind::NotFound)?; Ok( edit_watch_quest_impl(&pool, form.act.trim(), user.id, watch) .await? - .into_response(), + .render() + .wender(), ) } else { Err(EditErrorKind::NotSignedIn.into()) @@ -240,7 +189,7 @@ async fn edit_watch_quest_impl( action: &str, user: Julid, watch: Julid, -) -> Result { +) -> Result { let quest: Option = query_as(GET_QUEST_QUERY) .bind(user) .bind(watch) @@ -248,7 +197,7 @@ async fn edit_watch_quest_impl( .await .map_err(|e| { tracing::error!("Got error from checking watch status: {e:?}"); - EditErrorKind::UnknownDBError + EditErrorKind::DBError })?; if let Some(quest) = quest { match action { @@ -262,7 +211,7 @@ async fn edit_watch_quest_impl( .await .map_err(|e| { tracing::error!("Error removing quest: {e}"); - EditErrorKind::UnknownDBError + EditErrorKind::DBError })?; Ok(WatchStatusMenus { watch, quest: None }) } @@ -278,7 +227,7 @@ async fn edit_watch_quest_impl( .await .map_err(|e| { tracing::error!("Error updating quest: {e}"); - EditErrorKind::UnknownDBError + EditErrorKind::DBError })?; let quest = WatchQuest { watched, ..quest }; Ok(WatchStatusMenus { @@ -298,7 +247,7 @@ async fn edit_watch_quest_impl( .await .map_err(|e| { tracing::error!("Error updating quest: {e}"); - EditErrorKind::UnknownDBError + EditErrorKind::DBError })?; let quest = WatchQuest { public, ..quest }; Ok(WatchStatusMenus { @@ -312,7 +261,7 @@ async fn edit_watch_quest_impl( }), } } else { - Err(EditErrorKind::NotFound) + Err(EditErrorKind::NotFound.into()) } } @@ -336,14 +285,20 @@ pub async fn get_watch( watch, user: auth.user, } + .render() + .map_err(|e| { + tracing::error!("could not render watch page, got {e}"); + StatusCode::INTERNAL_SERVER_ERROR + }) + .into_response() } /// everything the user has saved pub async fn get_watches(auth: AuthSession, State(pool): State) -> impl IntoResponse { let user = auth.user; - let watches: Vec = if (user).is_some() { + let watches: Vec = if let Some(ref user) = user { query_as(GET_SAVED_WATCHES_QUERY) - .bind(user.as_ref().unwrap().id) + .bind(user.id) .fetch_all(&pool) .await .unwrap_or_default() @@ -352,6 +307,9 @@ pub async fn get_watches(auth: AuthSession, State(pool): State) -> i }; MyWatchesPage { watches, user } + .render() + .wender() + .into_response() } pub async fn get_watch_status( @@ -369,7 +327,10 @@ pub async fn get_watch_status( .map_err(|e| { tracing::error!("Got error from checking watch status: {e:?}"); })?; - Ok(WatchStatusMenus { watch, quest }.into_response()) + Ok(WatchStatusMenus { watch, quest } + .render() + .wender() + .into_response()) } else { Ok("Login to add".into_response()) } diff --git a/src/watches/mod.rs b/src/watches/mod.rs index 4824300..8480b73 100644 --- a/src/watches/mod.rs +++ b/src/watches/mod.rs @@ -1,9 +1,44 @@ +use axum::response::{IntoResponse, Response}; +use http::StatusCode; use julid::Julid; use serde::{Deserialize, Serialize}; +use crate::WatchError; + pub mod handlers; pub mod templates; +//-************************************************************************ +// Error types for Watch creation +//-************************************************************************ + +#[Error] +pub enum WatchesError { + Add(AddError), + Edit(EditError), +} + +#[Error] +pub struct AddError(#[from] AddErrorKind); + +#[Error] +#[non_exhaustive] +pub enum AddErrorKind { + DBError, + NotSignedIn, +} + +#[Error] +pub struct EditError(#[from] EditErrorKind); + +#[Error] +#[non_exhaustive] +pub enum EditErrorKind { + DBError, + NotSignedIn, + NotFound, +} + #[derive( Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize, sqlx::Type, )] @@ -104,3 +139,73 @@ impl WatchQuest { } } } + +//-************************************************************************ +// error impls +//-************************************************************************ + +impl IntoResponse for WatchesError { + fn into_response(self) -> Response { + match self { + Self::Add(ae) => ae.into_response(), + Self::Edit(ee) => ee.into_response(), + } + } +} + +impl From for WatchesError { + fn from(value: AddError) -> Self { + WatchesError::Add(value) + } +} + +impl From for WatchesError { + fn from(value: AddErrorKind) -> Self { + let e: AddError = value.into(); + e.into() + } +} + +impl From for WatchesError { + fn from(value: EditError) -> Self { + WatchesError::Edit(value) + } +} + +impl From for WatchesError { + fn from(value: EditErrorKind) -> Self { + let e: EditError = value.into(); + e.into() + } +} + +impl IntoResponse for EditError { + fn into_response(self) -> Response { + match &self.0 { + EditErrorKind::DBError => { + (StatusCode::INTERNAL_SERVER_ERROR, format!("{self}")).into_response() + } + EditErrorKind::NotSignedIn => ( + StatusCode::OK, + "Ope, you need to sign in first!".to_string(), + ) + .into_response(), + EditErrorKind::NotFound => (StatusCode::OK, "Could not find watch").into_response(), + } + } +} + +impl IntoResponse for AddError { + fn into_response(self) -> Response { + match &self.0 { + AddErrorKind::DBError => { + (StatusCode::INTERNAL_SERVER_ERROR, format!("{self}")).into_response() + } + AddErrorKind::NotSignedIn => ( + StatusCode::OK, + "Ope, you need to sign in first!".to_string(), + ) + .into_response(), + } + } +}