feat(api): fully implemented the register endpoint
This commit is contained in:
parent
2f2aa0e4a3
commit
b794574850
|
@ -55,7 +55,7 @@ dependencies = [
|
||||||
"tokio",
|
"tokio",
|
||||||
"tokio-util",
|
"tokio-util",
|
||||||
"tracing",
|
"tracing",
|
||||||
"zstd",
|
"zstd 0.12.4",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -213,6 +213,17 @@ version = "1.0.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
|
checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "aes"
|
||||||
|
version = "0.8.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ac1f845298e95f983ff1944b728ae08b8cebab80d684f0a832ed0fc74dfa27e2"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
"cipher",
|
||||||
|
"cpufeatures",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ahash"
|
name = "ahash"
|
||||||
version = "0.7.6"
|
version = "0.7.6"
|
||||||
|
@ -336,6 +347,17 @@ version = "1.0.72"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "3b13c32d80ecc7ab747b80c3784bce54ee8a7a0cc4fbda9bf4cda2cf6fe90854"
|
checksum = "3b13c32d80ecc7ab747b80c3784bce54ee8a7a0cc4fbda9bf4cda2cf6fe90854"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "async-trait"
|
||||||
|
version = "0.1.73"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "bc00ceb34980c03614e35a3a4e218276a0a824e911d07651cd0d858a51e8c0f0"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn 2.0.28",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "atoi"
|
name = "atoi"
|
||||||
version = "2.0.0"
|
version = "2.0.0"
|
||||||
|
@ -372,6 +394,12 @@ version = "0.13.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8"
|
checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "base64"
|
||||||
|
version = "0.20.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0ea22880d78093b0cbe17c89f64a7d457941e65759157ec6cb31a31d652b05e5"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "base64"
|
name = "base64"
|
||||||
version = "0.21.2"
|
version = "0.21.2"
|
||||||
|
@ -478,6 +506,27 @@ dependencies = [
|
||||||
"bytes",
|
"bytes",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bzip2"
|
||||||
|
version = "0.4.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "bdb116a6ef3f6c3698828873ad02c3014b3c85cadb88496095628e3ef1e347f8"
|
||||||
|
dependencies = [
|
||||||
|
"bzip2-sys",
|
||||||
|
"libc",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bzip2-sys"
|
||||||
|
version = "0.1.11+1.0.8"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "736a955f3fa7875102d57c82b8cac37ec45224a07fd32d58f9f7a186b6cd4cdc"
|
||||||
|
dependencies = [
|
||||||
|
"cc",
|
||||||
|
"libc",
|
||||||
|
"pkg-config",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "cc"
|
name = "cc"
|
||||||
version = "1.0.82"
|
version = "1.0.82"
|
||||||
|
@ -518,6 +567,16 @@ dependencies = [
|
||||||
"winapi",
|
"winapi",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cipher"
|
||||||
|
version = "0.4.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad"
|
||||||
|
dependencies = [
|
||||||
|
"crypto-common",
|
||||||
|
"inout",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "clang-sys"
|
name = "clang-sys"
|
||||||
version = "1.6.1"
|
version = "1.6.1"
|
||||||
|
@ -582,6 +641,12 @@ version = "0.9.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "28c122c3980598d243d63d9a704629a2d748d101f278052ff068be5a4423ab6f"
|
checksum = "28c122c3980598d243d63d9a704629a2d748d101f278052ff068be5a4423ab6f"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "constant_time_eq"
|
||||||
|
version = "0.1.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "convert_case"
|
name = "convert_case"
|
||||||
version = "0.4.0"
|
version = "0.4.0"
|
||||||
|
@ -667,6 +732,12 @@ dependencies = [
|
||||||
"typenum",
|
"typenum",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "data-encoding"
|
||||||
|
version = "2.4.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c2e66c9d817f1720209181c316d28635c050fa304f9c79e47a520882661b7308"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "der"
|
name = "der"
|
||||||
version = "0.7.8"
|
version = "0.7.8"
|
||||||
|
@ -733,6 +804,18 @@ dependencies = [
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "enum-as-inner"
|
||||||
|
version = "0.5.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c9720bba047d567ffc8a3cba48bf19126600e249ab7f128e9233e6376976a116"
|
||||||
|
dependencies = [
|
||||||
|
"heck",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn 1.0.109",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "env_logger"
|
name = "env_logger"
|
||||||
version = "0.10.0"
|
version = "0.10.0"
|
||||||
|
@ -915,6 +998,16 @@ dependencies = [
|
||||||
"version_check",
|
"version_check",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "gethostname"
|
||||||
|
version = "0.4.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0176e0459c2e4a1fe232f984bca6890e681076abb9934f6cea7c326f3fc47818"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
"windows-targets",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "getrandom"
|
name = "getrandom"
|
||||||
version = "0.2.10"
|
version = "0.2.10"
|
||||||
|
@ -1045,6 +1138,17 @@ dependencies = [
|
||||||
"windows-sys",
|
"windows-sys",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "hostname"
|
||||||
|
version = "0.3.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3c731c3e10504cc8ed35cfe2f1db4c9274c3d35fa486e3b31df46f068ef3e867"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
"match_cfg",
|
||||||
|
"winapi",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "http"
|
name = "http"
|
||||||
version = "0.2.9"
|
version = "0.2.9"
|
||||||
|
@ -1097,6 +1201,17 @@ dependencies = [
|
||||||
"cc",
|
"cc",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "idna"
|
||||||
|
version = "0.2.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "418a0a6fab821475f634efe3ccc45c013f742efe03d853e8d3355d5cb850ecf8"
|
||||||
|
dependencies = [
|
||||||
|
"matches",
|
||||||
|
"unicode-bidi",
|
||||||
|
"unicode-normalization",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "idna"
|
name = "idna"
|
||||||
version = "0.4.0"
|
version = "0.4.0"
|
||||||
|
@ -1127,6 +1242,33 @@ dependencies = [
|
||||||
"hashbrown 0.14.0",
|
"hashbrown 0.14.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "inout"
|
||||||
|
version = "0.1.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a0c10553d664a4d0bcff9f4215d0aac67a639cc68ef660840afe309b807bc9f5"
|
||||||
|
dependencies = [
|
||||||
|
"generic-array",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ipconfig"
|
||||||
|
version = "0.3.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b58db92f96b720de98181bbbe63c831e87005ab460c1bf306eb2622b4707997f"
|
||||||
|
dependencies = [
|
||||||
|
"socket2 0.5.3",
|
||||||
|
"widestring",
|
||||||
|
"windows-sys",
|
||||||
|
"winreg",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ipnet"
|
||||||
|
version = "2.8.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "28b29a3cd74f0f4598934efe3aeba42bae0eb4680554128851ebbecb02af14e6"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "is-terminal"
|
name = "is-terminal"
|
||||||
version = "0.4.9"
|
version = "0.4.9"
|
||||||
|
@ -1275,6 +1417,12 @@ dependencies = [
|
||||||
"vcpkg",
|
"vcpkg",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "linked-hash-map"
|
||||||
|
version = "0.5.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "linux-raw-sys"
|
name = "linux-raw-sys"
|
||||||
version = "0.4.5"
|
version = "0.4.5"
|
||||||
|
@ -1315,6 +1463,85 @@ version = "0.4.19"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b06a4cde4c0f271a446782e3eff8de789548ce57dbc8eca9292c27f4a42004b4"
|
checksum = "b06a4cde4c0f271a446782e3eff8de789548ce57dbc8eca9292c27f4a42004b4"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "lru-cache"
|
||||||
|
version = "0.1.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "31e24f1ad8321ca0e8a1e0ac13f23cb668e6f5466c2c57319f6a5cf1cc8e3b1c"
|
||||||
|
dependencies = [
|
||||||
|
"linked-hash-map",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "mail-auth"
|
||||||
|
version = "0.3.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c6b0969bac270a60560d3a6f89c812b3e39b2f4b3ca8d866063f482030d14f19"
|
||||||
|
dependencies = [
|
||||||
|
"ahash 0.8.3",
|
||||||
|
"flate2",
|
||||||
|
"lru-cache",
|
||||||
|
"mail-builder",
|
||||||
|
"mail-parser",
|
||||||
|
"parking_lot",
|
||||||
|
"quick-xml",
|
||||||
|
"ring",
|
||||||
|
"rustls-pemfile",
|
||||||
|
"serde",
|
||||||
|
"serde_json",
|
||||||
|
"trust-dns-resolver",
|
||||||
|
"zip",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "mail-builder"
|
||||||
|
version = "0.3.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "765969f4385f88a62738e8ed63e2fa630571d7ed6fd96ca6932d699513dd8c28"
|
||||||
|
dependencies = [
|
||||||
|
"gethostname",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "mail-parser"
|
||||||
|
version = "0.8.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e4158a1c18963244e083888b21465846dfb68d6170850ed1ab4742edd57c9d47"
|
||||||
|
dependencies = [
|
||||||
|
"encoding_rs",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "mail-send"
|
||||||
|
version = "0.4.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d6d2b8d0cb56f199d36f527ff96453cf3b1cdfdacb5e4d154ac1d8fcd89873c2"
|
||||||
|
dependencies = [
|
||||||
|
"base64 0.20.0",
|
||||||
|
"gethostname",
|
||||||
|
"mail-auth",
|
||||||
|
"mail-builder",
|
||||||
|
"md5",
|
||||||
|
"rand",
|
||||||
|
"rustls 0.21.6",
|
||||||
|
"smtp-proto",
|
||||||
|
"tokio",
|
||||||
|
"tokio-rustls 0.24.1",
|
||||||
|
"webpki-roots 0.23.1",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "match_cfg"
|
||||||
|
version = "0.1.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ffbee8634e0d45d258acb448e7eaab3fce7a0a467395d4d9f228e3c1f01fb2e4"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "matches"
|
||||||
|
version = "0.1.10"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2532096657941c2fea9c289d370a250971c689d4f143798ff67113ec042024a5"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "md-5"
|
name = "md-5"
|
||||||
version = "0.10.5"
|
version = "0.10.5"
|
||||||
|
@ -1324,6 +1551,12 @@ dependencies = [
|
||||||
"digest",
|
"digest",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "md5"
|
||||||
|
version = "0.7.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "490cc448043f947bae3cbee9c203358d62dbee0db12107a74be5c30ccfd09771"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "memchr"
|
name = "memchr"
|
||||||
version = "2.5.0"
|
version = "2.5.0"
|
||||||
|
@ -1375,7 +1608,8 @@ dependencies = [
|
||||||
"env_logger",
|
"env_logger",
|
||||||
"libinjection",
|
"libinjection",
|
||||||
"log",
|
"log",
|
||||||
"pbkdf2",
|
"mail-send",
|
||||||
|
"pbkdf2 0.12.2",
|
||||||
"serde",
|
"serde",
|
||||||
"sha2",
|
"sha2",
|
||||||
"sqlx",
|
"sqlx",
|
||||||
|
@ -1507,6 +1741,17 @@ dependencies = [
|
||||||
"windows-targets",
|
"windows-targets",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "password-hash"
|
||||||
|
version = "0.4.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "7676374caaee8a325c9e7a2ae557f216c5563a171d6997b0ef8a65af35147700"
|
||||||
|
dependencies = [
|
||||||
|
"base64ct",
|
||||||
|
"rand_core",
|
||||||
|
"subtle",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "password-hash"
|
name = "password-hash"
|
||||||
version = "0.5.0"
|
version = "0.5.0"
|
||||||
|
@ -1524,6 +1769,18 @@ version = "1.0.14"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c"
|
checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "pbkdf2"
|
||||||
|
version = "0.11.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "83a0692ec44e4cf1ef28ca317f14f8f07da2d95ec3fa01f86e4467b725e60917"
|
||||||
|
dependencies = [
|
||||||
|
"digest",
|
||||||
|
"hmac",
|
||||||
|
"password-hash 0.4.2",
|
||||||
|
"sha2",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pbkdf2"
|
name = "pbkdf2"
|
||||||
version = "0.12.2"
|
version = "0.12.2"
|
||||||
|
@ -1532,7 +1789,7 @@ checksum = "f8ed6a7761f76e3b9f92dfb0a60a6a6477c61024b775147ff0973a02653abaf2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"digest",
|
"digest",
|
||||||
"hmac",
|
"hmac",
|
||||||
"password-hash",
|
"password-hash 0.5.0",
|
||||||
"sha2",
|
"sha2",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -1631,6 +1888,21 @@ dependencies = [
|
||||||
"unicode-ident",
|
"unicode-ident",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "quick-error"
|
||||||
|
version = "1.2.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "quick-xml"
|
||||||
|
version = "0.28.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0ce5e73202a820a31f8a0ee32ada5e21029c81fd9e3ebf668a40832e4219d9d1"
|
||||||
|
dependencies = [
|
||||||
|
"memchr",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "quote"
|
name = "quote"
|
||||||
version = "1.0.32"
|
version = "1.0.32"
|
||||||
|
@ -1708,6 +1980,31 @@ version = "0.7.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e5ea92a5b6195c6ef2a0295ea818b312502c6fc94dde986c5553242e18fd4ce2"
|
checksum = "e5ea92a5b6195c6ef2a0295ea818b312502c6fc94dde986c5553242e18fd4ce2"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "resolv-conf"
|
||||||
|
version = "0.7.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "52e44394d2086d010551b14b53b1f24e31647570cd1deb0379e2c21b329aba00"
|
||||||
|
dependencies = [
|
||||||
|
"hostname",
|
||||||
|
"quick-error",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ring"
|
||||||
|
version = "0.16.20"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3053cf52e236a3ed746dfc745aa9cacf1b791d846bdaf412f60a8d7d6e17c8fc"
|
||||||
|
dependencies = [
|
||||||
|
"cc",
|
||||||
|
"libc",
|
||||||
|
"once_cell",
|
||||||
|
"spin 0.5.2",
|
||||||
|
"untrusted",
|
||||||
|
"web-sys",
|
||||||
|
"winapi",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rsa"
|
name = "rsa"
|
||||||
version = "0.9.2"
|
version = "0.9.2"
|
||||||
|
@ -1764,6 +2061,59 @@ dependencies = [
|
||||||
"windows-sys",
|
"windows-sys",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rustls"
|
||||||
|
version = "0.20.8"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "fff78fc74d175294f4e83b28343315ffcfb114b156f0185e9741cb5570f50e2f"
|
||||||
|
dependencies = [
|
||||||
|
"log",
|
||||||
|
"ring",
|
||||||
|
"sct",
|
||||||
|
"webpki",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rustls"
|
||||||
|
version = "0.21.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1d1feddffcfcc0b33f5c6ce9a29e341e4cd59c3f78e7ee45f4a40c038b1d6cbb"
|
||||||
|
dependencies = [
|
||||||
|
"log",
|
||||||
|
"ring",
|
||||||
|
"rustls-webpki 0.101.3",
|
||||||
|
"sct",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rustls-pemfile"
|
||||||
|
version = "1.0.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "2d3987094b1d07b653b7dfdc3f70ce9a1da9c51ac18c1b06b662e4f9a0e9f4b2"
|
||||||
|
dependencies = [
|
||||||
|
"base64 0.21.2",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rustls-webpki"
|
||||||
|
version = "0.100.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d6207cd5ed3d8dca7816f8f3725513a34609c0c765bf652b8c3cb4cfd87db46b"
|
||||||
|
dependencies = [
|
||||||
|
"ring",
|
||||||
|
"untrusted",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rustls-webpki"
|
||||||
|
version = "0.101.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "261e9e0888cba427c3316e6322805653c9425240b6fd96cee7cb671ab70ab8d0"
|
||||||
|
dependencies = [
|
||||||
|
"ring",
|
||||||
|
"untrusted",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ryu"
|
name = "ryu"
|
||||||
version = "1.0.15"
|
version = "1.0.15"
|
||||||
|
@ -1776,6 +2126,16 @@ version = "1.2.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
|
checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "sct"
|
||||||
|
version = "0.7.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d53dcdb7c9f8158937a7981b48accfd39a43af418591a5d008c7b22b5e1b7ca4"
|
||||||
|
dependencies = [
|
||||||
|
"ring",
|
||||||
|
"untrusted",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "semver"
|
name = "semver"
|
||||||
version = "1.0.18"
|
version = "1.0.18"
|
||||||
|
@ -1887,6 +2247,12 @@ version = "1.11.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "62bb4feee49fdd9f707ef802e22365a35de4b7b299de4763d44bfea899442ff9"
|
checksum = "62bb4feee49fdd9f707ef802e22365a35de4b7b299de4763d44bfea899442ff9"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "smtp-proto"
|
||||||
|
version = "0.1.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d4b756ac662e92a0e5b360349bea5f0b0784d4be4541eff2972049dfdfd7f862"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "socket2"
|
name = "socket2"
|
||||||
version = "0.4.9"
|
version = "0.4.9"
|
||||||
|
@ -2312,6 +2678,27 @@ dependencies = [
|
||||||
"syn 2.0.28",
|
"syn 2.0.28",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tokio-rustls"
|
||||||
|
version = "0.23.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c43ee83903113e03984cb9e5cebe6c04a5116269e900e3ddba8f068a62adda59"
|
||||||
|
dependencies = [
|
||||||
|
"rustls 0.20.8",
|
||||||
|
"tokio",
|
||||||
|
"webpki",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tokio-rustls"
|
||||||
|
version = "0.24.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081"
|
||||||
|
dependencies = [
|
||||||
|
"rustls 0.21.6",
|
||||||
|
"tokio",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tokio-stream"
|
name = "tokio-stream"
|
||||||
version = "0.1.14"
|
version = "0.1.14"
|
||||||
|
@ -2370,6 +2757,59 @@ dependencies = [
|
||||||
"once_cell",
|
"once_cell",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "trust-dns-proto"
|
||||||
|
version = "0.22.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "4f7f83d1e4a0e4358ac54c5c3681e5d7da5efc5a7a632c90bb6d6669ddd9bc26"
|
||||||
|
dependencies = [
|
||||||
|
"async-trait",
|
||||||
|
"cfg-if",
|
||||||
|
"data-encoding",
|
||||||
|
"enum-as-inner",
|
||||||
|
"futures-channel",
|
||||||
|
"futures-io",
|
||||||
|
"futures-util",
|
||||||
|
"idna 0.2.3",
|
||||||
|
"ipnet",
|
||||||
|
"lazy_static",
|
||||||
|
"rand",
|
||||||
|
"ring",
|
||||||
|
"rustls 0.20.8",
|
||||||
|
"rustls-pemfile",
|
||||||
|
"smallvec",
|
||||||
|
"thiserror",
|
||||||
|
"tinyvec",
|
||||||
|
"tokio",
|
||||||
|
"tokio-rustls 0.23.4",
|
||||||
|
"tracing",
|
||||||
|
"url",
|
||||||
|
"webpki",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "trust-dns-resolver"
|
||||||
|
version = "0.22.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "aff21aa4dcefb0a1afbfac26deb0adc93888c7d295fb63ab273ef276ba2b7cfe"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
"futures-util",
|
||||||
|
"ipconfig",
|
||||||
|
"lazy_static",
|
||||||
|
"lru-cache",
|
||||||
|
"parking_lot",
|
||||||
|
"resolv-conf",
|
||||||
|
"rustls 0.20.8",
|
||||||
|
"smallvec",
|
||||||
|
"thiserror",
|
||||||
|
"tokio",
|
||||||
|
"tokio-rustls 0.23.4",
|
||||||
|
"tracing",
|
||||||
|
"trust-dns-proto",
|
||||||
|
"webpki-roots 0.22.6",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "typenum"
|
name = "typenum"
|
||||||
version = "1.16.0"
|
version = "1.16.0"
|
||||||
|
@ -2409,6 +2849,12 @@ version = "0.1.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "39ec24b3121d976906ece63c9daad25b85969647682eee313cb5779fdd69e14e"
|
checksum = "39ec24b3121d976906ece63c9daad25b85969647682eee313cb5779fdd69e14e"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "untrusted"
|
||||||
|
version = "0.7.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "url"
|
name = "url"
|
||||||
version = "2.4.0"
|
version = "2.4.0"
|
||||||
|
@ -2416,7 +2862,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "50bff7831e19200a85b17131d085c25d7811bc4e186efdaf54bbd132994a88cb"
|
checksum = "50bff7831e19200a85b17131d085c25d7811bc4e186efdaf54bbd132994a88cb"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"form_urlencoded",
|
"form_urlencoded",
|
||||||
"idna",
|
"idna 0.4.0",
|
||||||
"percent-encoding",
|
"percent-encoding",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -2513,6 +2959,44 @@ version = "0.2.87"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ca6ad05a4870b2bf5fe995117d3728437bd27d7cd5f06f13c17443ef369775a1"
|
checksum = "ca6ad05a4870b2bf5fe995117d3728437bd27d7cd5f06f13c17443ef369775a1"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "web-sys"
|
||||||
|
version = "0.3.64"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9b85cbef8c220a6abc02aefd892dfc0fc23afb1c6a426316ec33253a3877249b"
|
||||||
|
dependencies = [
|
||||||
|
"js-sys",
|
||||||
|
"wasm-bindgen",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "webpki"
|
||||||
|
version = "0.22.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f095d78192e208183081cc07bc5515ef55216397af48b873e5edcd72637fa1bd"
|
||||||
|
dependencies = [
|
||||||
|
"ring",
|
||||||
|
"untrusted",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "webpki-roots"
|
||||||
|
version = "0.22.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b6c71e40d7d2c34a5106301fb632274ca37242cd0c9d3e64dbece371a40a2d87"
|
||||||
|
dependencies = [
|
||||||
|
"webpki",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "webpki-roots"
|
||||||
|
version = "0.23.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b03058f88386e5ff5310d9111d53f48b17d732b401aeb83a8d5190f2ac459338"
|
||||||
|
dependencies = [
|
||||||
|
"rustls-webpki 0.100.1",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "which"
|
name = "which"
|
||||||
version = "4.4.0"
|
version = "4.4.0"
|
||||||
|
@ -2530,6 +3014,12 @@ version = "1.4.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "22fc3756b8a9133049b26c7f61ab35416c130e8c09b660f5b3958b446f52cc50"
|
checksum = "22fc3756b8a9133049b26c7f61ab35416c130e8c09b660f5b3958b446f52cc50"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "widestring"
|
||||||
|
version = "1.0.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "653f141f39ec16bba3c5abe400a0c60da7468261cc2cbf36805022876bc721a8"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "winapi"
|
name = "winapi"
|
||||||
version = "0.3.9"
|
version = "0.3.9"
|
||||||
|
@ -2636,19 +3126,68 @@ version = "0.48.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a"
|
checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "winreg"
|
||||||
|
version = "0.50.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "524e57b2c537c0f9b1e69f1965311ec12182b4122e45035b1508cd24d2adadb1"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
"windows-sys",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "zeroize"
|
name = "zeroize"
|
||||||
version = "1.6.0"
|
version = "1.6.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "2a0956f1ba7c7909bfb66c2e9e4124ab6f6482560f6628b5aaeba39207c9aad9"
|
checksum = "2a0956f1ba7c7909bfb66c2e9e4124ab6f6482560f6628b5aaeba39207c9aad9"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "zip"
|
||||||
|
version = "0.6.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "760394e246e4c28189f19d488c058bf16f564016aefac5d32bb1f3b51d5e9261"
|
||||||
|
dependencies = [
|
||||||
|
"aes",
|
||||||
|
"byteorder",
|
||||||
|
"bzip2",
|
||||||
|
"constant_time_eq",
|
||||||
|
"crc32fast",
|
||||||
|
"crossbeam-utils",
|
||||||
|
"flate2",
|
||||||
|
"hmac",
|
||||||
|
"pbkdf2 0.11.0",
|
||||||
|
"sha1",
|
||||||
|
"time 0.3.25",
|
||||||
|
"zstd 0.11.2+zstd.1.5.2",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "zstd"
|
||||||
|
version = "0.11.2+zstd.1.5.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "20cc960326ece64f010d2d2107537f26dc589a6573a316bd5b1dba685fa5fde4"
|
||||||
|
dependencies = [
|
||||||
|
"zstd-safe 5.0.2+zstd.1.5.2",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "zstd"
|
name = "zstd"
|
||||||
version = "0.12.4"
|
version = "0.12.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1a27595e173641171fc74a1232b7b1c7a7cb6e18222c11e9dfb9888fa424c53c"
|
checksum = "1a27595e173641171fc74a1232b7b1c7a7cb6e18222c11e9dfb9888fa424c53c"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"zstd-safe",
|
"zstd-safe 6.0.6",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "zstd-safe"
|
||||||
|
version = "5.0.2+zstd.1.5.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1d2a5585e04f9eea4b2a3d1eca508c4dee9592a89ef6f450c11719da0726f4db"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
"zstd-sys",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
|
@ -20,3 +20,4 @@ actix-web-httpauth = "0.8.0"
|
||||||
sqlx = { version = "0.7.1", features = ["runtime-tokio", "mysql", "chrono"] }
|
sqlx = { version = "0.7.1", features = ["runtime-tokio", "mysql", "chrono"] }
|
||||||
uuid = { version = "1.4.1", features = ["v4"] }
|
uuid = { version = "1.4.1", features = ["v4"] }
|
||||||
chrono = "0.4"
|
chrono = "0.4"
|
||||||
|
mail-send = "0.4.0"
|
|
@ -0,0 +1,118 @@
|
||||||
|
use anyhow::{Error, Result};
|
||||||
|
use pbkdf2::{
|
||||||
|
password_hash::{rand_core::OsRng, PasswordHash, PasswordHasher, PasswordVerifier, SaltString},
|
||||||
|
Pbkdf2,
|
||||||
|
};
|
||||||
|
use sqlx::{mysql::MySqlPool, types::chrono as sqlx_chrono};
|
||||||
|
|
||||||
|
pub struct Account {
|
||||||
|
pub id: u64,
|
||||||
|
pub username: String,
|
||||||
|
pub email: String,
|
||||||
|
pub salt: String,
|
||||||
|
pub password: String,
|
||||||
|
pub joined: sqlx_chrono::NaiveDateTime,
|
||||||
|
pub verified: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Account {
|
||||||
|
/// This doesn't check if an account with that name is already existing!
|
||||||
|
pub async fn new(
|
||||||
|
pool: &MySqlPool,
|
||||||
|
username: &String,
|
||||||
|
email: &String,
|
||||||
|
password: &String,
|
||||||
|
) -> Result<Self> {
|
||||||
|
let salt = SaltString::generate(&mut OsRng);
|
||||||
|
let hash = Pbkdf2
|
||||||
|
.hash_password(password.as_bytes(), &salt)
|
||||||
|
.map_err(|_| anyhow::Error::msg("Failed to hash the password"))?
|
||||||
|
.to_string();
|
||||||
|
|
||||||
|
let joined = sqlx_chrono::Utc::now().naive_utc();
|
||||||
|
|
||||||
|
sqlx::query!(
|
||||||
|
r#"INSERT INTO Accounts (username, email, salt, password, joined, verified) VALUES (?, ?, ?, ?, ?, false);"#,
|
||||||
|
username,
|
||||||
|
email,
|
||||||
|
salt.to_string(),
|
||||||
|
hash,
|
||||||
|
joined,
|
||||||
|
)
|
||||||
|
.execute(pool)
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
match Account::from_username(pool, &username).await? {
|
||||||
|
Some(a) => Ok(a),
|
||||||
|
None => Err(Error::msg(
|
||||||
|
"The just created account can't be found in the database!",
|
||||||
|
)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn from_username(pool: &MySqlPool, username: &String) -> Result<Option<Self>> {
|
||||||
|
match sqlx::query!(r#"SELECT * FROM Accounts WHERE username = ?;"#, username)
|
||||||
|
.fetch_one(pool)
|
||||||
|
.await
|
||||||
|
{
|
||||||
|
Ok(row) => {
|
||||||
|
let account = Account {
|
||||||
|
id: row.id,
|
||||||
|
username: row.username,
|
||||||
|
email: row.email,
|
||||||
|
salt: row.salt,
|
||||||
|
password: row.password,
|
||||||
|
joined: row.joined,
|
||||||
|
verified: row.verified != 0,
|
||||||
|
};
|
||||||
|
Ok(Some(account))
|
||||||
|
}
|
||||||
|
Err(sqlx::Error::RowNotFound) => Ok(None),
|
||||||
|
Err(e) => Err(Error::new(e)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn from_id(pool: &MySqlPool, id: u64) -> Result<Option<Self>> {
|
||||||
|
match sqlx::query!(r#"SELECT * FROM Accounts WHERE id = ?;"#, id)
|
||||||
|
.fetch_one(pool)
|
||||||
|
.await
|
||||||
|
{
|
||||||
|
Ok(row) => {
|
||||||
|
let account = Account {
|
||||||
|
id: row.id,
|
||||||
|
username: row.username,
|
||||||
|
email: row.email,
|
||||||
|
salt: row.salt,
|
||||||
|
password: row.password,
|
||||||
|
joined: row.joined,
|
||||||
|
verified: row.verified != 0,
|
||||||
|
};
|
||||||
|
Ok(Some(account))
|
||||||
|
}
|
||||||
|
Err(sqlx::Error::RowNotFound) => Ok(None),
|
||||||
|
Err(e) => Err(Error::new(e)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn from_email(pool: &MySqlPool, email: &String) -> Result<Option<Self>> {
|
||||||
|
match sqlx::query!(r#"SELECT * FROM Accounts WHERE email = ?;"#, email)
|
||||||
|
.fetch_one(pool)
|
||||||
|
.await
|
||||||
|
{
|
||||||
|
Ok(row) => {
|
||||||
|
let account = Account {
|
||||||
|
id: row.id,
|
||||||
|
username: row.username,
|
||||||
|
email: row.email,
|
||||||
|
salt: row.salt,
|
||||||
|
password: row.password,
|
||||||
|
joined: row.joined,
|
||||||
|
verified: row.verified != 0,
|
||||||
|
};
|
||||||
|
Ok(Some(account))
|
||||||
|
}
|
||||||
|
Err(sqlx::Error::RowNotFound) => Ok(None),
|
||||||
|
Err(e) => Err(Error::new(e)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -9,7 +9,7 @@ async fn register(
|
||||||
data: web::Data<ApiState>,
|
data: web::Data<ApiState>,
|
||||||
body: web::Json<data::RegisterRequest>,
|
body: web::Json<data::RegisterRequest>,
|
||||||
) -> impl Responder {
|
) -> impl Responder {
|
||||||
match handlers::register(body.into_inner()).await {
|
match handlers::register(&data.pool, body.into_inner()).await {
|
||||||
Ok(resp) => match resp {
|
Ok(resp) => match resp {
|
||||||
data::RegisterResponse::Success => HttpResponse::Ok().finish(),
|
data::RegisterResponse::Success => HttpResponse::Ok().finish(),
|
||||||
data::RegisterResponse::Conflict(b) => HttpResponse::Conflict().json(web::Json(b)),
|
data::RegisterResponse::Conflict(b) => HttpResponse::Conflict().json(web::Json(b)),
|
||||||
|
@ -25,7 +25,7 @@ async fn register(
|
||||||
|
|
||||||
#[post("/account/verify")]
|
#[post("/account/verify")]
|
||||||
async fn verify(data: web::Data<ApiState>, body: web::Json<data::VerifyRequest>) -> impl Responder {
|
async fn verify(data: web::Data<ApiState>, body: web::Json<data::VerifyRequest>) -> impl Responder {
|
||||||
match handlers::verify(body.into_inner()).await {
|
match handlers::verify(&data.pool, body.into_inner()).await {
|
||||||
Ok(resp) => match resp {
|
Ok(resp) => match resp {
|
||||||
data::VerifyResponse::Success => HttpResponse::Ok().finish(),
|
data::VerifyResponse::Success => HttpResponse::Ok().finish(),
|
||||||
data::VerifyResponse::TokenUnknown => HttpResponse::NotFound().finish(),
|
data::VerifyResponse::TokenUnknown => HttpResponse::NotFound().finish(),
|
||||||
|
@ -43,7 +43,7 @@ async fn authenticate(
|
||||||
data: web::Data<ApiState>,
|
data: web::Data<ApiState>,
|
||||||
body: web::Json<data::AuthenticateRequest>,
|
body: web::Json<data::AuthenticateRequest>,
|
||||||
) -> impl Responder {
|
) -> impl Responder {
|
||||||
match handlers::authenticate(body.into_inner()).await {
|
match handlers::authenticate(&data.pool, body.into_inner()).await {
|
||||||
Ok(resp) => match resp {
|
Ok(resp) => match resp {
|
||||||
data::AuthenticateResponse::Success(b) => HttpResponse::Ok().json(web::Json(b)),
|
data::AuthenticateResponse::Success(b) => HttpResponse::Ok().json(web::Json(b)),
|
||||||
data::AuthenticateResponse::WrongPassword => HttpResponse::Unauthorized().finish(),
|
data::AuthenticateResponse::WrongPassword => HttpResponse::Unauthorized().finish(),
|
||||||
|
@ -59,7 +59,7 @@ async fn authenticate(
|
||||||
|
|
||||||
#[delete("/account/delete")]
|
#[delete("/account/delete")]
|
||||||
async fn delete(data: web::Data<ApiState>, auth: BearerAuth) -> impl Responder {
|
async fn delete(data: web::Data<ApiState>, auth: BearerAuth) -> impl Responder {
|
||||||
match handlers::delete(auth.token().to_string()).await {
|
match handlers::delete(&data.pool, auth.token().to_string()).await {
|
||||||
Ok(resp) => match resp {
|
Ok(resp) => match resp {
|
||||||
data::DeleteResponse::Success => HttpResponse::Ok().finish(),
|
data::DeleteResponse::Success => HttpResponse::Ok().finish(),
|
||||||
data::DeleteResponse::Unauthorized => HttpResponse::Unauthorized().finish(),
|
data::DeleteResponse::Unauthorized => HttpResponse::Unauthorized().finish(),
|
||||||
|
|
|
@ -1,6 +1,12 @@
|
||||||
use crate::api::account::data;
|
use crate::{
|
||||||
|
accounts::Account,
|
||||||
|
api::account::data,
|
||||||
|
tokens::{AuthToken, VerificationToken},
|
||||||
|
};
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use log::info;
|
use log::info;
|
||||||
|
use mail_send::{mail_builder::MessageBuilder, SmtpClient, SmtpClientBuilder};
|
||||||
|
use sqlx::MySqlPool;
|
||||||
|
|
||||||
fn is_sql_injection(string: &String) -> bool {
|
fn is_sql_injection(string: &String) -> bool {
|
||||||
match libinjection::sqli(string) {
|
match libinjection::sqli(string) {
|
||||||
|
@ -19,15 +25,55 @@ impl AlphaExt for String {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn register(request: data::RegisterRequest) -> Result<data::RegisterResponse> {
|
pub async fn register(
|
||||||
|
pool: &MySqlPool,
|
||||||
|
request: data::RegisterRequest,
|
||||||
|
) -> Result<data::RegisterResponse> {
|
||||||
if is_sql_injection(&request.username) || is_sql_injection(&request.email) {
|
if is_sql_injection(&request.username) || is_sql_injection(&request.email) {
|
||||||
return Ok(data::RegisterResponse::Blocked);
|
return Ok(data::RegisterResponse::Blocked);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if Account::from_username(pool, &request.username).await?.is_some() {
|
||||||
|
return Ok(data::RegisterResponse::Conflict(
|
||||||
|
data::RegisterConflict::Username,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
if Account::from_email(pool, &request.email).await?.is_some() {
|
||||||
|
return Ok(data::RegisterResponse::Conflict(
|
||||||
|
data::RegisterConflict::Email,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
let account = Account::new(pool, &request.username, &request.email, &request.password).await?;
|
||||||
|
|
||||||
|
let token = VerificationToken::new(pool, account.id, chrono::Duration::minutes(10)).await?;
|
||||||
|
|
||||||
|
let message = MessageBuilder::new()
|
||||||
|
.from(("Nerdcult Account Management (noreply)", "account@nerdcult.net"))
|
||||||
|
.to(vec![
|
||||||
|
(request.username.as_str(), request.email.as_str()),
|
||||||
|
])
|
||||||
|
.subject("Account Verification")
|
||||||
|
.text_body(format!("Please verify your NerdCult account. Your code is {} (will be replaced with a link in future).", token.token));
|
||||||
|
|
||||||
|
SmtpClientBuilder::new(&std::env::var("SMTP_HOST_URL")?, 465)
|
||||||
|
.implicit_tls(true)
|
||||||
|
.credentials(mail_send::Credentials::Plain { username: &std::env::var("SMTP_USER")?, secret: &std::env::var("SMTP_PASSWORD")? })
|
||||||
|
.connect()
|
||||||
|
.await?
|
||||||
|
.send(message)
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
info!("Verification Token: {:#?}", token);
|
||||||
|
|
||||||
Ok(data::RegisterResponse::Success)
|
Ok(data::RegisterResponse::Success)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn verify(request: data::VerifyRequest) -> Result<data::VerifyResponse> {
|
pub async fn verify(
|
||||||
|
pool: &MySqlPool,
|
||||||
|
request: data::VerifyRequest,
|
||||||
|
) -> Result<data::VerifyResponse> {
|
||||||
if !request.token.is_alpha() {
|
if !request.token.is_alpha() {
|
||||||
return Ok(data::VerifyResponse::Blocked);
|
return Ok(data::VerifyResponse::Blocked);
|
||||||
}
|
}
|
||||||
|
@ -36,6 +82,7 @@ pub async fn verify(request: data::VerifyRequest) -> Result<data::VerifyResponse
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn authenticate(
|
pub async fn authenticate(
|
||||||
|
pool: &MySqlPool,
|
||||||
request: data::AuthenticateRequest,
|
request: data::AuthenticateRequest,
|
||||||
) -> Result<data::AuthenticateResponse> {
|
) -> Result<data::AuthenticateResponse> {
|
||||||
if is_sql_injection(&request.username) {
|
if is_sql_injection(&request.username) {
|
||||||
|
@ -49,7 +96,7 @@ pub async fn authenticate(
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn delete(token: String) -> Result<data::DeleteResponse> {
|
pub async fn delete(pool: &MySqlPool, token: String) -> Result<data::DeleteResponse> {
|
||||||
if !token.is_alpha() {
|
if !token.is_alpha() {
|
||||||
return Ok(data::DeleteResponse::Blocked);
|
return Ok(data::DeleteResponse::Blocked);
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,7 +15,7 @@ pub async fn start(port: u16, pool: MySqlPool) -> Result<()> {
|
||||||
sqlx::query!(
|
sqlx::query!(
|
||||||
r#"
|
r#"
|
||||||
CREATE TABLE IF NOT EXISTS Accounts (
|
CREATE TABLE IF NOT EXISTS Accounts (
|
||||||
id INT8 UNSIGNED NOT NULL AUTO_INCREMENT,
|
id INT8 UNSIGNED NOT NULL AUTO_INCREMENT UNIQUE,
|
||||||
username VARCHAR(32) NOT NULL,
|
username VARCHAR(32) NOT NULL,
|
||||||
email TEXT NOT NULL,
|
email TEXT NOT NULL,
|
||||||
salt VARCHAR(22) NOT NULL,
|
salt VARCHAR(22) NOT NULL,
|
||||||
|
|
11
src/main.rs
11
src/main.rs
|
@ -1,3 +1,4 @@
|
||||||
|
mod accounts;
|
||||||
mod api;
|
mod api;
|
||||||
mod tokens;
|
mod tokens;
|
||||||
|
|
||||||
|
@ -32,6 +33,16 @@ async fn main() -> Result<()> {
|
||||||
})?)
|
})?)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
|
let _ = &std::env::var("SMTP_HOST_URL").map_err(|_| {
|
||||||
|
anyhow::Error::msg("Environment variable SMTP_HOST_URL needs to be specified!")
|
||||||
|
})?;
|
||||||
|
let _ = &std::env::var("SMTP_USER").map_err(|_| {
|
||||||
|
anyhow::Error::msg("Environment variable SMTP_HOST_URL needs to be specified!")
|
||||||
|
})?;
|
||||||
|
let _ = &std::env::var("SMTP_PASSWORD").map_err(|_| {
|
||||||
|
anyhow::Error::msg("Environment variable SMTP_HOST_URL needs to be specified!")
|
||||||
|
})?;
|
||||||
|
|
||||||
api::start(port, pool).await?;
|
api::start(port, pool).await?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
|
@ -3,15 +3,15 @@ use sqlx::{mysql::MySqlPool, types::chrono as sqlx_chrono};
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct AuthToken {
|
pub struct AuthToken {
|
||||||
token: String,
|
pub token: String,
|
||||||
account: u64,
|
pub account: u64,
|
||||||
expire: sqlx_chrono::NaiveDateTime,
|
pub expire: sqlx_chrono::NaiveDateTime,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AuthToken {
|
impl AuthToken {
|
||||||
pub async fn new(
|
pub async fn new(
|
||||||
pool: &MySqlPool,
|
pool: &MySqlPool,
|
||||||
account_id: usize,
|
account_id: u64,
|
||||||
lifetime: chrono::Duration,
|
lifetime: chrono::Duration,
|
||||||
) -> Result<Self> {
|
) -> Result<Self> {
|
||||||
let expire = match sqlx_chrono::Utc::now()
|
let expire = match sqlx_chrono::Utc::now()
|
||||||
|
@ -83,15 +83,15 @@ impl AuthToken {
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct VerificationToken {
|
pub struct VerificationToken {
|
||||||
token: String,
|
pub token: String,
|
||||||
account: u64,
|
pub account: u64,
|
||||||
expire: sqlx_chrono::NaiveDateTime,
|
pub expire: sqlx_chrono::NaiveDateTime,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl VerificationToken {
|
impl VerificationToken {
|
||||||
pub async fn new(
|
pub async fn new(
|
||||||
pool: &MySqlPool,
|
pool: &MySqlPool,
|
||||||
account_id: usize,
|
account_id: u64,
|
||||||
lifetime: chrono::Duration,
|
lifetime: chrono::Duration,
|
||||||
) -> Result<Self> {
|
) -> Result<Self> {
|
||||||
let expire = match sqlx_chrono::Utc::now()
|
let expire = match sqlx_chrono::Utc::now()
|
Loading…
Reference in New Issue