updatse
This commit is contained in:
parent
8a19a733d6
commit
52ef924f12
28 changed files with 577 additions and 170 deletions
252
Cargo.lock
generated
252
Cargo.lock
generated
|
@ -30,7 +30,7 @@ dependencies = [
|
|||
"actix-service",
|
||||
"actix-utils",
|
||||
"ahash",
|
||||
"base64 0.21.5",
|
||||
"base64",
|
||||
"bitflags 2.4.1",
|
||||
"brotli",
|
||||
"bytes",
|
||||
|
@ -65,7 +65,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "e01ed3140b2f8d422c68afa1ed2e85d996ea619c988ac834d255db32138655cb"
|
||||
dependencies = [
|
||||
"quote",
|
||||
"syn 2.0.43",
|
||||
"syn 2.0.44",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -179,7 +179,7 @@ dependencies = [
|
|||
"actix-router",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.43",
|
||||
"syn 2.0.44",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -199,9 +199,9 @@ checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
|
|||
|
||||
[[package]]
|
||||
name = "ahash"
|
||||
version = "0.8.6"
|
||||
version = "0.8.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "91429305e9f0a25f6205c5b8e0d2db09e0708a7a6df0f42212bb56c32c8ac97a"
|
||||
checksum = "77c3a9648d43b9cd48db467b3f87fdd6e146bcc88ab0180006cef2179fe11d01"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"getrandom",
|
||||
|
@ -251,13 +251,13 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "async-trait"
|
||||
version = "0.1.75"
|
||||
version = "0.1.76"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fdf6721fb0140e4f897002dd086c06f6c27775df19cfe1fccb21181a48fd2c98"
|
||||
checksum = "531b97fb4cd3dfdce92c35dedbfdc1f0b9d8091c8ca943d6dae340ef5012d514"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.43",
|
||||
"syn 2.0.44",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -281,12 +281,6 @@ dependencies = [
|
|||
"rustc-demangle",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "base64"
|
||||
version = "0.13.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8"
|
||||
|
||||
[[package]]
|
||||
name = "base64"
|
||||
version = "0.21.5"
|
||||
|
@ -299,7 +293,7 @@ version = "0.15.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "28d1c9c15093eb224f0baa400f38fcd713fc1391a6f1c389d886beef146d60a3"
|
||||
dependencies = [
|
||||
"base64 0.21.5",
|
||||
"base64",
|
||||
"blowfish",
|
||||
"getrandom",
|
||||
"subtle",
|
||||
|
@ -413,7 +407,7 @@ dependencies = [
|
|||
"num-traits",
|
||||
"serde",
|
||||
"wasm-bindgen",
|
||||
"windows-targets",
|
||||
"windows-targets 0.48.5",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -479,9 +473,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "deranged"
|
||||
version = "0.3.10"
|
||||
version = "0.3.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8eb30d70a07a3b04884d2677f06bec33509dc67ca60d92949e5535352d3191dc"
|
||||
checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4"
|
||||
dependencies = [
|
||||
"powerfmt",
|
||||
]
|
||||
|
@ -523,7 +517,7 @@ dependencies = [
|
|||
"diesel_table_macro_syntax",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.43",
|
||||
"syn 2.0.44",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -543,7 +537,7 @@ version = "0.1.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fc5557efc453706fed5e4fa85006fe9817c224c3f480a34c7e5959fd700921c5"
|
||||
dependencies = [
|
||||
"syn 2.0.43",
|
||||
"syn 2.0.44",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -650,8 +644,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "fe9006bed769170c11f845cf00c7c1e9092aeb3f268e007c3e760ac68008070f"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"js-sys",
|
||||
"libc",
|
||||
"wasi",
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -719,9 +715,9 @@ checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9"
|
|||
|
||||
[[package]]
|
||||
name = "iana-time-zone"
|
||||
version = "0.1.58"
|
||||
version = "0.1.59"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8326b86b6cff230b97d0d312a6c40a60726df3332e721f72a1b035f451663b20"
|
||||
checksum = "b6a67363e2aa4443928ce15e57ebae94fd8949958fd1223c4cfc0cd473ad7539"
|
||||
dependencies = [
|
||||
"android_system_properties",
|
||||
"core-foundation-sys",
|
||||
|
@ -794,18 +790,18 @@ dependencies = [
|
|||
]
|
||||
|
||||
[[package]]
|
||||
name = "jwt"
|
||||
version = "0.16.0"
|
||||
name = "jsonwebtoken"
|
||||
version = "9.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6204285f77fe7d9784db3fdc449ecce1a0114927a51d5a41c4c7a292011c015f"
|
||||
checksum = "5c7ea04a7c5c055c175f189b6dc6ba036fd62306b58c66c9f6389036c503a3f4"
|
||||
dependencies = [
|
||||
"base64 0.13.1",
|
||||
"crypto-common",
|
||||
"digest",
|
||||
"hmac",
|
||||
"base64",
|
||||
"js-sys",
|
||||
"pem",
|
||||
"ring",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"sha2",
|
||||
"simple_asn1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -913,6 +909,27 @@ dependencies = [
|
|||
"windows-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-bigint"
|
||||
version = "0.4.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "608e7659b5c3d7cba262d894801b9ec9d00de989e8a82bd4bef91d08da45cdc0"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"num-integer",
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-integer"
|
||||
version = "0.1.45"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"num-traits",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-traits"
|
||||
version = "0.2.17"
|
||||
|
@ -957,7 +974,7 @@ dependencies = [
|
|||
"libc",
|
||||
"redox_syscall",
|
||||
"smallvec",
|
||||
"windows-targets",
|
||||
"windows-targets 0.48.5",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -966,6 +983,16 @@ version = "1.0.14"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c"
|
||||
|
||||
[[package]]
|
||||
name = "pem"
|
||||
version = "3.0.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1b8fcc794035347fb64beda2d3b462595dd2753e3f268d89c5aae77e8cf2c310"
|
||||
dependencies = [
|
||||
"base64",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "percent-encoding"
|
||||
version = "2.3.1"
|
||||
|
@ -1013,18 +1040,18 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.71"
|
||||
version = "1.0.73"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "75cb1540fadbd5b8fbccc4dddad2734eba435053f725621c070711a14bb5f4b8"
|
||||
checksum = "2dd5e8a1f1029c43224ad5898e50140c2aebb1705f19e67c918ebf5b9e797fe1"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.33"
|
||||
version = "1.0.34"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae"
|
||||
checksum = "22a37c9326af5ed140c86a46655b5278de879853be5573c01df185b6f49a580a"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
@ -1108,6 +1135,20 @@ version = "0.8.2"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f"
|
||||
|
||||
[[package]]
|
||||
name = "ring"
|
||||
version = "0.17.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "688c63d65483050968b2a8937f7995f443e27041a0f7700aa59b0822aedebb74"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"getrandom",
|
||||
"libc",
|
||||
"spin",
|
||||
"untrusted",
|
||||
"windows-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustc-demangle"
|
||||
version = "0.1.23"
|
||||
|
@ -1167,14 +1208,14 @@ checksum = "43576ca501357b9b071ac53cdc7da8ef0cbd9493d8df094cd821777ea6e894d3"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.43",
|
||||
"syn 2.0.44",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_json"
|
||||
version = "1.0.108"
|
||||
version = "1.0.109"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3d1c7e3eac408d115102c4c24ad393e0821bb3a5df4d506a80f85f7a742a526b"
|
||||
checksum = "cb0652c533506ad7a2e353cce269330d6afd8bdfb6d75e0ace5b35aacbd7b9e9"
|
||||
dependencies = [
|
||||
"itoa",
|
||||
"ryu",
|
||||
|
@ -1233,6 +1274,18 @@ dependencies = [
|
|||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "simple_asn1"
|
||||
version = "0.6.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "adc4e5204eb1910f40f9cfa375f6f05b68c3abac4b6fd879c8ff5e7ae8a0a085"
|
||||
dependencies = [
|
||||
"num-bigint",
|
||||
"num-traits",
|
||||
"thiserror",
|
||||
"time",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "slab"
|
||||
version = "0.4.9"
|
||||
|
@ -1258,6 +1311,12 @@ dependencies = [
|
|||
"windows-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "spin"
|
||||
version = "0.9.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67"
|
||||
|
||||
[[package]]
|
||||
name = "subtle"
|
||||
version = "2.5.0"
|
||||
|
@ -1277,15 +1336,35 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.43"
|
||||
version = "2.0.44"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ee659fb5f3d355364e1f3e5bc10fb82068efbf824a1e9d1c9504244a6469ad53"
|
||||
checksum = "92d27c2c202598d05175a6dd3af46824b7f747f8d8e9b14c623f19fa5069735d"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror"
|
||||
version = "1.0.53"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b2cd5904763bad08ad5513ddbb12cf2ae273ca53fa9f68e843e236ec6dfccc09"
|
||||
dependencies = [
|
||||
"thiserror-impl",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror-impl"
|
||||
version = "1.0.53"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3dcf4a824cce0aeacd6f38ae6f24234c8e80d68632338ebaa1443b5df9e29e19"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.44",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "time"
|
||||
version = "0.3.31"
|
||||
|
@ -1442,6 +1521,12 @@ dependencies = [
|
|||
"tinyvec",
|
||||
]
|
||||
|
||||
[[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"
|
||||
|
@ -1478,7 +1563,7 @@ dependencies = [
|
|||
"diesel_migrations",
|
||||
"dotenvy",
|
||||
"hmac",
|
||||
"jwt",
|
||||
"jsonwebtoken",
|
||||
"lazy_static",
|
||||
"serde",
|
||||
"serde_json",
|
||||
|
@ -1512,7 +1597,7 @@ dependencies = [
|
|||
"once_cell",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.43",
|
||||
"syn 2.0.44",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
||||
|
@ -1534,7 +1619,7 @@ checksum = "f0eb82fcb7930ae6219a7ecfd55b217f5f0893484b7a13022ebb2b2bf20b5283"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.43",
|
||||
"syn 2.0.44",
|
||||
"wasm-bindgen-backend",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
@ -1547,11 +1632,11 @@ checksum = "7ab9b36309365056cd639da3134bf87fa8f3d86008abf99e612384a6eecd459f"
|
|||
|
||||
[[package]]
|
||||
name = "windows-core"
|
||||
version = "0.51.1"
|
||||
version = "0.52.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f1f8cf84f35d2db49a46868f947758c7a1138116f7fac3bc844f43ade1292e64"
|
||||
checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9"
|
||||
dependencies = [
|
||||
"windows-targets",
|
||||
"windows-targets 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1560,7 +1645,7 @@ version = "0.48.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9"
|
||||
dependencies = [
|
||||
"windows-targets",
|
||||
"windows-targets 0.48.5",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1569,13 +1654,28 @@ version = "0.48.5"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c"
|
||||
dependencies = [
|
||||
"windows_aarch64_gnullvm",
|
||||
"windows_aarch64_msvc",
|
||||
"windows_i686_gnu",
|
||||
"windows_i686_msvc",
|
||||
"windows_x86_64_gnu",
|
||||
"windows_x86_64_gnullvm",
|
||||
"windows_x86_64_msvc",
|
||||
"windows_aarch64_gnullvm 0.48.5",
|
||||
"windows_aarch64_msvc 0.48.5",
|
||||
"windows_i686_gnu 0.48.5",
|
||||
"windows_i686_msvc 0.48.5",
|
||||
"windows_x86_64_gnu 0.48.5",
|
||||
"windows_x86_64_gnullvm 0.48.5",
|
||||
"windows_x86_64_msvc 0.48.5",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows-targets"
|
||||
version = "0.52.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8a18201040b24831fbb9e4eb208f8892e1f50a37feb53cc7ff887feb8f50e7cd"
|
||||
dependencies = [
|
||||
"windows_aarch64_gnullvm 0.52.0",
|
||||
"windows_aarch64_msvc 0.52.0",
|
||||
"windows_i686_gnu 0.52.0",
|
||||
"windows_i686_msvc 0.52.0",
|
||||
"windows_x86_64_gnu 0.52.0",
|
||||
"windows_x86_64_gnullvm 0.52.0",
|
||||
"windows_x86_64_msvc 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1584,42 +1684,84 @@ version = "0.48.5"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8"
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_gnullvm"
|
||||
version = "0.52.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cb7764e35d4db8a7921e09562a0304bf2f93e0a51bfccee0bd0bb0b666b015ea"
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_msvc"
|
||||
version = "0.48.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc"
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_msvc"
|
||||
version = "0.52.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bbaa0368d4f1d2aaefc55b6fcfee13f41544ddf36801e793edbbfd7d7df075ef"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnu"
|
||||
version = "0.48.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnu"
|
||||
version = "0.52.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a28637cb1fa3560a16915793afb20081aba2c92ee8af57b4d5f28e4b3e7df313"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_msvc"
|
||||
version = "0.48.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_msvc"
|
||||
version = "0.52.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ffe5e8e31046ce6230cc7215707b816e339ff4d4d67c65dffa206fd0f7aa7b9a"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnu"
|
||||
version = "0.48.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnu"
|
||||
version = "0.52.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3d6fa32db2bc4a2f5abeacf2b69f7992cd09dca97498da74a151a3132c26befd"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnullvm"
|
||||
version = "0.48.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnullvm"
|
||||
version = "0.52.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1a657e1e9d3f514745a572a6846d3c7aa7dbe1658c056ed9c3344c4109a6949e"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_msvc"
|
||||
version = "0.48.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_msvc"
|
||||
version = "0.52.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04"
|
||||
|
||||
[[package]]
|
||||
name = "winnow"
|
||||
version = "0.5.31"
|
||||
|
@ -1646,7 +1788,7 @@ checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6"
|
|||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.43",
|
||||
"syn 2.0.44",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
|
@ -17,6 +17,6 @@ dotenvy = "*"
|
|||
hmac = "0.12"
|
||||
sha2 = "0.10"
|
||||
lazy_static = "1"
|
||||
jwt = "0.16"
|
||||
jsonwebtoken = "9"
|
||||
serde = "1"
|
||||
serde_json = "1"
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
-- This file should undo anything in `up.sql`
|
||||
DROP TABLE users;
|
||||
drop table users;
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
-- Your SQL goes here
|
||||
CREATE TABLE IF NOT EXISTS users
|
||||
create table if not exists users
|
||||
(
|
||||
id VARCHAR(24) DEFAULT nanoid(24),
|
||||
name VARCHAR(255) NOT NULL,
|
||||
email VARCHAR(255) NOT NULL,
|
||||
password TEXT NOT NULL,
|
||||
id varchar(24) default nanoid(24),
|
||||
name varchar(255) not null,
|
||||
email varchar(255) not null,
|
||||
password text not null,
|
||||
|
||||
updated_at TIMESTAMP,
|
||||
created_at TIMESTAMP DEFAULT now() NOT NULL,
|
||||
updated_at timestamp,
|
||||
created_at timestamp default now() not null,
|
||||
|
||||
PRIMARY KEY (id)
|
||||
primary key (id)
|
||||
);
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
-- This file should undo anything in `up.sql`
|
||||
DROP TABLE playlists;
|
||||
drop table playlists;
|
||||
|
|
|
@ -1,16 +1,16 @@
|
|||
CREATE TABLE IF NOT EXISTS playlists
|
||||
create table if not exists playlists
|
||||
(
|
||||
id VARCHAR(24) DEFAULT nanoid(24),
|
||||
name VARCHAR(255) NOT NULL,
|
||||
id varchar(24) default nanoid(24),
|
||||
name varchar(255) not null,
|
||||
public bool default false,
|
||||
|
||||
creator_id VARCHAR(24) NOT NULL,
|
||||
creator_id varchar(24) not null,
|
||||
|
||||
created_at TIMESTAMP DEFAULT now() NOT NULL,
|
||||
updated_at TIMESTAMP,
|
||||
created_at timestamp default now() not null,
|
||||
updated_at timestamp,
|
||||
|
||||
PRIMARY KEY (id),
|
||||
FOREIGN KEY (creator_id)
|
||||
REFERENCES users (id)
|
||||
primary key (id),
|
||||
foreign key (creator_id)
|
||||
references users (id)
|
||||
on delete cascade
|
||||
);
|
||||
|
||||
CREATE INDEX ON playlists (creator_id);
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
-- This file should undo anything in `up.sql`
|
||||
DROP TABLE tracks;
|
||||
drop table tracks;
|
||||
|
|
|
@ -1,16 +1,16 @@
|
|||
-- Your SQL goes here
|
||||
CREATE TABLE IF NOT EXISTS tracks
|
||||
create table if not exists tracks
|
||||
(
|
||||
id VARCHAR(24) DEFAULT nanoid(24),
|
||||
title VARCHAR(255) NOT NULL,
|
||||
duration_ms INT NOT NULL DEFAULT 0,
|
||||
id varchar(24) default nanoid(24),
|
||||
title varchar(255) not null,
|
||||
duration_ms int not null default 0,
|
||||
|
||||
created_at TIMESTAMP DEFAULT now() NOT NULL,
|
||||
updated_at TIMESTAMP,
|
||||
created_at timestamp default now() not null,
|
||||
updated_at timestamp,
|
||||
|
||||
-- music services
|
||||
spotify_id VARCHAR(21) UNIQUE,
|
||||
tidal_id VARCHAR(10) UNIQUE,
|
||||
spotify_id varchar(21) unique,
|
||||
tidal_id varchar(10) unique,
|
||||
|
||||
PRIMARY KEY (id)
|
||||
primary key (id)
|
||||
);
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
-- This file should undo anything in `up.sql`
|
||||
DROP TABLE playlists_tracks;
|
||||
drop table playlists_tracks;
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
CREATE TABLE IF NOT EXISTS playlists_tracks (
|
||||
playlist_id VARCHAR(24) REFERENCES playlists(id),
|
||||
track_id VARCHAR(24) REFERENCES tracks(id),
|
||||
PRIMARY KEY (playlist_id, track_id)
|
||||
create table if not exists playlists_tracks
|
||||
(
|
||||
playlist_id varchar(24) references playlists (id) on delete cascade,
|
||||
track_id varchar(24) references tracks (id) on delete cascade,
|
||||
primary key (playlist_id, track_id)
|
||||
);
|
||||
|
|
2
migrations/2023-12-31-104738_artists/down.sql
Normal file
2
migrations/2023-12-31-104738_artists/down.sql
Normal file
|
@ -0,0 +1,2 @@
|
|||
-- This file should undo anything in `up.sql`
|
||||
drop table artists;
|
15
migrations/2023-12-31-104738_artists/up.sql
Normal file
15
migrations/2023-12-31-104738_artists/up.sql
Normal file
|
@ -0,0 +1,15 @@
|
|||
-- Your SQL goes here
|
||||
create table if not exists artists
|
||||
(
|
||||
id varchar(24) default nanoid(24),
|
||||
name varchar(255) NOT NULL,
|
||||
|
||||
created_at TIMESTAMP DEFAULT now() NOT NULL,
|
||||
updated_at TIMESTAMP,
|
||||
|
||||
-- music services
|
||||
spotify_id VARCHAR(21) UNIQUE,
|
||||
tidal_id VARCHAR(10) UNIQUE,
|
||||
|
||||
primary key (id)
|
||||
);
|
2
migrations/2023-12-31-104741_artists_tracks/down.sql
Normal file
2
migrations/2023-12-31-104741_artists_tracks/down.sql
Normal file
|
@ -0,0 +1,2 @@
|
|||
-- This file should undo anything in `up.sql`
|
||||
drop table artists_tracks;
|
8
migrations/2023-12-31-104741_artists_tracks/up.sql
Normal file
8
migrations/2023-12-31-104741_artists_tracks/up.sql
Normal file
|
@ -0,0 +1,8 @@
|
|||
-- Your SQL goes here
|
||||
create table if not exists artists_tracks
|
||||
(
|
||||
artist_id varchar(24) references artists (id) on delete cascade,
|
||||
track_id varchar(24) references tracks (id) on delete cascade,
|
||||
|
||||
primary key (artist_id, track_id)
|
||||
);
|
|
@ -1,13 +1,18 @@
|
|||
use crate::utils::get_jwt_secret;
|
||||
use jwt::VerifyWithKey;
|
||||
use std::collections::BTreeMap;
|
||||
use crate::routes::auth::JWTClaims;
|
||||
use jsonwebtoken::errors::Error;
|
||||
use jsonwebtoken::{decode, DecodingKey, EncodingKey, TokenData, Validation};
|
||||
|
||||
pub fn get_token(token: &str) -> Result<BTreeMap<String, String>, &str> {
|
||||
let secret = get_jwt_secret().unwrap();
|
||||
let claims = token.verify_with_key(&secret);
|
||||
const JWT_SECRET: &str = "secret";
|
||||
|
||||
match claims {
|
||||
Ok(claims) => Ok(claims),
|
||||
Err(_e) => return Err("Error parsing token"),
|
||||
}
|
||||
pub fn get_token(token: &str) -> Result<TokenData<JWTClaims>, Error> {
|
||||
let token = decode::<JWTClaims>(&token, &get_decoding_key(), &Validation::default())?;
|
||||
Ok(token)
|
||||
}
|
||||
|
||||
pub fn get_encoding_key() -> EncodingKey {
|
||||
EncodingKey::from_secret(JWT_SECRET.as_ref())
|
||||
}
|
||||
|
||||
pub fn get_decoding_key() -> DecodingKey {
|
||||
DecodingKey::from_secret(JWT_SECRET.as_ref())
|
||||
}
|
||||
|
|
|
@ -1,9 +1,10 @@
|
|||
extern crate core;
|
||||
|
||||
mod helpers;
|
||||
mod middlewares;
|
||||
mod models;
|
||||
mod routes;
|
||||
mod schema;
|
||||
mod utils;
|
||||
|
||||
use crate::helpers::db;
|
||||
use actix_web::{web, App, HttpServer};
|
||||
|
@ -20,7 +21,7 @@ async fn main() -> std::io::Result<()> {
|
|||
.service(web::scope("/playlists").service(routes::playlists::get_playlist))
|
||||
.service(routes::auth::login)
|
||||
.service(routes::me::routes())
|
||||
.service(web::scope("/users").service(routes::users::get_user))
|
||||
.service(routes::users::routes())
|
||||
})
|
||||
.bind(("127.0.0.1", 9000))?
|
||||
.run()
|
||||
|
|
|
@ -9,18 +9,24 @@ pub fn get_user(req: HttpRequest) -> Result<Users, ErrorResponse> {
|
|||
|
||||
match authorization {
|
||||
Some(header) => {
|
||||
let claims = get_token(header.to_str().unwrap());
|
||||
let token_data = get_token(header.to_str().unwrap());
|
||||
|
||||
match claims {
|
||||
Ok(claims) => {
|
||||
let user = Users::find(claims["user_id"].as_str())?;
|
||||
match token_data {
|
||||
Ok(token_data) => {
|
||||
let user = Users::find(token_data.claims.user_id.as_str())?;
|
||||
|
||||
Ok(user)
|
||||
}
|
||||
Err(e) => {
|
||||
return Err(ErrorResponse {
|
||||
return Err(match e.kind() {
|
||||
jsonwebtoken::errors::ErrorKind::ExpiredSignature => ErrorResponse {
|
||||
message: "Not Authorized".to_string(),
|
||||
status: StatusCode::UNAUTHORIZED,
|
||||
},
|
||||
_ => ErrorResponse {
|
||||
message: e.to_string(),
|
||||
status: StatusCode::INTERNAL_SERVER_ERROR,
|
||||
},
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
79
src/models/artists.rs
Normal file
79
src/models/artists.rs
Normal file
|
@ -0,0 +1,79 @@
|
|||
use crate::helpers::db;
|
||||
use crate::schema::{artists, artists_tracks};
|
||||
use chrono::NaiveDateTime;
|
||||
use diesel::result::Error;
|
||||
use diesel::{
|
||||
AsChangeset, ExpressionMethods, Insertable, QueryDsl, Queryable, RunQueryDsl, Selectable,
|
||||
};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(AsChangeset, Insertable, Queryable, Selectable, Deserialize, Serialize)]
|
||||
#[diesel(table_name = crate::schema::artists)]
|
||||
#[diesel(check_for_backend(diesel::pg::Pg))]
|
||||
pub struct Artist {
|
||||
pub id: String,
|
||||
pub name: String,
|
||||
|
||||
created_at: NaiveDateTime,
|
||||
updated_at: Option<NaiveDateTime>,
|
||||
|
||||
pub spotify_id: Option<String>,
|
||||
pub tidal_id: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize, Queryable, Serialize)]
|
||||
pub struct Artists {
|
||||
pub id: String,
|
||||
pub title: String,
|
||||
|
||||
created_at: NaiveDateTime,
|
||||
updated_at: Option<NaiveDateTime>,
|
||||
|
||||
pub spotify_id: Option<String>,
|
||||
pub tidal_id: Option<String>,
|
||||
}
|
||||
|
||||
impl Artists {
|
||||
pub fn find(id: String) -> Result<Self, Error> {
|
||||
let conn = &mut db::connection()?;
|
||||
let playlist = artists::table.filter(artists::id.eq(id)).first(conn)?;
|
||||
Ok(playlist)
|
||||
}
|
||||
|
||||
pub fn create(artist: Artist) -> Result<Self, Error> {
|
||||
let conn = &mut db::connection()?;
|
||||
let playlist = diesel::insert_into(artists::table)
|
||||
.values(Artist::from(artist))
|
||||
.get_result(conn)?;
|
||||
Ok(playlist)
|
||||
}
|
||||
|
||||
pub fn find_by_track(track_id: &str) -> Result<Vec<Artists>, Error> {
|
||||
let conn = &mut db::connection()?;
|
||||
let tracks: Vec<(String, String)> = artists_tracks::table
|
||||
.filter(artists_tracks::track_id.eq(track_id))
|
||||
.get_results::<(String, String)>(conn)?;
|
||||
|
||||
let artists = tracks
|
||||
.into_iter()
|
||||
.map(|(artist_id, _)| Artists::find(artist_id).unwrap())
|
||||
.collect::<Vec<Artists>>();
|
||||
|
||||
Ok(artists)
|
||||
}
|
||||
}
|
||||
|
||||
impl Artist {
|
||||
fn from(artist: Artist) -> Artist {
|
||||
Artist {
|
||||
id: artist.id,
|
||||
name: artist.name,
|
||||
|
||||
created_at: artist.created_at,
|
||||
updated_at: artist.updated_at,
|
||||
|
||||
spotify_id: artist.spotify_id,
|
||||
tidal_id: artist.tidal_id,
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,3 +1,4 @@
|
|||
pub mod playlist;
|
||||
pub mod artists;
|
||||
pub mod playlists;
|
||||
pub mod tracks;
|
||||
pub mod user;
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
use crate::helpers::db;
|
||||
use crate::models::tracks::Tracks;
|
||||
use crate::models::tracks::{Track, Tracks, TracksWithArtists};
|
||||
use crate::models::user::Users;
|
||||
use crate::schema::playlists;
|
||||
use chrono::NaiveDateTime;
|
||||
use diesel::result::Error;
|
||||
use diesel::{
|
||||
AsChangeset, EqAll, ExpressionMethods, Insertable, QueryDsl, Queryable, RunQueryDsl, Selectable,
|
||||
AsChangeset, ExpressionMethods, Insertable, QueryDsl, Queryable, RunQueryDsl, Selectable,
|
||||
};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
|
@ -22,6 +22,7 @@ pub struct PlaylistCreator {
|
|||
pub struct Playlist {
|
||||
pub id: String,
|
||||
pub name: String,
|
||||
pub public: bool,
|
||||
pub creator_id: String,
|
||||
|
||||
pub created_at: NaiveDateTime,
|
||||
|
@ -32,6 +33,7 @@ pub struct Playlist {
|
|||
pub struct Playlists {
|
||||
pub id: String,
|
||||
pub name: String,
|
||||
pub public: bool,
|
||||
pub creator_id: String,
|
||||
|
||||
pub created_at: NaiveDateTime,
|
||||
|
@ -45,24 +47,36 @@ impl Playlists {
|
|||
Ok(playlist)
|
||||
}
|
||||
|
||||
pub fn create(playlist: Playlist) -> Result<Self, Error> {
|
||||
pub fn create(playlist: NewPlaylist) -> Result<Self, Error> {
|
||||
let conn = &mut db::connection()?;
|
||||
let playlist = diesel::insert_into(playlists::table)
|
||||
.values(Playlist::from(playlist))
|
||||
.values(playlist)
|
||||
.get_result(conn)?;
|
||||
Ok(playlist)
|
||||
}
|
||||
|
||||
pub fn find_for_user(user_id: &str) -> Result<Vec<Playlists>, Error> {
|
||||
pub fn find_for_user(user_id: &str, filter_public: bool) -> Result<Vec<Playlists>, Error> {
|
||||
let conn = &mut db::connection()?;
|
||||
let playlists = playlists::table
|
||||
|
||||
let mut playlists = playlists::table
|
||||
.filter(playlists::creator_id.eq(user_id))
|
||||
.get_results(conn)?;
|
||||
.into_boxed();
|
||||
|
||||
if filter_public {
|
||||
playlists = playlists.filter(playlists::public.eq(true));
|
||||
}
|
||||
|
||||
let playlists = playlists.get_results(conn)?;
|
||||
Ok(playlists)
|
||||
}
|
||||
|
||||
pub fn get_tracks(&self) -> Result<Vec<Tracks>, Error> {
|
||||
pub fn get_tracks(&self) -> Result<Vec<TracksWithArtists>, Error> {
|
||||
let tracks = Tracks::find_by_playlist(&self.id)?;
|
||||
let tracks: Vec<TracksWithArtists> = tracks
|
||||
.into_iter()
|
||||
.map(Track::with_artists)
|
||||
.collect::<Result<Vec<TracksWithArtists>, _>>()?;
|
||||
|
||||
Ok(tracks)
|
||||
}
|
||||
|
||||
|
@ -72,11 +86,28 @@ impl Playlists {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Insertable, Deserialize)]
|
||||
#[diesel(table_name = playlists)]
|
||||
pub struct NewPlaylist {
|
||||
pub name: String,
|
||||
pub public: bool,
|
||||
pub creator_id: Option<String>,
|
||||
}
|
||||
|
||||
impl Playlist {
|
||||
pub fn create(name: &str, public: bool, creator_id: &str) -> NewPlaylist {
|
||||
NewPlaylist {
|
||||
name: name.to_string(),
|
||||
public,
|
||||
creator_id: Some(creator_id.to_string()),
|
||||
}
|
||||
}
|
||||
|
||||
fn from(playlist: Playlist) -> Playlist {
|
||||
Playlist {
|
||||
id: playlist.id,
|
||||
name: playlist.name,
|
||||
public: playlist.public,
|
||||
creator_id: playlist.creator_id,
|
||||
|
||||
created_at: playlist.created_at,
|
|
@ -1,4 +1,5 @@
|
|||
use crate::helpers::db;
|
||||
use crate::models::artists::Artists;
|
||||
use crate::schema::tracks;
|
||||
use chrono::NaiveDateTime;
|
||||
use diesel::result::Error;
|
||||
|
@ -69,11 +70,10 @@ impl Tracks {
|
|||
Ok(tracks)
|
||||
}
|
||||
|
||||
// pub fn get_artist(&self) -> Result<Artist, Error> {
|
||||
// let conn = &mut db::connection();
|
||||
// let artist = ;
|
||||
// Ok(artist)
|
||||
// }
|
||||
pub fn get_artists(&self) -> Result<Vec<Artists>, Error> {
|
||||
let artists = Artists::find_by_track(&self.id)?;
|
||||
Ok(artists)
|
||||
}
|
||||
}
|
||||
|
||||
impl Track {
|
||||
|
@ -90,4 +90,31 @@ impl Track {
|
|||
tidal_id: track.tidal_id,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn with_artists(track: Tracks) -> Result<TracksWithArtists, Error> {
|
||||
let artists = track.get_artists()?;
|
||||
|
||||
Ok(TracksWithArtists {
|
||||
id: track.id,
|
||||
title: track.title,
|
||||
duration_ms: track.duration_ms,
|
||||
|
||||
artists,
|
||||
|
||||
spotify_id: track.spotify_id,
|
||||
tidal_id: track.tidal_id,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Deserialize, Serialize)]
|
||||
pub struct TracksWithArtists {
|
||||
pub id: String,
|
||||
pub title: String,
|
||||
pub duration_ms: i32,
|
||||
|
||||
pub artists: Vec<Artists>,
|
||||
|
||||
pub spotify_id: Option<String>,
|
||||
pub tidal_id: Option<String>,
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
use crate::helpers::db;
|
||||
use crate::schema::users;
|
||||
use bcrypt::BcryptError;
|
||||
use chrono::NaiveDateTime;
|
||||
use diesel::result::Error;
|
||||
use diesel::{
|
||||
|
@ -54,8 +55,8 @@ impl Users {
|
|||
Ok(user)
|
||||
}
|
||||
|
||||
pub fn verify_password(password: &str, user: &Users) -> bool {
|
||||
bcrypt::verify(password, &user.password).unwrap()
|
||||
pub fn verify_password(password: &str, hash: &str) -> Result<bool, BcryptError> {
|
||||
bcrypt::verify(password, hash)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,40 +1,53 @@
|
|||
use crate::helpers::jwt::get_encoding_key;
|
||||
use crate::middlewares::error::ErrorResponse;
|
||||
use crate::models::user::Users;
|
||||
use crate::utils::get_jwt_secret;
|
||||
use actix_web::http::StatusCode;
|
||||
use actix_web::{post, web, HttpResponse};
|
||||
use jwt::SignWithKey;
|
||||
use chrono::{Days, Utc};
|
||||
use jsonwebtoken::{encode, Header};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::collections::BTreeMap;
|
||||
|
||||
#[derive(Debug, Deserialize, Serialize)]
|
||||
pub struct JWTClaims {
|
||||
pub user_id: String,
|
||||
pub exp: usize,
|
||||
}
|
||||
|
||||
#[post("/auth/login")]
|
||||
async fn login(body: web::Json<LoginBody>) -> Result<HttpResponse, ErrorResponse> {
|
||||
#[derive(Deserialize, Serialize)]
|
||||
struct Response {
|
||||
access_token: String,
|
||||
exp: usize,
|
||||
}
|
||||
|
||||
let user = Users::find_by_email(&body.email);
|
||||
match user {
|
||||
Ok(user) => {
|
||||
let password = Users::verify_password(&body.password, &user);
|
||||
Ok(user) => match Users::verify_password(&body.password, &user.password) {
|
||||
Ok(_res) => {
|
||||
let exp = Utc::now()
|
||||
.checked_add_days(Days::new(30))
|
||||
.expect("valid timestamp")
|
||||
.timestamp();
|
||||
|
||||
if password == false {
|
||||
let claims = JWTClaims {
|
||||
user_id: user.id.to_string(),
|
||||
exp: exp as usize,
|
||||
};
|
||||
let token = encode(&Header::default(), &claims, &get_encoding_key()).unwrap();
|
||||
|
||||
Ok(HttpResponse::Ok().json(Response {
|
||||
access_token: token,
|
||||
exp: exp as usize,
|
||||
}))
|
||||
}
|
||||
Err(_e) => {
|
||||
return Err(ErrorResponse {
|
||||
message: "Invalid credentials.".to_string(),
|
||||
status: StatusCode::BAD_REQUEST,
|
||||
});
|
||||
}
|
||||
|
||||
let key = get_jwt_secret().unwrap();
|
||||
let mut claims = BTreeMap::new();
|
||||
claims.insert("user_id", &user.id);
|
||||
let token_str = claims.sign_with_key(&key).unwrap();
|
||||
|
||||
Ok(HttpResponse::Ok().json(Response {
|
||||
access_token: token_str,
|
||||
}))
|
||||
})
|
||||
}
|
||||
},
|
||||
Err(_err) => {
|
||||
return Err(ErrorResponse {
|
||||
message: "Invalid credentials.".to_string(),
|
||||
|
|
|
@ -1,11 +1,14 @@
|
|||
use crate::middlewares::error::ErrorResponse;
|
||||
use crate::middlewares::user::get_user;
|
||||
use crate::models::playlist::Playlists;
|
||||
use actix_web::{get, web, HttpRequest, HttpResponse, Scope};
|
||||
use crate::models::playlists::{NewPlaylist, Playlists};
|
||||
use actix_web::{get, post, web, HttpRequest, HttpResponse, Scope};
|
||||
use serde::Serialize;
|
||||
|
||||
pub fn routes() -> Scope {
|
||||
web::scope("/me").service(me).service(me_playlists)
|
||||
web::scope("/me")
|
||||
.service(me)
|
||||
.service(me_playlists)
|
||||
.service(create_playlist)
|
||||
}
|
||||
|
||||
#[derive(Serialize)]
|
||||
|
@ -36,6 +39,20 @@ async fn me_playlists(req: HttpRequest) -> Result<HttpResponse, ErrorResponse> {
|
|||
}
|
||||
|
||||
Ok(HttpResponse::Ok().json(Response {
|
||||
playlists: Playlists::find_for_user(&user.id)?,
|
||||
playlists: Playlists::find_for_user(&user.id, false)?,
|
||||
}))
|
||||
}
|
||||
|
||||
#[post("/playlists")]
|
||||
async fn create_playlist(
|
||||
req: HttpRequest,
|
||||
mut playlist: web::Json<NewPlaylist>,
|
||||
) -> Result<HttpResponse, ErrorResponse> {
|
||||
let user = get_user(req)?;
|
||||
|
||||
playlist.creator_id = Option::from(user.id);
|
||||
|
||||
Playlists::create(playlist.into_inner())?;
|
||||
|
||||
Ok(HttpResponse::Accepted().finish())
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use crate::middlewares::error::ErrorResponse;
|
||||
use crate::models::playlist::{PlaylistCreator, Playlists};
|
||||
use crate::models::tracks::Tracks;
|
||||
use crate::models::playlists::{PlaylistCreator, Playlists};
|
||||
use crate::models::tracks::TracksWithArtists;
|
||||
use actix_web::{get, web, HttpResponse};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
|
@ -9,7 +9,9 @@ struct GetPlaylistResponse {
|
|||
pub id: String,
|
||||
pub name: String,
|
||||
pub creator: PlaylistCreator,
|
||||
pub tracks: Vec<Tracks>,
|
||||
pub tracks: Vec<TracksWithArtists>,
|
||||
pub tracks_count: usize,
|
||||
pub duration: usize,
|
||||
}
|
||||
|
||||
#[get("/{playlist_id}")]
|
||||
|
@ -19,6 +21,14 @@ pub async fn get_playlist(path: web::Path<String>) -> Result<HttpResponse, Error
|
|||
|
||||
let creator = playlist.get_creator()?;
|
||||
|
||||
let tracks = playlist.get_tracks()?;
|
||||
let tracks_count = tracks.len();
|
||||
let duration = tracks
|
||||
.iter()
|
||||
.map(|track| track.duration_ms)
|
||||
.reduce(|a, b| a + b)
|
||||
.unwrap() as usize;
|
||||
|
||||
Ok(HttpResponse::Ok().json(GetPlaylistResponse {
|
||||
id: playlist.id.to_string(),
|
||||
name: playlist.name.to_string(),
|
||||
|
@ -26,6 +36,8 @@ pub async fn get_playlist(path: web::Path<String>) -> Result<HttpResponse, Error
|
|||
id: creator.id,
|
||||
name: creator.name,
|
||||
},
|
||||
tracks: playlist.get_tracks()?,
|
||||
tracks,
|
||||
tracks_count,
|
||||
duration,
|
||||
}))
|
||||
}
|
||||
|
|
|
@ -1,27 +1,29 @@
|
|||
use crate::middlewares::error::ErrorResponse;
|
||||
use crate::models::playlists::Playlists;
|
||||
use crate::models::user::Users;
|
||||
use actix_web::http::StatusCode;
|
||||
use actix_web::{get, web, HttpResponse, Result};
|
||||
use actix_web::{get, web, HttpResponse, Result, Scope};
|
||||
use diesel::result::Error as DBError;
|
||||
use serde::Serialize;
|
||||
|
||||
pub fn routes() -> Scope {
|
||||
web::scope("/users")
|
||||
.service(get_user)
|
||||
.service(get_user_playlists)
|
||||
}
|
||||
|
||||
#[derive(Serialize)]
|
||||
struct GetUserResponse {
|
||||
id: String,
|
||||
name: String,
|
||||
cover: String,
|
||||
}
|
||||
|
||||
#[get("/{user_id}")]
|
||||
async fn get_user(path: web::Path<String>) -> Result<HttpResponse, ErrorResponse> {
|
||||
let user_id = path.into_inner();
|
||||
|
||||
let user = Users::find(user_id.as_str());
|
||||
fn get_a_user(user_id: &str) -> Result<Users, ErrorResponse> {
|
||||
let user = Users::find(user_id);
|
||||
|
||||
match user {
|
||||
Ok(user) => Ok(HttpResponse::Ok().json(GetUserResponse {
|
||||
id: user.id,
|
||||
name: user.name,
|
||||
})),
|
||||
Ok(user) => Ok(user),
|
||||
Err(DBError::NotFound) => {
|
||||
return Err(ErrorResponse {
|
||||
message: "User not found".to_string(),
|
||||
|
@ -36,3 +38,24 @@ async fn get_user(path: web::Path<String>) -> Result<HttpResponse, ErrorResponse
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[get("/{user_id}")]
|
||||
async fn get_user(path: web::Path<String>) -> Result<HttpResponse, ErrorResponse> {
|
||||
let user = get_a_user(&path.into_inner())?;
|
||||
let user_id = &user.id;
|
||||
|
||||
Ok(HttpResponse::Ok().json(GetUserResponse {
|
||||
id: user_id.to_string(),
|
||||
name: user.name,
|
||||
cover: format!("https://assets.vybr.net/users/{}.png", user_id),
|
||||
}))
|
||||
}
|
||||
|
||||
#[get("/{user_id}/playlists")]
|
||||
async fn get_user_playlists(path: web::Path<String>) -> Result<HttpResponse, ErrorResponse> {
|
||||
let user = get_a_user(&path.into_inner())?;
|
||||
|
||||
let playlists = Playlists::find_for_user(&user.id, true)?;
|
||||
|
||||
Ok(HttpResponse::Ok().json(playlists))
|
||||
}
|
||||
|
|
|
@ -1,11 +1,36 @@
|
|||
// @generated automatically by Diesel CLI.
|
||||
|
||||
diesel::table! {
|
||||
artists (id) {
|
||||
#[max_length = 24]
|
||||
id -> Varchar,
|
||||
#[max_length = 255]
|
||||
name -> Varchar,
|
||||
created_at -> Timestamp,
|
||||
updated_at -> Nullable<Timestamp>,
|
||||
#[max_length = 21]
|
||||
spotify_id -> Nullable<Varchar>,
|
||||
#[max_length = 10]
|
||||
tidal_id -> Nullable<Varchar>,
|
||||
}
|
||||
}
|
||||
|
||||
diesel::table! {
|
||||
artists_tracks (artist_id, track_id) {
|
||||
#[max_length = 24]
|
||||
artist_id -> Varchar,
|
||||
#[max_length = 24]
|
||||
track_id -> Varchar,
|
||||
}
|
||||
}
|
||||
|
||||
diesel::table! {
|
||||
playlists (id) {
|
||||
#[max_length = 24]
|
||||
id -> Varchar,
|
||||
#[max_length = 255]
|
||||
name -> Varchar,
|
||||
public -> Bool,
|
||||
#[max_length = 24]
|
||||
creator_id -> Varchar,
|
||||
created_at -> Timestamp,
|
||||
|
@ -52,11 +77,15 @@ diesel::table! {
|
|||
}
|
||||
}
|
||||
|
||||
diesel::joinable!(artists_tracks -> artists (artist_id));
|
||||
diesel::joinable!(artists_tracks -> tracks (track_id));
|
||||
diesel::joinable!(playlists -> users (creator_id));
|
||||
diesel::joinable!(playlists_tracks -> playlists (playlist_id));
|
||||
diesel::joinable!(playlists_tracks -> tracks (track_id));
|
||||
|
||||
diesel::allow_tables_to_appear_in_same_query!(
|
||||
artists,
|
||||
artists_tracks,
|
||||
playlists,
|
||||
playlists_tracks,
|
||||
tracks,
|
||||
|
|
|
@ -1,8 +0,0 @@
|
|||
use hmac::{Hmac, Mac};
|
||||
use sha2::Sha256;
|
||||
use std::error::Error;
|
||||
|
||||
pub fn get_jwt_secret() -> Result<Hmac<Sha256>, Box<dyn Error>> {
|
||||
let key: Hmac<Sha256> = Hmac::new_from_slice(b"secret")?;
|
||||
Ok(key)
|
||||
}
|
Loading…
Reference in a new issue